diff --git a/.gitmodules b/.gitmodules index 06b16b93..a79d3846 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "src/test/jsmn"] - path = src/test/jsmn + path = src/jsmn url = https://github.com/getdnsapi/jsmn.git branch = getdns diff --git a/src/Makefile.in b/src/Makefile.in index 3766b318..1c66530c 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -76,6 +76,8 @@ COMPAT_OBJ=$(LIBOBJS:.o=.lo) UTIL_OBJ=rbtree.lo val_secalgo.lo +JSMN_OBJ=jsmn.lo + EXTENSION_OBJ=default_eventloop.lo libevent.lo libev.lo NON_C99_OBJS=context.lo libuv.lo @@ -104,6 +106,9 @@ $(COMPAT_OBJ): $(UTIL_OBJ): $(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -c $(srcdir)/util/$(@:.lo=.c) -o $@ +$(JSMN_OBJ): + $(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -DJSMN_GETDNS -c $(srcdir)/jsmn/$(@:.lo=.c) -o $@ + $(EXTENSION_OBJ): $(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -c $(srcdir)/extension/$(@:.lo=.c) -o $@ @@ -144,8 +149,8 @@ libgetdns_ext_ev.la: libgetdns.la libev.lo $(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) -o $@ libev.lo libgetdns.la $(LDFLAGS) $(EXTENSION_LIBEV_LDFLAGS) $(EXTENSION_LIBEV_EXT_LIBS) -rpath $(libdir) -version-info $(libversion) -no-undefined -export-symbols $(srcdir)/extension/libev.symbols -libgetdns.la: $(GETDNS_OBJ) version.lo context.lo default_eventloop.lo $(GLDNS_OBJ) $(COMPAT_OBJ) $(UTIL_OBJ) - $(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) -o $@ $(GETDNS_OBJ) version.lo context.lo default_eventloop.lo $(GLDNS_OBJ) $(COMPAT_OBJ) $(UTIL_OBJ) $(LDFLAGS) -rpath $(libdir) -version-info $(libversion) -no-undefined -export-symbols $(srcdir)/libgetdns.symbols +libgetdns.la: $(GETDNS_OBJ) version.lo context.lo default_eventloop.lo $(GLDNS_OBJ) $(COMPAT_OBJ) $(UTIL_OBJ) $(JSMN_OBJ) + $(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) -o $@ $(GETDNS_OBJ) version.lo context.lo default_eventloop.lo $(GLDNS_OBJ) $(COMPAT_OBJ) $(UTIL_OBJ) $(JSMN_OBJ) $(LDFLAGS) -rpath $(libdir) -version-info $(libversion) -no-undefined -export-symbols $(srcdir)/libgetdns.symbols test: all @@ -203,11 +208,12 @@ configure.status: configure depend: (cd $(srcdir) ; awk 'BEGIN{P=1}{if(P)print}/^# Dependencies/{P=0}' Makefile.in > Makefile.in.new ) - (blddir=`pwd`; cd $(srcdir) ; gcc -MM -I. -I"$$blddir" *.c gldns/*.c compat/*.c util/*.c extension/*.c| \ + (blddir=`pwd`; cd $(srcdir) ; gcc -MM -I. -I"$$blddir" *.c gldns/*.c compat/*.c util/*.c jsmn/*.c extension/*.c| \ sed -e "s? $$blddir/? ?g" \ -e 's?gldns/?$$(srcdir)/gldns/?g' \ -e 's?compat/?$$(srcdir)/compat/?g' \ -e 's?util/?$$(srcdir)/util/?g' \ + -e 's?jsmn/?$$(srcdir)/jsmn/?g' \ -e 's?extension/?$$(srcdir)/extension/?g' \ -e 's? \([a-z_-]*\)\.\([ch]\)? $$(srcdir)/\1.\2?g' \ -e 's? \$$(srcdir)/config\.h? config.h?g' \ @@ -237,7 +243,8 @@ convert.lo convert.o: $(srcdir)/convert.c config.h getdns/getdns.h getdns/getdns getdns/getdns.h $(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ $(srcdir)/extension/default_eventloop.h config.h getdns/getdns_extra.h $(srcdir)/ub_loop.h \ $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \ - $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/convert.h + $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/const-info.h $(srcdir)/dict.h \ + $(srcdir)/list.h $(srcdir)/jsmn/jsmn.h $(srcdir)/convert.h dict.lo dict.o: $(srcdir)/dict.c config.h $(srcdir)/types-internal.h getdns/getdns.h \ getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h $(srcdir)/util-internal.h \ $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h config.h getdns/getdns_extra.h \ @@ -324,6 +331,7 @@ rbtree.lo rbtree.o: $(srcdir)/util/rbtree.c config.h $(srcdir)/util/log.h $(srcd $(srcdir)/util/fptr_wlist.h $(srcdir)/util/rbtree.h val_secalgo.lo val_secalgo.o: $(srcdir)/util/val_secalgo.c config.h $(srcdir)/util/val_secalgo.h $(srcdir)/util/log.h \ $(srcdir)/debug.h config.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/keyraw.h $(srcdir)/gldns/gbuffer.h +jsmn.lo jsmn.o: $(srcdir)/jsmn/jsmn.c $(srcdir)/jsmn/jsmn.h default_eventloop.lo default_eventloop.o: $(srcdir)/extension/default_eventloop.c \ $(srcdir)/extension/default_eventloop.h config.h getdns/getdns.h \ getdns/getdns_extra.h $(srcdir)/debug.h config.h diff --git a/src/const-info.c b/src/const-info.c index 200100c2..0294e281 100644 --- a/src/const-info.c +++ b/src/const-info.c @@ -123,3 +123,212 @@ getdns_get_errorstr_by_id(uint16_t err) else return NULL; } + +static struct const_name_info consts_name_info[] = { + { "GETDNS_APPEND_NAME_ALWAYS", 550 }, + { "GETDNS_APPEND_NAME_NEVER", 553 }, + { "GETDNS_APPEND_NAME_ONLY_TO_MULTIPLE_LABEL_NAME_AFTER_FAILURE", 552 }, + { "GETDNS_APPEND_NAME_ONLY_TO_SINGLE_LABEL_AFTER_FAILURE", 551 }, + { "GETDNS_APPEND_NAME_TO_SINGLE_LABEL_FIRST", 554 }, + { "GETDNS_AUTHENTICATION_NONE", 1300 }, + { "GETDNS_AUTHENTICATION_REQUIRED", 1301 }, + { "GETDNS_BAD_DNS_ALL_NUMERIC_LABEL", 1101 }, + { "GETDNS_BAD_DNS_CNAME_IN_TARGET", 1100 }, + { "GETDNS_BAD_DNS_CNAME_RETURNED_FOR_OTHER_TYPE", 1102 }, + { "GETDNS_CALLBACK_CANCEL", 701 }, + { "GETDNS_CALLBACK_COMPLETE", 700 }, + { "GETDNS_CALLBACK_ERROR", 703 }, + { "GETDNS_CALLBACK_TIMEOUT", 702 }, + { "GETDNS_CONTEXT_CODE_APPEND_NAME", 607 }, + { "GETDNS_CONTEXT_CODE_DNSSEC_ALLOWED_SKEW", 614 }, + { "GETDNS_CONTEXT_CODE_DNSSEC_TRUST_ANCHORS", 609 }, + { "GETDNS_CONTEXT_CODE_DNS_ROOT_SERVERS", 604 }, + { "GETDNS_CONTEXT_CODE_DNS_TRANSPORT", 605 }, + { "GETDNS_CONTEXT_CODE_EDNS_CLIENT_SUBNET_PRIVATE", 619 }, + { "GETDNS_CONTEXT_CODE_EDNS_DO_BIT", 613 }, + { "GETDNS_CONTEXT_CODE_EDNS_EXTENDED_RCODE", 611 }, + { "GETDNS_CONTEXT_CODE_EDNS_MAXIMUM_UDP_PAYLOAD_SIZE", 610 }, + { "GETDNS_CONTEXT_CODE_EDNS_VERSION", 612 }, + { "GETDNS_CONTEXT_CODE_FOLLOW_REDIRECTS", 602 }, + { "GETDNS_CONTEXT_CODE_IDLE_TIMEOUT", 617 }, + { "GETDNS_CONTEXT_CODE_LIMIT_OUTSTANDING_QUERIES", 606 }, + { "GETDNS_CONTEXT_CODE_MEMORY_FUNCTIONS", 615 }, + { "GETDNS_CONTEXT_CODE_NAMESPACES", 600 }, + { "GETDNS_CONTEXT_CODE_PUBKEY_PINSET", 621 }, + { "GETDNS_CONTEXT_CODE_RESOLUTION_TYPE", 601 }, + { "GETDNS_CONTEXT_CODE_SUFFIX", 608 }, + { "GETDNS_CONTEXT_CODE_TIMEOUT", 616 }, + { "GETDNS_CONTEXT_CODE_TLS_AUTHENTICATION", 618 }, + { "GETDNS_CONTEXT_CODE_TLS_QUERY_PADDING_BLOCKSIZE", 620 }, + { "GETDNS_CONTEXT_CODE_UPSTREAM_RECURSIVE_SERVERS", 603 }, + { "GETDNS_DNSSEC_BOGUS", 401 }, + { "GETDNS_DNSSEC_INDETERMINATE", 402 }, + { "GETDNS_DNSSEC_INSECURE", 403 }, + { "GETDNS_DNSSEC_NOT_PERFORMED", 404 }, + { "GETDNS_DNSSEC_SECURE", 400 }, + { "GETDNS_EXTENSION_FALSE", 1001 }, + { "GETDNS_EXTENSION_TRUE", 1000 }, + { "GETDNS_NAMESPACE_DNS", 500 }, + { "GETDNS_NAMESPACE_LOCALNAMES", 501 }, + { "GETDNS_NAMESPACE_MDNS", 503 }, + { "GETDNS_NAMESPACE_NETBIOS", 502 }, + { "GETDNS_NAMESPACE_NIS", 504 }, + { "GETDNS_NAMETYPE_DNS", 800 }, + { "GETDNS_NAMETYPE_WINS", 801 }, + { "GETDNS_OPCODE_IQUERY", 1 }, + { "GETDNS_OPCODE_NOTIFY", 4 }, + { "GETDNS_OPCODE_QUERY", 0 }, + { "GETDNS_OPCODE_STATUS", 2 }, + { "GETDNS_OPCODE_UPDATE", 5 }, + { "GETDNS_RCODE_BADALG", 21 }, + { "GETDNS_RCODE_BADKEY", 17 }, + { "GETDNS_RCODE_BADMODE", 19 }, + { "GETDNS_RCODE_BADNAME", 20 }, + { "GETDNS_RCODE_BADSIG", 16 }, + { "GETDNS_RCODE_BADTIME", 18 }, + { "GETDNS_RCODE_BADTRUNC", 22 }, + { "GETDNS_RCODE_BADVERS", 16 }, + { "GETDNS_RCODE_FORMERR", 1 }, + { "GETDNS_RCODE_NOERROR", 0 }, + { "GETDNS_RCODE_NOTAUTH", 9 }, + { "GETDNS_RCODE_NOTIMP", 4 }, + { "GETDNS_RCODE_NOTZONE", 10 }, + { "GETDNS_RCODE_NXDOMAIN", 3 }, + { "GETDNS_RCODE_NXRRSET", 8 }, + { "GETDNS_RCODE_REFUSED", 5 }, + { "GETDNS_RCODE_SERVFAIL", 2 }, + { "GETDNS_RCODE_YXDOMAIN", 6 }, + { "GETDNS_RCODE_YXRRSET", 7 }, + { "GETDNS_REDIRECTS_DO_NOT_FOLLOW", 531 }, + { "GETDNS_REDIRECTS_FOLLOW", 530 }, + { "GETDNS_RESOLUTION_RECURSING", 521 }, + { "GETDNS_RESOLUTION_STUB", 520 }, + { "GETDNS_RESPSTATUS_ALL_BOGUS_ANSWERS", 904 }, + { "GETDNS_RESPSTATUS_ALL_TIMEOUT", 902 }, + { "GETDNS_RESPSTATUS_GOOD", 900 }, + { "GETDNS_RESPSTATUS_NO_NAME", 901 }, + { "GETDNS_RESPSTATUS_NO_SECURE_ANSWERS", 903 }, + { "GETDNS_RETURN_BAD_CONTEXT", 301 }, + { "GETDNS_RETURN_BAD_DOMAIN_NAME", 300 }, + { "GETDNS_RETURN_CONTEXT_UPDATE_FAIL", 302 }, + { "GETDNS_RETURN_DNSSEC_WITH_STUB_DISALLOWED", 309 }, + { "GETDNS_RETURN_EXTENSION_MISFORMAT", 308 }, + { "GETDNS_RETURN_GENERIC_ERROR", 1 }, + { "GETDNS_RETURN_GOOD", 0 }, + { "GETDNS_RETURN_INVALID_PARAMETER", 311 }, + { "GETDNS_RETURN_MEMORY_ERROR", 310 }, + { "GETDNS_RETURN_NEED_MORE_SPACE", 399 }, + { "GETDNS_RETURN_NOT_IMPLEMENTED", 312 }, + { "GETDNS_RETURN_NO_SUCH_DICT_NAME", 305 }, + { "GETDNS_RETURN_NO_SUCH_EXTENSION", 307 }, + { "GETDNS_RETURN_NO_SUCH_LIST_ITEM", 304 }, + { "GETDNS_RETURN_UNKNOWN_TRANSACTION", 303 }, + { "GETDNS_RETURN_WRONG_TYPE_REQUESTED", 306 }, + { "GETDNS_RRCLASS_ANY", 255 }, + { "GETDNS_RRCLASS_CH", 3 }, + { "GETDNS_RRCLASS_HS", 4 }, + { "GETDNS_RRCLASS_IN", 1 }, + { "GETDNS_RRCLASS_NONE", 254 }, + { "GETDNS_RRTYPE_A", 1 }, + { "GETDNS_RRTYPE_AAAA", 28 }, + { "GETDNS_RRTYPE_AFSDB", 18 }, + { "GETDNS_RRTYPE_ANY", 255 }, + { "GETDNS_RRTYPE_APL", 42 }, + { "GETDNS_RRTYPE_ATMA", 34 }, + { "GETDNS_RRTYPE_AXFR", 252 }, + { "GETDNS_RRTYPE_CAA", 257 }, + { "GETDNS_RRTYPE_CDNSKEY", 60 }, + { "GETDNS_RRTYPE_CDS", 59 }, + { "GETDNS_RRTYPE_CERT", 37 }, + { "GETDNS_RRTYPE_CNAME", 5 }, + { "GETDNS_RRTYPE_CSYNC", 62 }, + { "GETDNS_RRTYPE_DHCID", 49 }, + { "GETDNS_RRTYPE_DLV", 32769 }, + { "GETDNS_RRTYPE_DNAME", 39 }, + { "GETDNS_RRTYPE_DNSKEY", 48 }, + { "GETDNS_RRTYPE_DS", 43 }, + { "GETDNS_RRTYPE_EID", 31 }, + { "GETDNS_RRTYPE_GID", 102 }, + { "GETDNS_RRTYPE_GPOS", 27 }, + { "GETDNS_RRTYPE_HINFO", 13 }, + { "GETDNS_RRTYPE_HIP", 55 }, + { "GETDNS_RRTYPE_IPSECKEY", 45 }, + { "GETDNS_RRTYPE_ISDN", 20 }, + { "GETDNS_RRTYPE_IXFR", 251 }, + { "GETDNS_RRTYPE_KEY", 25 }, + { "GETDNS_RRTYPE_KX", 36 }, + { "GETDNS_RRTYPE_LOC", 29 }, + { "GETDNS_RRTYPE_LP", 107 }, + { "GETDNS_RRTYPE_MAILA", 254 }, + { "GETDNS_RRTYPE_MAILB", 253 }, + { "GETDNS_RRTYPE_MB", 7 }, + { "GETDNS_RRTYPE_MD", 3 }, + { "GETDNS_RRTYPE_MF", 4 }, + { "GETDNS_RRTYPE_MG", 8 }, + { "GETDNS_RRTYPE_MINFO", 14 }, + { "GETDNS_RRTYPE_MR", 9 }, + { "GETDNS_RRTYPE_MX", 15 }, + { "GETDNS_RRTYPE_NAPTR", 35 }, + { "GETDNS_RRTYPE_NID", 104 }, + { "GETDNS_RRTYPE_NIMLOC", 32 }, + { "GETDNS_RRTYPE_NINFO", 56 }, + { "GETDNS_RRTYPE_NS", 2 }, + { "GETDNS_RRTYPE_NSAP", 22 }, + { "GETDNS_RRTYPE_NSEC", 47 }, + { "GETDNS_RRTYPE_NULL", 10 }, + { "GETDNS_RRTYPE_NXT", 30 }, + { "GETDNS_RRTYPE_OPENPGPKEY", 61 }, + { "GETDNS_RRTYPE_OPT", 41 }, + { "GETDNS_RRTYPE_PTR", 12 }, + { "GETDNS_RRTYPE_PX", 26 }, + { "GETDNS_RRTYPE_RKEY", 57 }, + { "GETDNS_RRTYPE_RP", 17 }, + { "GETDNS_RRTYPE_RRSIG", 46 }, + { "GETDNS_RRTYPE_RT", 21 }, + { "GETDNS_RRTYPE_SIG", 24 }, + { "GETDNS_RRTYPE_SINK", 40 }, + { "GETDNS_RRTYPE_SOA", 6 }, + { "GETDNS_RRTYPE_SPF", 99 }, + { "GETDNS_RRTYPE_SRV", 33 }, + { "GETDNS_RRTYPE_SSHFP", 44 }, + { "GETDNS_RRTYPE_TA", 32768 }, + { "GETDNS_RRTYPE_TALINK", 58 }, + { "GETDNS_RRTYPE_TKEY", 249 }, + { "GETDNS_RRTYPE_TLSA", 52 }, + { "GETDNS_RRTYPE_TSIG", 250 }, + { "GETDNS_RRTYPE_TXT", 16 }, + { "GETDNS_RRTYPE_UID", 101 }, + { "GETDNS_RRTYPE_UINFO", 100 }, + { "GETDNS_RRTYPE_UNSPEC", 103 }, + { "GETDNS_RRTYPE_URI", 256 }, + { "GETDNS_RRTYPE_WKS", 11 }, + { "GETDNS_TRANSPORT_TCP", 1201 }, + { "GETDNS_TRANSPORT_TCP_ONLY", 542 }, + { "GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN", 543 }, + { "GETDNS_TRANSPORT_TLS", 1202 }, + { "GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN", 545 }, + { "GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN", 544 }, + { "GETDNS_TRANSPORT_UDP", 1200 }, + { "GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP", 540 }, + { "GETDNS_TRANSPORT_UDP_ONLY", 541 }, +}; + +static int const_name_info_cmp(const void *a, const void *b) +{ + return strcmp( ((struct const_name_info *) a)->name + , ((struct const_name_info *) b)->name ); +} + +int +_getdns_get_const_name_info(const char *name, uint32_t *code) +{ + struct const_name_info key = { name, 0 }; + struct const_name_info *i = bsearch(&key, consts_name_info, + sizeof(consts_name_info) / sizeof(struct const_name_info), + sizeof(struct const_name_info), const_name_info_cmp); + if (!i) + return 0; + if (code) + *code = i->code; + return 1; +} diff --git a/src/const-info.h b/src/const-info.h index 39d7c98e..379e2512 100644 --- a/src/const-info.h +++ b/src/const-info.h @@ -47,6 +47,13 @@ struct const_info { struct const_info *_getdns_get_const_info(int value); +struct const_name_info { + const char *name; + uint32_t code; +}; + +int _getdns_get_const_name_info(const char *name, uint32_t *code); + #endif /* const-info.h */ diff --git a/src/convert.c b/src/convert.c index 2539d7bd..c5bc98c4 100644 --- a/src/convert.c +++ b/src/convert.c @@ -48,9 +48,15 @@ #include "util-internal.h" #include "gldns/wire2str.h" #include "gldns/str2wire.h" +#include "gldns/parseutil.h" +#include "const-info.h" +#include "types-internal.h" /* For getdns_item */ #include "dict.h" #include "list.h" +#include "jsmn/jsmn.h" #include "convert.h" +#include /* For bsearch */ + /* stuff to make it compile pedantically */ #define UNUSED_PARAM(x) ((void)(x)) @@ -1031,5 +1037,641 @@ getdns_msg_dict2str_scan( return r; } +static getdns_dict * +_getdns_ipaddr_dict_mf(struct mem_funcs *mf, char *ipstr) +{ + getdns_dict *r = _getdns_dict_create_with_mf(mf); + char *s = strchr(ipstr, '%'), *scope_id_str = ""; + char *p = strchr(ipstr, '@'), *portstr = ""; + char *t = strchr(ipstr, '#'), *tls_portstr = ""; + char *n = strchr(ipstr, '~'), *tls_namestr = ""; + /* ^[alg:]name:key */ + char *T = strchr(ipstr, '^'), *tsig_name_str = "" + , *tsig_secret_str = "" + , *tsig_algorithm_str = ""; + char *br, *c; + int tsig_secret_size; + uint8_t tsig_secret_buf[256]; /* 4 times SHA512 */ + getdns_bindata tsig_secret; + uint8_t buf[sizeof(struct in6_addr)]; + getdns_bindata addr; + + addr.data = buf; + + if (!r) return NULL; + + if (*ipstr == '[') { + char *br = strchr(ipstr, ']'); + if (br) { + ipstr += 1; + *br = 0; + if ((c = strchr(br + 1, ':'))) { + p = c; + } + } + } else if ((br = strchr(ipstr, '.')) && (c = strchr(br + 1, ':')) + && (T == NULL || c < T)) + p = c; + + else if ((*ipstr == '*') && (c = strchr(ipstr+1, ':'))) + p = c; + + if (s) { + *s = 0; + scope_id_str = s + 1; + } + if (p) { + *p = 0; + portstr = p + 1; + } + if (t) { + *t = 0; + tls_portstr = t + 1; + } + if (n) { + *n = 0; + tls_namestr = n + 1; + } + if (T) { + *T = 0; + tsig_name_str = T + 1; + if ((T = strchr(tsig_name_str, ':'))) { + *T = 0; + tsig_secret_str = T + 1; + if ((T = strchr(tsig_secret_str, ':'))) { + *T = 0; + tsig_algorithm_str = tsig_name_str; + tsig_name_str = tsig_secret_str; + tsig_secret_str = T + 1; + } + } else { + tsig_name_str = ""; + } + } + if (*ipstr == '*') { + getdns_dict_util_set_string(r, "address_type", "IPv6"); + addr.size = 16; + (void) memset(buf, 0, 16); + } else if (strchr(ipstr, ':')) { + getdns_dict_util_set_string(r, "address_type", "IPv6"); + addr.size = 16; + if (inet_pton(AF_INET6, ipstr, buf) <= 0) { + getdns_dict_destroy(r); + return NULL; + } + } else { + getdns_dict_util_set_string(r, "address_type", "IPv4"); + addr.size = 4; + if (inet_pton(AF_INET, ipstr, buf) <= 0) { + getdns_dict_destroy(r); + return NULL; + } + } + getdns_dict_set_bindata(r, "address_data", &addr); + if (*portstr) + getdns_dict_set_int(r, "port", (int32_t)atoi(portstr)); + if (*tls_portstr) + getdns_dict_set_int(r, "tls_port", (int32_t)atoi(tls_portstr)); + if (*tls_namestr) { + getdns_dict_util_set_string(r, "tls_auth_name", tls_namestr); + } + if (*scope_id_str) + getdns_dict_util_set_string(r, "scope_id", scope_id_str); + if (*tsig_name_str) + getdns_dict_util_set_string(r, "tsig_name", tsig_name_str); + if (*tsig_algorithm_str) + getdns_dict_util_set_string(r, "tsig_algorithm", tsig_algorithm_str); + if (*tsig_secret_str) { + tsig_secret_size = gldns_b64_pton( + tsig_secret_str, tsig_secret_buf, sizeof(tsig_secret_buf)); + if (tsig_secret_size > 0) { + tsig_secret.size = tsig_secret_size; + tsig_secret.data = tsig_secret_buf; + getdns_dict_set_bindata(r, "tsig_secret", &tsig_secret); + } + } + return r; +} + +static int _jsmn_get_ipdict(struct mem_funcs *mf, const char *js, jsmntok_t *t, + getdns_dict **value) +{ + char value_str[3072]; + int size = t->end - t->start; + + if (size <= 0 || size >= sizeof(value_str)) + return 0; + + (void) memcpy(value_str, js + t->start, size); + value_str[size] = '\0'; + + *value = _getdns_ipaddr_dict_mf(mf, value_str); + return *value != NULL; +} + +static int _jsmn_get_data(struct mem_funcs *mf, const char *js, jsmntok_t *t, + getdns_bindata **value) +{ + size_t i, j; + uint8_t h, l; + + if ((t->end - t->start) < 4 || (t->end - t->start) % 2 == 1 || + js[t->start] != '0' || js[t->start + 1] != 'x') + return 0; + + for (i = t->start + 2; i < t->end; i++) + if (!((js[i] >= '0' && js[i] <= '9') + ||(js[i] >= 'a' && js[i] <= 'f') + ||(js[i] >= 'A' && js[i] <= 'F'))) + return 0; + + if (!(*value = GETDNS_MALLOC(*mf, getdns_bindata))) + return 0; + + else if (!((*value)->data = GETDNS_XMALLOC( + *mf, uint8_t, (t->end - t->start) / 2 - 1))) { + GETDNS_FREE(*mf, *value); + return 0; + } + for (i = t->start + 2, j = 0; i < t->end; i++, j++) { + h = js[i] >= '0' && js[i] <= '9' ? js[i] - '0' + : js[i] >= 'A' && js[i] <= 'F' ? js[i] + 10 - 'A' + : js[i] + 10 - 'a'; + h <<= 4; + i++; + l = js[i] >= '0' && js[i] <= '9' ? js[i] - '0' + : js[i] >= 'A' && js[i] <= 'F' ? js[i] + 10 - 'A' + : js[i] + 10 - 'a'; + (*value)->data[j] = h | l; + } + (*value)->size = j; + return 1; +} + +static int _jsmn_get_dname(struct mem_funcs *mf, const char *js, jsmntok_t *t, + getdns_bindata **value) +{ + char value_str[1025]; + int size = t->end - t->start; + + if (size <= 0 || size >= sizeof(value_str) || js[t->end - 1] != '.') + return 0; + + (void) memcpy(value_str, js + t->start, size); + value_str[size] = '\0'; + + return !getdns_convert_fqdn_to_dns_name(value_str, value); +} + +static int _jsmn_get_ipv4(struct mem_funcs *mf, const char *js, jsmntok_t *t, + getdns_bindata **value) +{ + char value_str[16]; + int size = t->end - t->start; + uint8_t buf[4]; + + if (size <= 0 || size >= sizeof(value_str)) + return 0; + + (void) memcpy(value_str, js + t->start, size); + value_str[size] = '\0'; + + if (inet_pton(AF_INET, value_str, buf) <= 0) + ; /* pass */ + + else if (!(*value = GETDNS_MALLOC(*mf, getdns_bindata))) + ; /* pass */ + + else if (!((*value)->data = GETDNS_XMALLOC(*mf, uint8_t, 4))) + GETDNS_FREE(*mf, *value); + + else { + (*value)->size = 4; + (void) memcpy((*value)->data, buf, 4); + return 1; + } + return 0; +} + +static int _jsmn_get_ipv6(struct mem_funcs *mf, const char *js, jsmntok_t *t, + getdns_bindata **value) +{ + char value_str[40]; + int size = t->end - t->start; + uint8_t buf[16]; + + if (size <= 0 || size >= sizeof(value_str)) + return 0; + + (void) memcpy(value_str, js + t->start, size); + value_str[size] = '\0'; + + if (inet_pton(AF_INET6, value_str, buf) <= 0) + ; /* pass */ + + else if (!(*value = GETDNS_MALLOC(*mf, getdns_bindata))) + ; /* pass */ + + else if (!((*value)->data = GETDNS_XMALLOC(*mf, uint8_t, 16))) + GETDNS_FREE(*mf, *value); + + else { + (*value)->size = 16; + (void) memcpy((*value)->data, buf, 16); + return 1; + } + return 0; +} + +static int _jsmn_get_int(struct mem_funcs *mf, const char *js, jsmntok_t *t, + uint32_t *value) +{ + char value_str[11]; + int size = t->end - t->start; + char *endptr; + + if (size <= 0 || size >= sizeof(value_str)) + return 0; + + (void) memcpy(value_str, js + t->start, size); + value_str[size] = '\0'; + + *value = (uint32_t)strtoul(value_str, &endptr, 10); + return *value_str != '\0' && *endptr == '\0'; +} + +static int _jsmn_get_const(struct mem_funcs *mf, const char *js, jsmntok_t *t, + uint32_t *value) +{ + char value_str[80]; + int size = t->end - t->start; + + if (size <= 0 || size >= sizeof(value_str)) + return 0; + + (void) memcpy(value_str, js + t->start, size); + value_str[size] = '\0'; + + return _getdns_get_const_name_info(value_str, value); +} + +static void +_getdns_destroy_item_data(struct mem_funcs *mf, getdns_item *item) +{ + switch (item->dtype) { + case t_dict: + getdns_dict_destroy(item->data.dict); + break; + + case t_list: + getdns_list_destroy(item->data.list); + break; + + case t_bindata: + GETDNS_FREE(*mf, item->data.bindata->data); + GETDNS_FREE(*mf, item->data.bindata); + default: + break; + } +} +static int _jsmn_get_item(struct mem_funcs *mf, const char *js, jsmntok_t *t, + size_t count, getdns_item *item, getdns_return_t *r); + +static int _jsmn_get_dict(struct mem_funcs *mf, const char *js, jsmntok_t *t, + size_t count, getdns_dict *dict, getdns_return_t *r) +{ + size_t i, j = 1; + char key_spc[1024], *key = NULL; + getdns_item child_item; + + for (i = 0; i < t->size; i++) { + if (t[j].type != JSMN_STRING && + t[j].type != JSMN_PRIMITIVE) { + + /* Key must be string or primitive */ + *r = GETDNS_RETURN_WRONG_TYPE_REQUESTED; + break; + } + if (t[j].end <= t[j].start) { + /* Key must be at least 1 character */ + *r = GETDNS_RETURN_GENERIC_ERROR; /* range error */ + break; + } + if (t[j].end - t[j].start < sizeof(key_spc)) + key = key_spc; + + else if (!(key = GETDNS_XMALLOC( + *mf, char, t[j].end - t[j].start + 1))) { + + *r = GETDNS_RETURN_MEMORY_ERROR; + break; + } + (void) memcpy(key, js + t[j].start, t[j].end - t[j].start); + key[t[j].end - t[j].start] = '\0'; + j += 1; + + j += _jsmn_get_item(mf, js, t + j, count - j, &child_item, r); + if (*r) break; + + switch (child_item.dtype) { + case t_int: + *r = getdns_dict_set_int(dict, key, + child_item.data.n); + break; + case t_bindata: + *r = getdns_dict_set_bindata(dict, key, + child_item.data.bindata); + break; + case t_list: + *r = getdns_dict_set_list(dict, key, + child_item.data.list); + break; + case t_dict: + *r = getdns_dict_set_dict(dict, key, + child_item.data.dict); + break; + default: + *r = GETDNS_RETURN_WRONG_TYPE_REQUESTED; + break; + + } + _getdns_destroy_item_data(mf, &child_item); + if (*r) break; + if (key && key != key_spc) { + GETDNS_FREE(*mf, key); + key = NULL; + } + } + if (key && key != key_spc) + GETDNS_FREE(*mf, key); + + if (*r) { + getdns_dict_destroy(dict); + return 0; + } + return j; +} + +static int _jsmn_get_list(struct mem_funcs *mf, const char *js, jsmntok_t *t, + size_t count, getdns_list *list, getdns_return_t *r) +{ + size_t i, j = 1, index = 0; + getdns_item child_item; + + for (i = 0; i < t->size; i++) { + j += _jsmn_get_item(mf, js, t + j, count - j, &child_item, r); + if (*r) break; + + switch (child_item.dtype) { + case t_int: + *r = getdns_list_set_int(list, index++, + child_item.data.n); + break; + case t_bindata: + *r = getdns_list_set_bindata(list, index++, + child_item.data.bindata); + break; + case t_list: + *r = getdns_list_set_list(list, index++, + child_item.data.list); + break; + case t_dict: + *r = getdns_list_set_dict(list, index++, + child_item.data.dict); + break; + default: + *r = GETDNS_RETURN_WRONG_TYPE_REQUESTED; + break; + + } + _getdns_destroy_item_data(mf, &child_item); + if (*r) break; + } + if (*r) { + getdns_list_destroy(list); + return 0; + } + return j; +} + +static int _jsmn_get_item(struct mem_funcs *mf, const char *js, jsmntok_t *t, + size_t count, getdns_item *item, getdns_return_t *r) +{ + assert(item); + + switch (t->type) { + case JSMN_STRING: + if (t->end < t->start) + *r = GETDNS_RETURN_GENERIC_ERROR; + + else if (!(item->data.bindata = + GETDNS_MALLOC(*mf, getdns_bindata))) + *r = GETDNS_RETURN_MEMORY_ERROR; + + else if (!(item->data.bindata->data = GETDNS_XMALLOC( + *mf, uint8_t, t->end - t->start + 1))) { + GETDNS_FREE(*mf, item->data.bindata); + *r = GETDNS_RETURN_MEMORY_ERROR; + } else { + item->dtype = t_bindata; + if (t->end - t->start) { + (void) memcpy(item->data.bindata->data, + js + t->start, t->end - t->start); + } + item->data.bindata->data[t->end - t->start] = '\0'; + item->data.bindata->size = t->end - t->start; + *r = GETDNS_RETURN_GOOD; + return 1; + } + break; + + case JSMN_PRIMITIVE: + /* There is no such thing as an empty primitive */ + if (t->end <= t->start) { + *r = GETDNS_RETURN_GENERIC_ERROR; + break; + + } else if (_jsmn_get_int(mf, js, t, &item->data.n) + || _jsmn_get_const(mf, js, t, &item->data.n)) { + + item->dtype = t_int; + } + else if (_jsmn_get_data(mf, js, t, &item->data.bindata) + || _jsmn_get_dname(mf, js, t, &item->data.bindata) + || _jsmn_get_ipv4(mf, js, t, &item->data.bindata) + || _jsmn_get_ipv6(mf, js, t, &item->data.bindata)) + + item->dtype = t_bindata; + + else if (_jsmn_get_ipdict(mf, js, t, &item->data.dict)) + + item->dtype = t_dict; + else { + *r = GETDNS_RETURN_GENERIC_ERROR; + break; + } + *r = GETDNS_RETURN_GOOD; + return 1; + + case JSMN_OBJECT: + if (!(item->data.dict = _getdns_dict_create_with_mf(mf))) { + *r = GETDNS_RETURN_MEMORY_ERROR; + break; + } + item->dtype = t_dict; + return _jsmn_get_dict(mf, js, t, count, item->data.dict, r); + + case JSMN_ARRAY: + if (!(item->data.list = _getdns_list_create_with_mf(mf))) { + *r = GETDNS_RETURN_MEMORY_ERROR; + break; + } + item->dtype = t_list; + return _jsmn_get_list(mf, js, t, count, item->data.list, r); + + default: + *r = GETDNS_RETURN_WRONG_TYPE_REQUESTED; + break; + } + return 0; +} + +static getdns_return_t +_getdns_str2item_mf(struct mem_funcs *mf, const char *str, getdns_item *item) +{ + jsmn_parser p; + jsmntok_t *tok = NULL, *new_tok; + size_t tokcount = 100; + int r; + getdns_return_t gr; + + jsmn_init(&p); + tok = GETDNS_XMALLOC(*mf, jsmntok_t, tokcount); + do { + r = jsmn_parse(&p, str, strlen(str), tok, tokcount); + if (r == JSMN_ERROR_NOMEM) { + tokcount *= 2; + if (!(new_tok = GETDNS_XREALLOC( + *mf, tok, jsmntok_t, tokcount))) { + GETDNS_FREE(*mf, tok); + return GETDNS_RETURN_MEMORY_ERROR; + } + tok = new_tok; + } + } while (r == JSMN_ERROR_NOMEM); + if (r < 0) + gr = GETDNS_RETURN_GENERIC_ERROR; + else + (void) _jsmn_get_item(mf, str, tok, p.toknext, item, &gr); + GETDNS_FREE(*mf, tok); + return gr; +} + +getdns_return_t +getdns_str2dict(const char *str, getdns_dict **dict) +{ + getdns_item item; + getdns_return_t r; + + if ((r = _getdns_str2item_mf(&_getdns_plain_mem_funcs, str, &item))) + return r; + + else if (item.dtype != t_dict) { + uint8_t buf[16]; + getdns_dict *dict_r; + + if (item.dtype != t_bindata) + r = GETDNS_RETURN_WRONG_TYPE_REQUESTED; + + else if (item.data.bindata->size == 4 && + inet_pton(AF_INET, str, buf) == 1) { + + if (!(dict_r = getdns_dict_create())) + r = GETDNS_RETURN_MEMORY_ERROR; + + else if ((r = getdns_dict_util_set_string( + dict_r, "address_type", "IPv4"))) + getdns_dict_destroy(dict_r); + + else if ((r = getdns_dict_set_bindata( + dict_r, "address_data", item.data.bindata))) + getdns_dict_destroy(dict_r); + else + *dict = dict_r; + + } else if (item.data.bindata->size == 16 && + inet_pton(AF_INET6, str, buf) == 1) { + + if (!(dict_r = getdns_dict_create())) + r = GETDNS_RETURN_MEMORY_ERROR; + + else if ((r = getdns_dict_util_set_string( + dict_r, "address_type", "IPv6"))) + getdns_dict_destroy(dict_r); + + else if ((r = getdns_dict_set_bindata( + dict_r, "address_data", item.data.bindata))) + getdns_dict_destroy(dict_r); + else + *dict = dict_r; + } else + r = GETDNS_RETURN_WRONG_TYPE_REQUESTED; + + _getdns_destroy_item_data(&_getdns_plain_mem_funcs, &item); + return r; + } + *dict = item.data.dict; + return GETDNS_RETURN_GOOD; +} + +getdns_return_t +getdns_str2list(const char *str, getdns_list **list) +{ + getdns_item item; + getdns_return_t r; + + if ((r = _getdns_str2item_mf(&_getdns_plain_mem_funcs, str, &item))) + return r; + + else if (item.dtype != t_list) { + _getdns_destroy_item_data(&_getdns_plain_mem_funcs, &item); + return GETDNS_RETURN_WRONG_TYPE_REQUESTED; + } + *list = item.data.list; + return GETDNS_RETURN_GOOD; +} + +getdns_return_t +getdns_str2bindata(const char *str, getdns_bindata **bindata) +{ + getdns_item item; + getdns_return_t r; + + if ((r = _getdns_str2item_mf(&_getdns_plain_mem_funcs, str, &item))) + return r; + + else if (item.dtype != t_bindata) { + _getdns_destroy_item_data(&_getdns_plain_mem_funcs, &item); + return GETDNS_RETURN_WRONG_TYPE_REQUESTED; + } + *bindata = item.data.bindata; + return GETDNS_RETURN_GOOD; +} + +getdns_return_t +getdns_str2int(const char *str, uint32_t *value) +{ + getdns_item item; + getdns_return_t r; + + if ((r = _getdns_str2item_mf(&_getdns_plain_mem_funcs, str, &item))) + return r; + + else if (item.dtype != t_int) { + _getdns_destroy_item_data(&_getdns_plain_mem_funcs, &item); + return GETDNS_RETURN_WRONG_TYPE_REQUESTED; + } + *value = item.data.n; + return GETDNS_RETURN_GOOD; +} -/* convert.c */ diff --git a/src/getdns/getdns_extra.h.in b/src/getdns/getdns_extra.h.in index c8a3713f..a8d9740b 100644 --- a/src/getdns/getdns_extra.h.in +++ b/src/getdns/getdns_extra.h.in @@ -822,6 +822,10 @@ getdns_validate_dnssec2(getdns_list *to_validate, #define GETDNS_APPEND_NAME_TO_SINGLE_LABEL_FIRST ((getdns_append_name_t) 554 ) #define GETDNS_APPEND_NAME_TO_SINGLE_LABEL_FIRST_TEXT "See getdns_context_set_append_name()" +getdns_return_t getdns_str2dict(const char *str, getdns_dict **dict); +getdns_return_t getdns_str2list(const char *str, getdns_list **list); +getdns_return_t getdns_str2bindata(const char *str, getdns_bindata **bindata); +getdns_return_t getdns_str2int(const char *str, uint32_t *value); #ifdef __cplusplus } diff --git a/src/test/jsmn b/src/jsmn similarity index 100% rename from src/test/jsmn rename to src/jsmn diff --git a/src/libgetdns.symbols b/src/libgetdns.symbols index 2eb8e381..88d1cebe 100644 --- a/src/libgetdns.symbols +++ b/src/libgetdns.symbols @@ -134,6 +134,10 @@ getdns_service getdns_service_sync getdns_snprint_json_dict getdns_snprint_json_list +getdns_str2bindata +getdns_str2dict +getdns_str2int +getdns_str2list getdns_str2rr_dict getdns_strerror getdns_validate_dnssec diff --git a/src/mk-const-info.c.sh b/src/mk-const-info.c.sh index 9e8b2826..f9c54323 100755 --- a/src/mk-const-info.c.sh +++ b/src/mk-const-info.c.sh @@ -46,18 +46,20 @@ getdns_get_errorstr_by_id(uint16_t err) else return NULL; } -END_OF_TAIL -gawk 'BEGIN{p=1}{if(p)print}/^static struct const_name_info consts_name_info\[\] = {$/{p=0}' test/getdns_str2dict.c > test/new-getdns_str2dict.c -gawk '/^[ ]+GETDNS_[A-Z_]+[ ]+=[ ]+[0-9]+/{ key = sprintf("%d", $3); consts[$1] = key; }/^#define GETDNS_[A-Z_]+[ ]+[0-9]+/ && !/_TEXT/{ key = sprintf("%d", $3); consts[$2] = key; }/^#define GETDNS_[A-Z_]+[ ]+\(\(getdns_(return|append_name)_t) [0-9]+ \)/{ key = sprintf("%d", $4); consts[$2] = key; }END{ n = asorti(consts, const_vals); for ( i = 1; i <= n; i++) { val = const_vals[i]; name = consts[val]; print "\t{ \""val"\", "name" },"}}' getdns/getdns.h.in getdns/getdns_extra.h.in | sed 's/,,/,/g' >> test/new-getdns_str2dict.c -cat >> test/new-getdns_str2dict.c << END_OF_TAIL +static struct const_name_info consts_name_info[] = { +END_OF_TAIL +gawk '/^[ ]+GETDNS_[A-Z_]+[ ]+=[ ]+[0-9]+/{ key = sprintf("%d", $3); consts[$1] = key; }/^#define GETDNS_[A-Z_]+[ ]+[0-9]+/ && !/_TEXT/{ key = sprintf("%d", $3); consts[$2] = key; }/^#define GETDNS_[A-Z_]+[ ]+\(\(getdns_(return|append_name)_t) [0-9]+ \)/{ key = sprintf("%d", $4); consts[$2] = key; }END{ n = asorti(consts, const_vals); for ( i = 1; i <= n; i++) { val = const_vals[i]; name = consts[val]; print "\t{ \""val"\", "name" },"}}' getdns/getdns.h.in getdns/getdns_extra.h.in | sed 's/,,/,/g' >> const-info.c +cat >> const-info.c << END_OF_TAIL }; + static int const_name_info_cmp(const void *a, const void *b) { return strcmp( ((struct const_name_info *) a)->name , ((struct const_name_info *) b)->name ); } -static int + +int _getdns_get_const_name_info(const char *name, uint32_t *code) { struct const_name_info key = { name, 0 }; @@ -71,5 +73,4 @@ _getdns_get_const_name_info(const char *name, uint32_t *code) return 1; } END_OF_TAIL -mv test/new-getdns_str2dict.c test/getdns_str2dict.c diff --git a/src/test/Makefile.in b/src/test/Makefile.in index 797f2e6e..f66494e7 100644 --- a/src/test/Makefile.in +++ b/src/test/Makefile.in @@ -66,16 +66,13 @@ CHECK_CFLAGS=@CHECK_CFLAGS@ CHECK_OBJS=check_getdns_common.lo check_getdns_context_set_timeout.lo \ check_getdns.lo check_getdns_transport.lo -DECOMPOSED_OBJS_WITHOUT_JSMN=getdns_str2dict.lo getdns_context_config.lo \ - getdns_context_set_listen_addresses.lo - -DECOMPOSED_OBJS=$(DECOMPOSED_OBJS_WITHOUT_JSMN) jsmn.lo +DECOMPOSED_OBJS=getdns_context_config.lo getdns_context_set_listen_addresses.lo ALL_OBJS=$(CHECK_OBJS) check_getdns_libevent.lo check_getdns_libev.lo \ check_getdns_selectloop.lo getdns_query.lo scratchpad.lo \ testmessages.lo tests_dict.lo tests_list.lo tests_namespaces.lo \ tests_stub_async.lo tests_stub_sync.lo \ - $(DECOMPOSED_OBJS_WITHOUT_JSMN) + $(DECOMPOSED_OBJS) NON_C99_OBJS=check_getdns_libuv.lo @@ -94,9 +91,6 @@ default: all all: $(PROGRAMS) -jsmn.lo: - $(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -DJSMN_GETDNS -c $(srcdir)/jsmn/jsmn.c -o $@ - $(ALL_OBJS): $(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -c $(srcdir)/$(@:.lo=.c) -o $@ @@ -221,7 +215,6 @@ depend: -e 's? \$$(srcdir)/\.\./config\.h? ../config.h?g' \ -e 's? \$$(srcdir)/\.\./getdns/getdns\.h? ../getdns/getdns.h?g' \ -e 's? \$$(srcdir)/\.\./getdns/getdns_extra\.h? ../getdns/getdns_extra.h?g' \ - -e 's? jsmn/jsmn\.h? $$(srcdir)/jsmn/jsmn.h?g' \ -e 's!\(.*\)\.o[ :]*!\1.lo \1.o: !g' >> Makefile.in.new ) (cd $(srcdir) ; diff Makefile.in.new Makefile.in && rm Makefile.in.new \ || mv Makefile.in.new Makefile.in ) @@ -273,20 +266,18 @@ check_getdns_selectloop.lo check_getdns_selectloop.o: $(srcdir)/check_getdns_sel check_getdns_transport.lo check_getdns_transport.o: $(srcdir)/check_getdns_transport.c \ $(srcdir)/check_getdns_transport.h $(srcdir)/check_getdns_common.h ../getdns/getdns.h \ ../getdns/getdns_extra.h +const-info.lo const-info.o: $(srcdir)/const-info.c getdns_context_config.lo getdns_context_config.o: $(srcdir)/getdns_context_config.c $(srcdir)/getdns_context_config.h \ ../getdns/getdns.h ../getdns/getdns_extra.h getdns_context_set_listen_addresses.lo getdns_context_set_listen_addresses.o: \ $(srcdir)/getdns_context_set_listen_addresses.c ../config.h \ $(srcdir)/getdns_context_set_listen_addresses.h ../getdns/getdns.h \ ../getdns/getdns_extra.h $(srcdir)/../types-internal.h ../getdns/getdns.h \ - ../getdns/getdns_extra.h $(srcdir)/../util/rbtree.h + ../getdns/getdns_extra.h $(srcdir)/../util/rbtree.h $(srcdir)/../debug.h ../config.h getdns_query.lo getdns_query.o: $(srcdir)/getdns_query.c ../config.h $(srcdir)/../debug.h ../config.h \ - $(srcdir)/getdns_str2dict.h ../getdns/getdns.h $(srcdir)/getdns_context_config.h \ + $(srcdir)/getdns_context_config.h ../getdns/getdns.h \ $(srcdir)/getdns_context_set_listen_addresses.h ../getdns/getdns_extra.h -getdns_str2dict.lo getdns_str2dict.o: $(srcdir)/getdns_str2dict.c ../config.h $(srcdir)/../const-info.h \ - $(srcdir)/jsmn/jsmn.h $(srcdir)/getdns_str2dict.h ../getdns/getdns.h $(srcdir)/../types-internal.h \ - ../getdns/getdns.h ../getdns/getdns_extra.h $(srcdir)/../util/rbtree.h $(srcdir)/../list.h \ - $(srcdir)/../types-internal.h $(srcdir)/../dict.h +new-getdns_str2dict.lo new-getdns_str2dict.o: $(srcdir)/new-getdns_str2dict.c scratchpad.template.lo scratchpad.template.o: scratchpad.template.c ../getdns/getdns.h \ ../getdns/getdns_extra.h testmessages.lo testmessages.o: $(srcdir)/testmessages.c $(srcdir)/testmessages.h diff --git a/src/test/getdns_query.c b/src/test/getdns_query.c index 09184e6d..ced608bb 100644 --- a/src/test/getdns_query.c +++ b/src/test/getdns_query.c @@ -27,7 +27,6 @@ #include "config.h" #include "debug.h" -#include "getdns_str2dict.h" #include "getdns_context_config.h" #include "getdns_context_set_listen_addresses.h" #include diff --git a/src/test/getdns_str2dict.c b/src/test/getdns_str2dict.c deleted file mode 100644 index ae5fb1d9..00000000 --- a/src/test/getdns_str2dict.c +++ /dev/null @@ -1,951 +0,0 @@ -/* - * Copyright (c) 2013, NLNet Labs, Verisign, Inc. - * 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 names of the copyright holders 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 Verisign, Inc. 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 "config.h" -#include "const-info.h" -#include "jsmn/jsmn.h" -#include "getdns_str2dict.h" -#include "types-internal.h" /* For getdns_item */ -#include "list.h" /* For _getdns_list_create_from_mf() */ -#include "dict.h" /* For _getdns_dict_create_from_mf() */ -#include /* For bsearch */ - -static struct mem_funcs _getdns_plain_mem_funcs = { - MF_PLAIN, .mf.pln = { malloc, realloc, free } -}; - -/* TODO: Replace with gldns_b64_pton - * once getdns_ipaddr_dict becomes part of the library - */ -static int _gldns_b64_pton(char const *src, uint8_t *target, size_t targsize) -{ - const uint8_t pad64 = 64; /* is 64th in the b64 array */ - const char* s = src; - uint8_t in[4]; - size_t o = 0, incount = 0; - - while(*s) { - /* skip any character that is not base64 */ - /* conceptually we do: - const char* b64 = pad'=' is appended to array - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; - const char* d = strchr(b64, *s++); - and use d-b64; - */ - char d = *s++; - if(d <= 'Z' && d >= 'A') - d -= 'A'; - else if(d <= 'z' && d >= 'a') - d = d - 'a' + 26; - else if(d <= '9' && d >= '0') - d = d - '0' + 52; - else if(d == '+') - d = 62; - else if(d == '/') - d = 63; - else if(d == '=') - d = 64; - else continue; - in[incount++] = (uint8_t)d; - if(incount != 4) - continue; - /* process whole block of 4 characters into 3 output bytes */ - if(in[3] == pad64 && in[2] == pad64) { /* A B = = */ - if(o+1 > targsize) - return -1; - target[o] = (in[0]<<2) | ((in[1]&0x30)>>4); - o += 1; - break; /* we are done */ - } else if(in[3] == pad64) { /* A B C = */ - if(o+2 > targsize) - return -1; - target[o] = (in[0]<<2) | ((in[1]&0x30)>>4); - target[o+1]= ((in[1]&0x0f)<<4) | ((in[2]&0x3c)>>2); - o += 2; - break; /* we are done */ - } else { - if(o+3 > targsize) - return -1; - /* write xxxxxxyy yyyyzzzz zzwwwwww */ - target[o] = (in[0]<<2) | ((in[1]&0x30)>>4); - target[o+1]= ((in[1]&0x0f)<<4) | ((in[2]&0x3c)>>2); - target[o+2]= ((in[2]&0x03)<<6) | in[3]; - o += 3; - } - incount = 0; - } - return (int)o; -} - -static getdns_dict * -_getdns_ipaddr_dict_mf(struct mem_funcs *mf, char *ipstr) -{ - getdns_dict *r = _getdns_dict_create_with_mf(mf); - char *s = strchr(ipstr, '%'), *scope_id_str = ""; - char *p = strchr(ipstr, '@'), *portstr = ""; - char *t = strchr(ipstr, '#'), *tls_portstr = ""; - char *n = strchr(ipstr, '~'), *tls_namestr = ""; - /* ^[alg:]name:key */ - char *T = strchr(ipstr, '^'), *tsig_name_str = "" - , *tsig_secret_str = "" - , *tsig_algorithm_str = ""; - char *br, *c; - int tsig_secret_size; - uint8_t tsig_secret_buf[256]; /* 4 times SHA512 */ - getdns_bindata tsig_secret; - uint8_t buf[sizeof(struct in6_addr)]; - getdns_bindata addr; - - addr.data = buf; - - if (!r) return NULL; - - if (*ipstr == '[') { - char *br = strchr(ipstr, ']'); - if (br) { - ipstr += 1; - *br = 0; - if ((c = strchr(br + 1, ':'))) { - p = c; - } - } - } else if ((br = strchr(ipstr, '.')) && (c = strchr(br + 1, ':')) - && (T == NULL || c < T)) - p = c; - - else if ((*ipstr == '*') && (c = strchr(ipstr+1, ':'))) - p = c; - - if (s) { - *s = 0; - scope_id_str = s + 1; - } - if (p) { - *p = 0; - portstr = p + 1; - } - if (t) { - *t = 0; - tls_portstr = t + 1; - } - if (n) { - *n = 0; - tls_namestr = n + 1; - } - if (T) { - *T = 0; - tsig_name_str = T + 1; - if ((T = strchr(tsig_name_str, ':'))) { - *T = 0; - tsig_secret_str = T + 1; - if ((T = strchr(tsig_secret_str, ':'))) { - *T = 0; - tsig_algorithm_str = tsig_name_str; - tsig_name_str = tsig_secret_str; - tsig_secret_str = T + 1; - } - } else { - tsig_name_str = ""; - } - } - if (*ipstr == '*') { - getdns_dict_util_set_string(r, "address_type", "IPv6"); - addr.size = 16; - (void) memset(buf, 0, 16); - } else if (strchr(ipstr, ':')) { - getdns_dict_util_set_string(r, "address_type", "IPv6"); - addr.size = 16; - if (inet_pton(AF_INET6, ipstr, buf) <= 0) { - getdns_dict_destroy(r); - return NULL; - } - } else { - getdns_dict_util_set_string(r, "address_type", "IPv4"); - addr.size = 4; - if (inet_pton(AF_INET, ipstr, buf) <= 0) { - getdns_dict_destroy(r); - return NULL; - } - } - getdns_dict_set_bindata(r, "address_data", &addr); - if (*portstr) - getdns_dict_set_int(r, "port", (int32_t)atoi(portstr)); - if (*tls_portstr) - getdns_dict_set_int(r, "tls_port", (int32_t)atoi(tls_portstr)); - if (*tls_namestr) { - getdns_dict_util_set_string(r, "tls_auth_name", tls_namestr); - } - if (*scope_id_str) - getdns_dict_util_set_string(r, "scope_id", scope_id_str); - if (*tsig_name_str) - getdns_dict_util_set_string(r, "tsig_name", tsig_name_str); - if (*tsig_algorithm_str) - getdns_dict_util_set_string(r, "tsig_algorithm", tsig_algorithm_str); - if (*tsig_secret_str) { - tsig_secret_size = _gldns_b64_pton( - tsig_secret_str, tsig_secret_buf, sizeof(tsig_secret_buf)); - if (tsig_secret_size > 0) { - tsig_secret.size = tsig_secret_size; - tsig_secret.data = tsig_secret_buf; - getdns_dict_set_bindata(r, "tsig_secret", &tsig_secret); - } - } - return r; -} - -static int _jsmn_get_ipdict(struct mem_funcs *mf, const char *js, jsmntok_t *t, - getdns_dict **value) -{ - char value_str[3072]; - int size = t->end - t->start; - - if (size <= 0 || size >= sizeof(value_str)) - return 0; - - (void) memcpy(value_str, js + t->start, size); - value_str[size] = '\0'; - - *value = _getdns_ipaddr_dict_mf(mf, value_str); - return *value != NULL; -} - -static int _jsmn_get_data(struct mem_funcs *mf, const char *js, jsmntok_t *t, - getdns_bindata **value) -{ - size_t i, j; - uint8_t h, l; - - if ((t->end - t->start) < 4 || (t->end - t->start) % 2 == 1 || - js[t->start] != '0' || js[t->start + 1] != 'x') - return 0; - - for (i = t->start + 2; i < t->end; i++) - if (!((js[i] >= '0' && js[i] <= '9') - ||(js[i] >= 'a' && js[i] <= 'f') - ||(js[i] >= 'A' && js[i] <= 'F'))) - return 0; - - if (!(*value = GETDNS_MALLOC(*mf, getdns_bindata))) - return 0; - - else if (!((*value)->data = GETDNS_XMALLOC( - *mf, uint8_t, (t->end - t->start) / 2 - 1))) { - GETDNS_FREE(*mf, *value); - return 0; - } - for (i = t->start + 2, j = 0; i < t->end; i++, j++) { - h = js[i] >= '0' && js[i] <= '9' ? js[i] - '0' - : js[i] >= 'A' && js[i] <= 'F' ? js[i] + 10 - 'A' - : js[i] + 10 - 'a'; - h <<= 4; - i++; - l = js[i] >= '0' && js[i] <= '9' ? js[i] - '0' - : js[i] >= 'A' && js[i] <= 'F' ? js[i] + 10 - 'A' - : js[i] + 10 - 'a'; - (*value)->data[j] = h | l; - } - (*value)->size = j; - return 1; -} - -static int _jsmn_get_dname(struct mem_funcs *mf, const char *js, jsmntok_t *t, - getdns_bindata **value) -{ - char value_str[1025]; - int size = t->end - t->start; - - if (size <= 0 || size >= sizeof(value_str) || js[t->end - 1] != '.') - return 0; - - (void) memcpy(value_str, js + t->start, size); - value_str[size] = '\0'; - - return !getdns_convert_fqdn_to_dns_name(value_str, value); -} - -static int _jsmn_get_ipv4(struct mem_funcs *mf, const char *js, jsmntok_t *t, - getdns_bindata **value) -{ - char value_str[16]; - int size = t->end - t->start; - uint8_t buf[4]; - - if (size <= 0 || size >= sizeof(value_str)) - return 0; - - (void) memcpy(value_str, js + t->start, size); - value_str[size] = '\0'; - - if (inet_pton(AF_INET, value_str, buf) <= 0) - ; /* pass */ - - else if (!(*value = GETDNS_MALLOC(*mf, getdns_bindata))) - ; /* pass */ - - else if (!((*value)->data = GETDNS_XMALLOC(*mf, uint8_t, 4))) - GETDNS_FREE(*mf, *value); - - else { - (*value)->size = 4; - (void) memcpy((*value)->data, buf, 4); - return 1; - } - return 0; -} - -static int _jsmn_get_ipv6(struct mem_funcs *mf, const char *js, jsmntok_t *t, - getdns_bindata **value) -{ - char value_str[40]; - int size = t->end - t->start; - uint8_t buf[16]; - - if (size <= 0 || size >= sizeof(value_str)) - return 0; - - (void) memcpy(value_str, js + t->start, size); - value_str[size] = '\0'; - - if (inet_pton(AF_INET6, value_str, buf) <= 0) - ; /* pass */ - - else if (!(*value = GETDNS_MALLOC(*mf, getdns_bindata))) - ; /* pass */ - - else if (!((*value)->data = GETDNS_XMALLOC(*mf, uint8_t, 16))) - GETDNS_FREE(*mf, *value); - - else { - (*value)->size = 16; - (void) memcpy((*value)->data, buf, 16); - return 1; - } - return 0; -} - -static int _jsmn_get_int(struct mem_funcs *mf, const char *js, jsmntok_t *t, - uint32_t *value) -{ - char value_str[11]; - int size = t->end - t->start; - char *endptr; - - if (size <= 0 || size >= sizeof(value_str)) - return 0; - - (void) memcpy(value_str, js + t->start, size); - value_str[size] = '\0'; - - *value = (uint32_t)strtoul(value_str, &endptr, 10); - return *value_str != '\0' && *endptr == '\0'; -} - -static int _getdns_get_const_name_info(const char *name, uint32_t *code); - -static int _jsmn_get_const(struct mem_funcs *mf, const char *js, jsmntok_t *t, - uint32_t *value) -{ - char value_str[80]; - int size = t->end - t->start; - - if (size <= 0 || size >= sizeof(value_str)) - return 0; - - (void) memcpy(value_str, js + t->start, size); - value_str[size] = '\0'; - - return _getdns_get_const_name_info(value_str, value); -} - -static void -_getdns_destroy_item_data(struct mem_funcs *mf, getdns_item *item) -{ - switch (item->dtype) { - case t_dict: - getdns_dict_destroy(item->data.dict); - break; - - case t_list: - getdns_list_destroy(item->data.list); - break; - - case t_bindata: - GETDNS_FREE(*mf, item->data.bindata->data); - GETDNS_FREE(*mf, item->data.bindata); - default: - break; - } -} -static int _jsmn_get_item(struct mem_funcs *mf, const char *js, jsmntok_t *t, - size_t count, getdns_item *item, getdns_return_t *r); - -static int _jsmn_get_dict(struct mem_funcs *mf, const char *js, jsmntok_t *t, - size_t count, getdns_dict *dict, getdns_return_t *r) -{ - size_t i, j = 1; - char key_spc[1024], *key = NULL; - getdns_item child_item; - - for (i = 0; i < t->size; i++) { - if (t[j].type != JSMN_STRING && - t[j].type != JSMN_PRIMITIVE) { - - /* Key must be string or primitive */ - *r = GETDNS_RETURN_WRONG_TYPE_REQUESTED; - break; - } - if (t[j].end <= t[j].start) { - /* Key must be at least 1 character */ - *r = GETDNS_RETURN_GENERIC_ERROR; /* range error */ - break; - } - if (t[j].end - t[j].start < sizeof(key_spc)) - key = key_spc; - - else if (!(key = GETDNS_XMALLOC( - *mf, char, t[j].end - t[j].start + 1))) { - - *r = GETDNS_RETURN_MEMORY_ERROR; - break; - } - (void) memcpy(key, js + t[j].start, t[j].end - t[j].start); - key[t[j].end - t[j].start] = '\0'; - j += 1; - - j += _jsmn_get_item(mf, js, t + j, count - j, &child_item, r); - if (*r) break; - - switch (child_item.dtype) { - case t_int: - *r = getdns_dict_set_int(dict, key, - child_item.data.n); - break; - case t_bindata: - *r = getdns_dict_set_bindata(dict, key, - child_item.data.bindata); - break; - case t_list: - *r = getdns_dict_set_list(dict, key, - child_item.data.list); - break; - case t_dict: - *r = getdns_dict_set_dict(dict, key, - child_item.data.dict); - break; - default: - *r = GETDNS_RETURN_WRONG_TYPE_REQUESTED; - break; - - } - _getdns_destroy_item_data(mf, &child_item); - if (*r) break; - if (key && key != key_spc) { - GETDNS_FREE(*mf, key); - key = NULL; - } - } - if (key && key != key_spc) - GETDNS_FREE(*mf, key); - - if (*r) { - getdns_dict_destroy(dict); - return 0; - } - return j; -} - -static int _jsmn_get_list(struct mem_funcs *mf, const char *js, jsmntok_t *t, - size_t count, getdns_list *list, getdns_return_t *r) -{ - size_t i, j = 1, index = 0; - getdns_item child_item; - - for (i = 0; i < t->size; i++) { - j += _jsmn_get_item(mf, js, t + j, count - j, &child_item, r); - if (*r) break; - - switch (child_item.dtype) { - case t_int: - *r = getdns_list_set_int(list, index++, - child_item.data.n); - break; - case t_bindata: - *r = getdns_list_set_bindata(list, index++, - child_item.data.bindata); - break; - case t_list: - *r = getdns_list_set_list(list, index++, - child_item.data.list); - break; - case t_dict: - *r = getdns_list_set_dict(list, index++, - child_item.data.dict); - break; - default: - *r = GETDNS_RETURN_WRONG_TYPE_REQUESTED; - break; - - } - _getdns_destroy_item_data(mf, &child_item); - if (*r) break; - } - if (*r) { - getdns_list_destroy(list); - return 0; - } - return j; -} - -static int _jsmn_get_item(struct mem_funcs *mf, const char *js, jsmntok_t *t, - size_t count, getdns_item *item, getdns_return_t *r) -{ - assert(item); - - switch (t->type) { - case JSMN_STRING: - if (t->end < t->start) - *r = GETDNS_RETURN_GENERIC_ERROR; - - else if (!(item->data.bindata = - GETDNS_MALLOC(*mf, getdns_bindata))) - *r = GETDNS_RETURN_MEMORY_ERROR; - - else if (!(item->data.bindata->data = GETDNS_XMALLOC( - *mf, uint8_t, t->end - t->start + 1))) { - GETDNS_FREE(*mf, item->data.bindata); - *r = GETDNS_RETURN_MEMORY_ERROR; - } else { - item->dtype = t_bindata; - if (t->end - t->start) { - (void) memcpy(item->data.bindata->data, - js + t->start, t->end - t->start); - } - item->data.bindata->data[t->end - t->start] = '\0'; - item->data.bindata->size = t->end - t->start; - *r = GETDNS_RETURN_GOOD; - return 1; - } - break; - - case JSMN_PRIMITIVE: - /* There is no such thing as an empty primitive */ - if (t->end <= t->start) { - *r = GETDNS_RETURN_GENERIC_ERROR; - break; - - } else if (_jsmn_get_int(mf, js, t, &item->data.n) - || _jsmn_get_const(mf, js, t, &item->data.n)) { - - item->dtype = t_int; - } - else if (_jsmn_get_data(mf, js, t, &item->data.bindata) - || _jsmn_get_dname(mf, js, t, &item->data.bindata) - || _jsmn_get_ipv4(mf, js, t, &item->data.bindata) - || _jsmn_get_ipv6(mf, js, t, &item->data.bindata)) - - item->dtype = t_bindata; - - else if (_jsmn_get_ipdict(mf, js, t, &item->data.dict)) - - item->dtype = t_dict; - else { - *r = GETDNS_RETURN_GENERIC_ERROR; - break; - } - *r = GETDNS_RETURN_GOOD; - return 1; - - case JSMN_OBJECT: - if (!(item->data.dict = _getdns_dict_create_with_mf(mf))) { - *r = GETDNS_RETURN_MEMORY_ERROR; - break; - } - item->dtype = t_dict; - return _jsmn_get_dict(mf, js, t, count, item->data.dict, r); - - case JSMN_ARRAY: - if (!(item->data.list = _getdns_list_create_with_mf(mf))) { - *r = GETDNS_RETURN_MEMORY_ERROR; - break; - } - item->dtype = t_list; - return _jsmn_get_list(mf, js, t, count, item->data.list, r); - - default: - *r = GETDNS_RETURN_WRONG_TYPE_REQUESTED; - break; - } - return 0; -} - -static getdns_return_t -_getdns_str2item_mf(struct mem_funcs *mf, const char *str, getdns_item *item) -{ - jsmn_parser p; - jsmntok_t *tok = NULL, *new_tok; - size_t tokcount = 100; - int r; - getdns_return_t gr; - - jsmn_init(&p); - tok = GETDNS_XMALLOC(*mf, jsmntok_t, tokcount); - do { - r = jsmn_parse(&p, str, strlen(str), tok, tokcount); - if (r == JSMN_ERROR_NOMEM) { - tokcount *= 2; - if (!(new_tok = GETDNS_XREALLOC( - *mf, tok, jsmntok_t, tokcount))) { - GETDNS_FREE(*mf, tok); - return GETDNS_RETURN_MEMORY_ERROR; - } - tok = new_tok; - } - } while (r == JSMN_ERROR_NOMEM); - if (r < 0) - gr = GETDNS_RETURN_GENERIC_ERROR; - else - (void) _jsmn_get_item(mf, str, tok, p.toknext, item, &gr); - GETDNS_FREE(*mf, tok); - return gr; -} - -getdns_return_t -getdns_str2dict(const char *str, getdns_dict **dict) -{ - getdns_item item; - getdns_return_t r; - - if ((r = _getdns_str2item_mf(&_getdns_plain_mem_funcs, str, &item))) - return r; - - else if (item.dtype != t_dict) { - uint8_t buf[16]; - getdns_dict *dict_r; - - if (item.dtype != t_bindata) - r = GETDNS_RETURN_WRONG_TYPE_REQUESTED; - - else if (item.data.bindata->size == 4 && - inet_pton(AF_INET, str, buf) == 1) { - - if (!(dict_r = getdns_dict_create())) - r = GETDNS_RETURN_MEMORY_ERROR; - - else if ((r = getdns_dict_util_set_string( - dict_r, "address_type", "IPv4"))) - getdns_dict_destroy(dict_r); - - else if ((r = getdns_dict_set_bindata( - dict_r, "address_data", item.data.bindata))) - getdns_dict_destroy(dict_r); - else - *dict = dict_r; - - } else if (item.data.bindata->size == 16 && - inet_pton(AF_INET6, str, buf) == 1) { - - if (!(dict_r = getdns_dict_create())) - r = GETDNS_RETURN_MEMORY_ERROR; - - else if ((r = getdns_dict_util_set_string( - dict_r, "address_type", "IPv6"))) - getdns_dict_destroy(dict_r); - - else if ((r = getdns_dict_set_bindata( - dict_r, "address_data", item.data.bindata))) - getdns_dict_destroy(dict_r); - else - *dict = dict_r; - } else - r = GETDNS_RETURN_WRONG_TYPE_REQUESTED; - - _getdns_destroy_item_data(&_getdns_plain_mem_funcs, &item); - return r; - } - *dict = item.data.dict; - return GETDNS_RETURN_GOOD; -} - -getdns_return_t -getdns_str2list(const char *str, getdns_list **list) -{ - getdns_item item; - getdns_return_t r; - - if ((r = _getdns_str2item_mf(&_getdns_plain_mem_funcs, str, &item))) - return r; - - else if (item.dtype != t_list) { - _getdns_destroy_item_data(&_getdns_plain_mem_funcs, &item); - return GETDNS_RETURN_WRONG_TYPE_REQUESTED; - } - *list = item.data.list; - return GETDNS_RETURN_GOOD; -} - -getdns_return_t -getdns_str2bindata(const char *str, getdns_bindata **bindata) -{ - getdns_item item; - getdns_return_t r; - - if ((r = _getdns_str2item_mf(&_getdns_plain_mem_funcs, str, &item))) - return r; - - else if (item.dtype != t_bindata) { - _getdns_destroy_item_data(&_getdns_plain_mem_funcs, &item); - return GETDNS_RETURN_WRONG_TYPE_REQUESTED; - } - *bindata = item.data.bindata; - return GETDNS_RETURN_GOOD; -} - -getdns_return_t -getdns_str2int(const char *str, uint32_t *value) -{ - getdns_item item; - getdns_return_t r; - - if ((r = _getdns_str2item_mf(&_getdns_plain_mem_funcs, str, &item))) - return r; - - else if (item.dtype != t_int) { - _getdns_destroy_item_data(&_getdns_plain_mem_funcs, &item); - return GETDNS_RETURN_WRONG_TYPE_REQUESTED; - } - *value = item.data.n; - return GETDNS_RETURN_GOOD; -} - - -struct const_name_info { const char *name; uint32_t code; }; -static struct const_name_info consts_name_info[] = { - { "GETDNS_APPEND_NAME_ALWAYS", 550 }, - { "GETDNS_APPEND_NAME_NEVER", 553 }, - { "GETDNS_APPEND_NAME_ONLY_TO_MULTIPLE_LABEL_NAME_AFTER_FAILURE", 552 }, - { "GETDNS_APPEND_NAME_ONLY_TO_SINGLE_LABEL_AFTER_FAILURE", 551 }, - { "GETDNS_APPEND_NAME_TO_SINGLE_LABEL_FIRST", 554 }, - { "GETDNS_AUTHENTICATION_NONE", 1300 }, - { "GETDNS_AUTHENTICATION_REQUIRED", 1301 }, - { "GETDNS_BAD_DNS_ALL_NUMERIC_LABEL", 1101 }, - { "GETDNS_BAD_DNS_CNAME_IN_TARGET", 1100 }, - { "GETDNS_BAD_DNS_CNAME_RETURNED_FOR_OTHER_TYPE", 1102 }, - { "GETDNS_CALLBACK_CANCEL", 701 }, - { "GETDNS_CALLBACK_COMPLETE", 700 }, - { "GETDNS_CALLBACK_ERROR", 703 }, - { "GETDNS_CALLBACK_TIMEOUT", 702 }, - { "GETDNS_CONTEXT_CODE_APPEND_NAME", 607 }, - { "GETDNS_CONTEXT_CODE_DNSSEC_ALLOWED_SKEW", 614 }, - { "GETDNS_CONTEXT_CODE_DNSSEC_TRUST_ANCHORS", 609 }, - { "GETDNS_CONTEXT_CODE_DNS_ROOT_SERVERS", 604 }, - { "GETDNS_CONTEXT_CODE_DNS_TRANSPORT", 605 }, - { "GETDNS_CONTEXT_CODE_EDNS_CLIENT_SUBNET_PRIVATE", 619 }, - { "GETDNS_CONTEXT_CODE_EDNS_DO_BIT", 613 }, - { "GETDNS_CONTEXT_CODE_EDNS_EXTENDED_RCODE", 611 }, - { "GETDNS_CONTEXT_CODE_EDNS_MAXIMUM_UDP_PAYLOAD_SIZE", 610 }, - { "GETDNS_CONTEXT_CODE_EDNS_VERSION", 612 }, - { "GETDNS_CONTEXT_CODE_FOLLOW_REDIRECTS", 602 }, - { "GETDNS_CONTEXT_CODE_IDLE_TIMEOUT", 617 }, - { "GETDNS_CONTEXT_CODE_LIMIT_OUTSTANDING_QUERIES", 606 }, - { "GETDNS_CONTEXT_CODE_MEMORY_FUNCTIONS", 615 }, - { "GETDNS_CONTEXT_CODE_NAMESPACES", 600 }, - { "GETDNS_CONTEXT_CODE_PUBKEY_PINSET", 621 }, - { "GETDNS_CONTEXT_CODE_RESOLUTION_TYPE", 601 }, - { "GETDNS_CONTEXT_CODE_SUFFIX", 608 }, - { "GETDNS_CONTEXT_CODE_TIMEOUT", 616 }, - { "GETDNS_CONTEXT_CODE_TLS_AUTHENTICATION", 618 }, - { "GETDNS_CONTEXT_CODE_TLS_QUERY_PADDING_BLOCKSIZE", 620 }, - { "GETDNS_CONTEXT_CODE_UPSTREAM_RECURSIVE_SERVERS", 603 }, - { "GETDNS_DNSSEC_BOGUS", 401 }, - { "GETDNS_DNSSEC_INDETERMINATE", 402 }, - { "GETDNS_DNSSEC_INSECURE", 403 }, - { "GETDNS_DNSSEC_NOT_PERFORMED", 404 }, - { "GETDNS_DNSSEC_SECURE", 400 }, - { "GETDNS_EXTENSION_FALSE", 1001 }, - { "GETDNS_EXTENSION_TRUE", 1000 }, - { "GETDNS_NAMESPACE_DNS", 500 }, - { "GETDNS_NAMESPACE_LOCALNAMES", 501 }, - { "GETDNS_NAMESPACE_MDNS", 503 }, - { "GETDNS_NAMESPACE_NETBIOS", 502 }, - { "GETDNS_NAMESPACE_NIS", 504 }, - { "GETDNS_NAMETYPE_DNS", 800 }, - { "GETDNS_NAMETYPE_WINS", 801 }, - { "GETDNS_OPCODE_IQUERY", 1 }, - { "GETDNS_OPCODE_NOTIFY", 4 }, - { "GETDNS_OPCODE_QUERY", 0 }, - { "GETDNS_OPCODE_STATUS", 2 }, - { "GETDNS_OPCODE_UPDATE", 5 }, - { "GETDNS_RCODE_BADALG", 21 }, - { "GETDNS_RCODE_BADKEY", 17 }, - { "GETDNS_RCODE_BADMODE", 19 }, - { "GETDNS_RCODE_BADNAME", 20 }, - { "GETDNS_RCODE_BADSIG", 16 }, - { "GETDNS_RCODE_BADTIME", 18 }, - { "GETDNS_RCODE_BADTRUNC", 22 }, - { "GETDNS_RCODE_BADVERS", 16 }, - { "GETDNS_RCODE_FORMERR", 1 }, - { "GETDNS_RCODE_NOERROR", 0 }, - { "GETDNS_RCODE_NOTAUTH", 9 }, - { "GETDNS_RCODE_NOTIMP", 4 }, - { "GETDNS_RCODE_NOTZONE", 10 }, - { "GETDNS_RCODE_NXDOMAIN", 3 }, - { "GETDNS_RCODE_NXRRSET", 8 }, - { "GETDNS_RCODE_REFUSED", 5 }, - { "GETDNS_RCODE_SERVFAIL", 2 }, - { "GETDNS_RCODE_YXDOMAIN", 6 }, - { "GETDNS_RCODE_YXRRSET", 7 }, - { "GETDNS_REDIRECTS_DO_NOT_FOLLOW", 531 }, - { "GETDNS_REDIRECTS_FOLLOW", 530 }, - { "GETDNS_RESOLUTION_RECURSING", 521 }, - { "GETDNS_RESOLUTION_STUB", 520 }, - { "GETDNS_RESPSTATUS_ALL_BOGUS_ANSWERS", 904 }, - { "GETDNS_RESPSTATUS_ALL_TIMEOUT", 902 }, - { "GETDNS_RESPSTATUS_GOOD", 900 }, - { "GETDNS_RESPSTATUS_NO_NAME", 901 }, - { "GETDNS_RESPSTATUS_NO_SECURE_ANSWERS", 903 }, - { "GETDNS_RETURN_BAD_CONTEXT", 301 }, - { "GETDNS_RETURN_BAD_DOMAIN_NAME", 300 }, - { "GETDNS_RETURN_CONTEXT_UPDATE_FAIL", 302 }, - { "GETDNS_RETURN_DNSSEC_WITH_STUB_DISALLOWED", 309 }, - { "GETDNS_RETURN_EXTENSION_MISFORMAT", 308 }, - { "GETDNS_RETURN_GENERIC_ERROR", 1 }, - { "GETDNS_RETURN_GOOD", 0 }, - { "GETDNS_RETURN_INVALID_PARAMETER", 311 }, - { "GETDNS_RETURN_MEMORY_ERROR", 310 }, - { "GETDNS_RETURN_NEED_MORE_SPACE", 399 }, - { "GETDNS_RETURN_NOT_IMPLEMENTED", 312 }, - { "GETDNS_RETURN_NO_SUCH_DICT_NAME", 305 }, - { "GETDNS_RETURN_NO_SUCH_EXTENSION", 307 }, - { "GETDNS_RETURN_NO_SUCH_LIST_ITEM", 304 }, - { "GETDNS_RETURN_UNKNOWN_TRANSACTION", 303 }, - { "GETDNS_RETURN_WRONG_TYPE_REQUESTED", 306 }, - { "GETDNS_RRCLASS_ANY", 255 }, - { "GETDNS_RRCLASS_CH", 3 }, - { "GETDNS_RRCLASS_HS", 4 }, - { "GETDNS_RRCLASS_IN", 1 }, - { "GETDNS_RRCLASS_NONE", 254 }, - { "GETDNS_RRTYPE_A", 1 }, - { "GETDNS_RRTYPE_AAAA", 28 }, - { "GETDNS_RRTYPE_AFSDB", 18 }, - { "GETDNS_RRTYPE_ANY", 255 }, - { "GETDNS_RRTYPE_APL", 42 }, - { "GETDNS_RRTYPE_ATMA", 34 }, - { "GETDNS_RRTYPE_AXFR", 252 }, - { "GETDNS_RRTYPE_CAA", 257 }, - { "GETDNS_RRTYPE_CDNSKEY", 60 }, - { "GETDNS_RRTYPE_CDS", 59 }, - { "GETDNS_RRTYPE_CERT", 37 }, - { "GETDNS_RRTYPE_CNAME", 5 }, - { "GETDNS_RRTYPE_CSYNC", 62 }, - { "GETDNS_RRTYPE_DHCID", 49 }, - { "GETDNS_RRTYPE_DLV", 32769 }, - { "GETDNS_RRTYPE_DNAME", 39 }, - { "GETDNS_RRTYPE_DNSKEY", 48 }, - { "GETDNS_RRTYPE_DS", 43 }, - { "GETDNS_RRTYPE_EID", 31 }, - { "GETDNS_RRTYPE_GID", 102 }, - { "GETDNS_RRTYPE_GPOS", 27 }, - { "GETDNS_RRTYPE_HINFO", 13 }, - { "GETDNS_RRTYPE_HIP", 55 }, - { "GETDNS_RRTYPE_IPSECKEY", 45 }, - { "GETDNS_RRTYPE_ISDN", 20 }, - { "GETDNS_RRTYPE_IXFR", 251 }, - { "GETDNS_RRTYPE_KEY", 25 }, - { "GETDNS_RRTYPE_KX", 36 }, - { "GETDNS_RRTYPE_LOC", 29 }, - { "GETDNS_RRTYPE_LP", 107 }, - { "GETDNS_RRTYPE_MAILA", 254 }, - { "GETDNS_RRTYPE_MAILB", 253 }, - { "GETDNS_RRTYPE_MB", 7 }, - { "GETDNS_RRTYPE_MD", 3 }, - { "GETDNS_RRTYPE_MF", 4 }, - { "GETDNS_RRTYPE_MG", 8 }, - { "GETDNS_RRTYPE_MINFO", 14 }, - { "GETDNS_RRTYPE_MR", 9 }, - { "GETDNS_RRTYPE_MX", 15 }, - { "GETDNS_RRTYPE_NAPTR", 35 }, - { "GETDNS_RRTYPE_NID", 104 }, - { "GETDNS_RRTYPE_NIMLOC", 32 }, - { "GETDNS_RRTYPE_NINFO", 56 }, - { "GETDNS_RRTYPE_NS", 2 }, - { "GETDNS_RRTYPE_NSAP", 22 }, - { "GETDNS_RRTYPE_NSEC", 47 }, - { "GETDNS_RRTYPE_NULL", 10 }, - { "GETDNS_RRTYPE_NXT", 30 }, - { "GETDNS_RRTYPE_OPENPGPKEY", 61 }, - { "GETDNS_RRTYPE_OPT", 41 }, - { "GETDNS_RRTYPE_PTR", 12 }, - { "GETDNS_RRTYPE_PX", 26 }, - { "GETDNS_RRTYPE_RKEY", 57 }, - { "GETDNS_RRTYPE_RP", 17 }, - { "GETDNS_RRTYPE_RRSIG", 46 }, - { "GETDNS_RRTYPE_RT", 21 }, - { "GETDNS_RRTYPE_SIG", 24 }, - { "GETDNS_RRTYPE_SINK", 40 }, - { "GETDNS_RRTYPE_SOA", 6 }, - { "GETDNS_RRTYPE_SPF", 99 }, - { "GETDNS_RRTYPE_SRV", 33 }, - { "GETDNS_RRTYPE_SSHFP", 44 }, - { "GETDNS_RRTYPE_TA", 32768 }, - { "GETDNS_RRTYPE_TALINK", 58 }, - { "GETDNS_RRTYPE_TKEY", 249 }, - { "GETDNS_RRTYPE_TLSA", 52 }, - { "GETDNS_RRTYPE_TSIG", 250 }, - { "GETDNS_RRTYPE_TXT", 16 }, - { "GETDNS_RRTYPE_UID", 101 }, - { "GETDNS_RRTYPE_UINFO", 100 }, - { "GETDNS_RRTYPE_UNSPEC", 103 }, - { "GETDNS_RRTYPE_URI", 256 }, - { "GETDNS_RRTYPE_WKS", 11 }, - { "GETDNS_TRANSPORT_TCP", 1201 }, - { "GETDNS_TRANSPORT_TCP_ONLY", 542 }, - { "GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN", 543 }, - { "GETDNS_TRANSPORT_TLS", 1202 }, - { "GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN", 545 }, - { "GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN", 544 }, - { "GETDNS_TRANSPORT_UDP", 1200 }, - { "GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP", 540 }, - { "GETDNS_TRANSPORT_UDP_ONLY", 541 }, -}; -static int const_name_info_cmp(const void *a, const void *b) -{ - return strcmp( ((struct const_name_info *) a)->name - , ((struct const_name_info *) b)->name ); -} -static int -_getdns_get_const_name_info(const char *name, uint32_t *code) -{ - struct const_name_info key = { name, 0 }; - struct const_name_info *i = bsearch(&key, consts_name_info, - sizeof(consts_name_info) / sizeof(struct const_name_info), - sizeof(struct const_name_info), const_name_info_cmp); - if (!i) - return 0; - if (code) - *code = i->code; - return 1; -} diff --git a/src/test/getdns_str2dict.h b/src/test/getdns_str2dict.h deleted file mode 100644 index 71cb26c8..00000000 --- a/src/test/getdns_str2dict.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2013, NLNet Labs, Verisign, Inc. - * 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 names of the copyright holders 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 Verisign, Inc. 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 GETDNS_STR2DICT_H_ -#define GETDNS_STR2DICT_H_ -#include "getdns/getdns.h" - -getdns_return_t getdns_str2dict(const char *str, getdns_dict **dict); -getdns_return_t getdns_str2list(const char *str, getdns_list **list); -getdns_return_t getdns_str2bindata(const char *str, getdns_bindata **bindata); -getdns_return_t getdns_str2int(const char *str, uint32_t *value); - -#endif