static getdns_return_t set_cookie(getdns_dict *exts, char *cookie) { uint8_t data[40]; size_t i; getdns_return_t r = GETDNS_RETURN_GENERIC_ERROR; getdns_bindata bindata; getdns_dict *opt_parameters = getdns_dict_create(); getdns_list *options = getdns_list_create(); getdns_dict *option = getdns_dict_create(); if (*cookie == '=') cookie++; for (i = 0; i < 40 && *cookie; i++) { if (*cookie >= '0' && *cookie <= '9') data[i] = (uint8_t)(*cookie - '0') << 4; else if (*cookie >= 'a' && *cookie <= 'f') data[i] = (uint8_t)(*cookie - 'a' + 10) << 4; else if (*cookie >= 'A' && *cookie <= 'F') data[i] = (uint8_t)(*cookie - 'A' + 10) << 4; else goto done; cookie++; if (*cookie >= '0' && *cookie <= '9') data[i] |= (uint8_t)(*cookie - '0'); else if (*cookie >= 'a' && *cookie <= 'f') data[i] |= (uint8_t)(*cookie - 'a' + 10); else if (*cookie >= 'A' && *cookie <= 'F') data[i] |= (uint8_t)(*cookie - 'A' + 10); else goto done; cookie++;; } bindata.data = data; bindata.size = i; if ((r = getdns_dict_set_int(option, "option_code", 65001))) goto done; if ((r = getdns_dict_set_bindata(option, "option_data", &bindata))) goto done; if ((r = getdns_list_set_dict(options, 0, option))) goto done; if ((r = getdns_dict_set_list(opt_parameters, "options", options))) goto done; r = getdns_dict_set_dict(exts, "add_opt_parameters", opt_parameters); done: getdns_dict_destroy(option); getdns_list_destroy(options); getdns_dict_destroy(opt_parameters); return r; }
getdns_dict * ipaddr_dict(getdns_context *context, char *ipstr) { getdns_dict *r = getdns_dict_create_with_context(context); char *s = strchr(ipstr, '%'), *scope_id_str = ""; char *p = strchr(ipstr, '@'), *portstr = ""; char *t = strchr(ipstr, '#'), *tls_portstr = ""; uint8_t buf[sizeof(struct in6_addr)]; getdns_bindata addr; addr.data = buf; if (!r) return NULL; 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 (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 (*scope_id_str) getdns_dict_util_set_string(r, "scope_id", scope_id_str); return r; }
void callback(getdns_context *context, getdns_callback_type_t callback_type, getdns_dict *response, void *userarg, getdns_transaction_t trans_id) { char *response_str; if (callback_type == GETDNS_CALLBACK_COMPLETE) { /* This is a callback with data */; if (!quiet && (response_str = json ? getdns_print_json_dict(response, json == 1) : getdns_pretty_print_dict(response))) { fprintf(stdout, "ASYNC response:\n%s\n", response_str); free(response_str); } fprintf(stderr, "The callback with ID %llu was successfull.\n", (unsigned long long)trans_id); } else if (callback_type == GETDNS_CALLBACK_CANCEL) fprintf(stderr, "The callback with ID %llu was cancelled. Exiting.\n", (unsigned long long)trans_id); else fprintf(stderr, "The callback got a callback_type of %d. Exiting.\n", callback_type); getdns_dict_destroy(response); response = NULL; }
void dns_req_free(getdns_dns_req * req) { if (!req) { return; } getdns_network_req *net_req = NULL; struct getdns_context *context = req->context; /* free extensions */ getdns_dict_destroy(req->extensions); /* free network requests */ net_req = req->first_req; while (net_req) { getdns_network_req *next = net_req->next; network_req_free(net_req); net_req = next; } if (req->local_timeout_id != 0) { getdns_context_clear_timeout(context, req->local_timeout_id); } getdns_context_clear_timeout(context, req->trans_id); /* free strduped name */ GETDNS_FREE(req->my_mf, req->name); GETDNS_FREE(req->my_mf, req); }
getdns_list* GNUtil::convertToList(Local<Array> array) { uint32_t len = array->Length(); getdns_list* result = getdns_list_create(); for (uint32_t i = 0; i < len; ++i) { size_t idx = getdns_list_get_length(result, &idx); Local<Value> val = array->Get(i); GetdnsType type = getGetdnsType(val); switch (type) { case IntType: getdns_list_set_int(result, idx, val->ToUint32()->Value()); break; case BoolType: if (val->IsTrue()) { getdns_list_set_int(result, idx, GETDNS_EXTENSION_TRUE); } else { getdns_list_set_int(result, idx, GETDNS_EXTENSION_FALSE); } break; case StringType: { struct getdns_bindata strdata; String::Utf8Value utf8Str(val->ToString()); int len = utf8Str.length(); strdata.data = (uint8_t*) *utf8Str; strdata.size = len; getdns_list_set_bindata(result, idx, &strdata); } break; case BinDataType: { struct getdns_bindata bdata; bdata.data = (uint8_t*) node::Buffer::Data(val); bdata.size = node::Buffer::Length(val); getdns_list_set_bindata(result, idx, &bdata); } break; case ListType: { Local<Array> subArray = Local<Array>::Cast(val); struct getdns_list* sublist = GNUtil::convertToList(subArray); getdns_list_set_list(result, idx, sublist); getdns_list_destroy(sublist); } break; case DictType: { Local<Object> subObj = val->ToObject(); struct getdns_dict* subdict = GNUtil::convertToDict(subObj); if (subdict) { getdns_list_set_dict(result, idx, subdict); getdns_dict_destroy(subdict); } } break; default: break; } } return result; }
getdns_return_t _getdns_fp2rr_list(struct mem_funcs *mf, FILE *in, getdns_list **rr_list, const char *origin, uint32_t default_ttl) { struct gldns_file_parse_state pst; getdns_list *rrs; getdns_return_t r = GETDNS_RETURN_GOOD; uint8_t *rr; size_t len, dname_len; getdns_dict *rr_dict; if (!in || !rr_list) return GETDNS_RETURN_INVALID_PARAMETER; if (!origin) { *pst.origin = 0; pst.origin_len = 1; } else if (gldns_str2wire_dname_buf(origin,pst.origin,&pst.origin_len)) return GETDNS_RETURN_GENERIC_ERROR; *pst.prev_rr = 0; pst.prev_rr_len = 1; pst.default_ttl = default_ttl; pst.lineno = 1; if (!(rrs = _getdns_list_create_with_mf(mf))) return GETDNS_RETURN_MEMORY_ERROR; if (!(rr = GETDNS_XMALLOC(*mf, uint8_t, GLDNS_RR_BUF_SIZE))) r = GETDNS_RETURN_MEMORY_ERROR; else while (r == GETDNS_RETURN_GOOD && !feof(in)) { len = GLDNS_RR_BUF_SIZE; dname_len = 0; if (gldns_fp2wire_rr_buf(in, rr, &len, &dname_len, &pst)) break; if (dname_len && dname_len < sizeof(pst.prev_rr)) { memcpy(pst.prev_rr, rr, dname_len); pst.prev_rr_len = dname_len; } if (len == 0) continue; if ((r = _getdns_wire2rr_dict(mf, rr, len, &rr_dict))) break; r = _getdns_list_append_dict(rrs, rr_dict); getdns_dict_destroy(rr_dict); } if (rr) GETDNS_FREE(*mf, rr); if (r) getdns_list_destroy(rrs); else *rr_list = rrs; return r; }
void destroy_callbackfn(struct getdns_context *context, getdns_callback_type_t callback_type, struct getdns_dict *response, void *userarg, getdns_transaction_t transaction_id) { int* flag = (int*)userarg; *flag = 1; getdns_dict_destroy(response); getdns_context_destroy(context); }
/** * test the copy and pretty print functions */ void tst_copy(void) { char *dictstr = NULL; struct getdns_dict *dict1 = NULL; struct getdns_dict *dict2 = NULL; tstmsg_case_begin("tst_copy"); tstmsg_case_msg("empty list cases"); getdns_dict_copy(NULL, NULL); dict1 = getdns_dict_create(); getdns_dict_copy(dict1, &dict2); getdns_dict_destroy(dict2); /* getdns_dict_copy(NULL, &dict1); */ tstmsg_case_msg("dict1 populate"); getdns_dict_set_int(dict1, "foo", 42); getdns_dict_set_int(dict1, "bar", 52); getdns_dict_set_int(dict1, "quz", 62); dictstr = getdns_pretty_print_dict(dict1); printf("%s\n", dictstr); free(dictstr); tstmsg_case_msg("getdns_dict_copy(dict1, &dict2)"); getdns_dict_copy(dict1, &dict2); dictstr = getdns_pretty_print_dict(dict2); printf("%s\n", dictstr); free(dictstr); getdns_dict_destroy(dict1); getdns_dict_destroy(dict2); tstmsg_case_end(); return; } /* tst_copy */
/* convert an HPKP-style pin description to an appropriate getdns data structure. An example string is: (with the quotes, without any leading or trailing whitespace): pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=" getdns_build_pin_from_string returns a dict created from ctx, or NULL if the string did not match. If ctx is NULL, the dict is created via getdns_dict_create(). It is the caller's responsibility to call getdns_dict_destroy when it is no longer needed. */ getdns_dict* getdns_pubkey_pin_create_from_string( getdns_context* context, const char* str) { BIO *bio = NULL; int i; uint8_t buf[SHA256_DIGEST_LENGTH]; char inbuf[B64_ENCODED_SHA256_LENGTH + 1]; getdns_bindata value = { .size = SHA256_DIGEST_LENGTH, .data = buf }; getdns_dict* out = NULL; /* we only do sha256 right now, make sure this is well-formed */ if (strncmp(PIN_PREFIX, str, PIN_PREFIX_LENGTH)) return NULL; for (i = PIN_PREFIX_LENGTH; i < PIN_PREFIX_LENGTH + B64_ENCODED_SHA256_LENGTH - 1; i++) if (!((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z') || (str[i] >= '0' && str[i] <= '9') || (str[i] == '+') || (str[i] == '/'))) return NULL; if (str[i++] != '=') return NULL; if (str[i++] != '"') return NULL; if (str[i++] != '\0') return NULL; /* openssl needs a trailing newline to base64 decode */ memcpy(inbuf, str + PIN_PREFIX_LENGTH, B64_ENCODED_SHA256_LENGTH); inbuf[B64_ENCODED_SHA256_LENGTH] = '\n'; bio = BIO_push(BIO_new(BIO_f_base64()), BIO_new_mem_buf(inbuf, sizeof(inbuf))); if (BIO_read(bio, buf, sizeof(buf)) != sizeof(buf)) goto fail; if (context) out = getdns_dict_create_with_context(context); else out = getdns_dict_create(); if (out == NULL) goto fail; if (getdns_dict_set_bindata(out, "digest", &sha256)) goto fail; if (getdns_dict_set_bindata(out, "value", &value)) goto fail; return out; fail: BIO_free_all(bio); getdns_dict_destroy(out); return NULL; }
getdns_return_t _getdns_get_pubkey_pinset_list(getdns_context *ctx, const sha256_pin_t *pinset_in, getdns_list **pinset_list) { getdns_list *out = getdns_list_create_with_context(ctx); getdns_return_t r; uint8_t buf[SHA256_DIGEST_LENGTH]; getdns_bindata value = { .size = SHA256_DIGEST_LENGTH, .data = buf }; getdns_dict *pin = NULL; size_t idx = 0; if (out == NULL) return GETDNS_RETURN_MEMORY_ERROR; while (pinset_in) { pin = getdns_dict_create_with_context(ctx); if (pin == NULL) { r = GETDNS_RETURN_MEMORY_ERROR; goto fail; } if (r = getdns_dict_set_bindata(pin, "digest", &sha256), r) goto fail; memcpy(buf, pinset_in->pin, sizeof(buf)); if (r = getdns_dict_set_bindata(pin, "value", &value), r) goto fail; if (r = getdns_list_set_dict(out, idx++, pin), r) goto fail; getdns_dict_destroy(pin); pin = NULL; pinset_in = pinset_in->next; } *pinset_list = out; return GETDNS_RETURN_GOOD; fail: getdns_dict_destroy(pin); getdns_list_destroy(out); return r; }
int main() { /* Create the DNS context for this call */ struct getdns_context *this_context = NULL; getdns_return_t context_create_return = getdns_context_create(&this_context, 1); if (context_create_return != GETDNS_RETURN_GOOD) { fprintf(stderr, "Trying to create the context failed: %d", context_create_return); return (GETDNS_RETURN_GENERIC_ERROR); } getdns_context_set_resolution_type(this_context, GETDNS_RESOLUTION_STUB); struct getdns_dict *response = NULL; getdns_return_t ret = getdns_address_sync(this_context, "www.google.com", NULL, &response); if (ret != GETDNS_RETURN_GOOD || response == NULL) { fprintf(stderr, "Address sync returned error.\n"); exit(EXIT_FAILURE); } print_response(response); getdns_dict_destroy(response); ret = getdns_service_sync(this_context, "www.google.com", NULL, &response); if (ret != GETDNS_RETURN_GOOD || response == NULL) { fprintf(stderr, "Service sync returned error.\n"); exit(EXIT_FAILURE); } print_response(response); getdns_dict_destroy(response); /* Clean up */ getdns_context_destroy(this_context); /* Assuming we get here, leave gracefully */ exit(EXIT_SUCCESS); } /* main */
/** * test the create, destroy and allocation functions */ void tst_create(void) { struct getdns_dict *dict = NULL; /* make sure we can do a simple create/destroy first */ tstmsg_case_begin("tst_create"); tstmsg_case_msg("getdns_dict_create"); dict = getdns_dict_create(); if (dict != NULL) { tstmsg_case_msg("getdns_dict_destroy(dict)"); getdns_dict_destroy(dict); } tstmsg_case_msg("getdns_dict_destroy(NULL)"); getdns_dict_destroy(NULL); tstmsg_case_end(); return; } /* tst_create */
getdns_return_t _getdns_list_remove_name(getdns_list *list, const char *name) { const char *next, *key = name; char *endptr; size_t index; getdns_item *i; if (*key == '/') { if (!(next = strchr(++key, '/'))) next = strchr(key, '\0'); } else next = strchr(key, '\0'); if (key[0] == '-' && next == key + 1) return GETDNS_RETURN_NO_SUCH_LIST_ITEM; index = strtoul(key, &endptr, 10); if (!isdigit((int)*key) || endptr != next) /* Not a list index, so it was assumed */ return GETDNS_RETURN_WRONG_TYPE_REQUESTED; if (index >= list->numinuse) return GETDNS_RETURN_NO_SUCH_LIST_ITEM; i = &list->items[index]; if (!*next) { switch (i->dtype) { case t_dict : getdns_dict_destroy(i->data.dict); break; case t_list : getdns_list_destroy(i->data.list); break; case t_bindata: _getdns_bindata_destroy( &list->mf, i->data.bindata); default : break; } if (index < list->numinuse - 1) (void) memmove( i, &i[1], (list->numinuse - index) * sizeof(getdns_item)); list->numinuse -= 1; return GETDNS_RETURN_GOOD; } else switch (i->dtype) { case t_dict: return getdns_dict_remove_name(i->data.dict, next); case t_list: return _getdns_list_remove_name(i->data.list, next); default : /* Trying to dereference a non list or dict */ return GETDNS_RETURN_NO_SUCH_LIST_ITEM; } }
int main() { getdns_return_t r = GETDNS_RETURN_MEMORY_ERROR; getdns_dict *dict = NULL; unsigned char bladiebla_str[] = "bla die bla"; getdns_bindata bladiebla = { sizeof(bladiebla_str), bladiebla_str }; if (!(dict = getdns_dict_create())) fprintf(stderr, "Could not create dict"); else if ((r = getdns_dict_set_int(dict, "/bla/bloe/blie", 53280)) || (r = getdns_dict_set_int(dict, "/bla/hola", 53281)) || (r = getdns_dict_set_int(dict, "/bla/cola/-", 1)) || (r = getdns_dict_set_int(dict, "/bla/cola/-", 2)) || (r = getdns_dict_set_int(dict, "/bla/cola/-/drie", 3)) || (r = getdns_dict_set_int(dict, "/bla/cola/-", 4)) || (r = getdns_dict_set_int(dict, "/bla/cola/1", 5)) || (r = getdns_dict_set_int(dict, "/bla/cola/2/zes", 6)) || (r = getdns_dict_set_bindata(dict, "/die/bla", &bladiebla)) ) fprintf(stderr, "Error setting dict data"); else { char *dict_str = getdns_pretty_print_dict(dict); if (!dict_str) { fprintf(stderr, "Could not convert dict to string"); r = GETDNS_RETURN_MEMORY_ERROR; } else { printf("%s\n", dict_str); free(dict_str); } } if (r) fprintf(stderr, ": %s\n", getdns_get_errorstr_by_id(r)); if (dict) getdns_dict_destroy(dict); if (r) exit(EXIT_FAILURE); exit(EXIT_SUCCESS); }
/* convert an HPKP-style pin description to an appropriate getdns data structure. An example string is: (with the quotes, without any leading or trailing whitespace): pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=" getdns_build_pin_from_string returns a dict created from ctx, or NULL if the string did not match. If ctx is NULL, the dict is created via getdns_dict_create(). It is the caller's responsibility to call getdns_dict_destroy when it is no longer needed. */ getdns_dict *getdns_pubkey_pin_create_from_string( const getdns_context *context, const char *str) { size_t i; uint8_t buf[SHA256_DIGEST_LENGTH]; getdns_bindata value = { .size = SHA256_DIGEST_LENGTH, .data = buf }; getdns_dict *out = NULL; /* we only do sha256 right now, make sure this is well-formed */ if (!str || strncmp(PIN_PREFIX, str, PIN_PREFIX_LENGTH)) return NULL; for (i = PIN_PREFIX_LENGTH; i < PIN_PREFIX_LENGTH + B64_ENCODED_SHA256_LENGTH - 1; i++) if (!((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z') || (str[i] >= '0' && str[i] <= '9') || (str[i] == '+') || (str[i] == '/'))) return NULL; if (str[i++] != '=') return NULL; if (str[i++] != '"') return NULL; if (str[i++] != '\0') return NULL; if (_getdns_decode_base64(str + PIN_PREFIX_LENGTH, buf, sizeof(buf)) != GETDNS_RETURN_GOOD) goto fail; if (context) out = getdns_dict_create_with_context(context); else out = getdns_dict_create(); if (out == NULL) goto fail; if (getdns_dict_set_bindata(out, "digest", &sha256)) goto fail; if (getdns_dict_set_bindata(out, "value", &value)) goto fail; return out; fail: getdns_dict_destroy(out); return NULL; }
static void _getdns_list_destroy_item(struct getdns_list *list, size_t index) { switch (list->items[index].dtype) { case t_dict: getdns_dict_destroy(list->items[index].data.dict); break; case t_list: getdns_list_destroy(list->items[index].data.list); break; case t_bindata: _getdns_bindata_destroy(&list->mf, list->items[index].data.bindata); break; default: break; } }
/*---------------------------------------- getdns_list_set_dict */ getdns_return_t getdns_list_set_dict( getdns_list *list, size_t index, const getdns_dict *child_dict) { getdns_dict *newdict; getdns_return_t r; if (!list || !child_dict) return GETDNS_RETURN_INVALID_PARAMETER; if ((r = _getdns_dict_copy(child_dict, &newdict))) return r; if ((r = _getdns_list_request_index(list, index))) { getdns_dict_destroy(newdict); return r; } list->items[index].dtype = t_dict; list->items[index].data.dict = newdict; return GETDNS_RETURN_GOOD; } /* getdns_list_set_dict */
/* Set up the callback function, which will also do the processing of the results */ void this_callbackfn(struct getdns_context *this_context, getdns_callback_type_t this_callback_type, struct getdns_dict *this_response, void *this_userarg, getdns_transaction_t this_transaction_id) { (void)this_context; (void)this_userarg; if (this_callback_type == GETDNS_CALLBACK_COMPLETE) { /* This is a callback with data */ char *res = getdns_pretty_print_dict(this_response); fprintf(stdout, "%s\n", res); free(res); } else if (this_callback_type == GETDNS_CALLBACK_CANCEL) fprintf(stderr, "The callback with ID %llu was cancelled. Exiting.\n", (unsigned long long)this_transaction_id); else fprintf(stderr, "The callback got a callback_type of %d. Exiting.\n", this_callback_type); getdns_dict_destroy(this_response); }
/* Set up the callback function, which will also do the processing of the results */ void callback(getdns_context *context, getdns_callback_type_t callback_type, getdns_dict *response, void *userarg, getdns_transaction_t transaction_id) { getdns_return_t r; /* Holder for all function returns */ getdns_list *replies_tree; size_t n_replies, i; (void) context; (void) userarg; /* unused parameters */ switch(callback_type) { case GETDNS_CALLBACK_CANCEL: printf("Transaction with ID %"PRIu64" was cancelled.\n", transaction_id); return; case GETDNS_CALLBACK_TIMEOUT: printf("Transaction with ID %"PRIu64" timed out.\n", transaction_id); return; case GETDNS_CALLBACK_ERROR: printf("An error occurred for transaction ID %"PRIu64".\n", transaction_id); return; default: break; } assert( callback_type == GETDNS_CALLBACK_COMPLETE ); if ((r = getdns_dict_get_list(response, "replies_tree", &replies_tree))) fprintf(stderr, "Could not get \"replies_tree\" from response"); else if ((r = getdns_list_get_length(replies_tree, &n_replies))) fprintf(stderr, "Could not get replies_tree\'s length"); else for (i = 0; i < n_replies && r == GETDNS_RETURN_GOOD; i++) { getdns_dict *reply; getdns_list *answer; size_t n_answers, j; if ((r = getdns_list_get_dict(replies_tree, i, &reply))) fprintf(stderr, "Could not get address %zu from just_address_answers", i); else if ((r = getdns_dict_get_list(reply, "answer", &answer))) fprintf(stderr, "Could not get \"address_data\" from address"); else if ((r = getdns_list_get_length(answer, &n_answers))) fprintf(stderr, "Could not get answer section\'s length"); else for (j = 0; j < n_answers && r == GETDNS_RETURN_GOOD; j++) { getdns_dict *rr; getdns_bindata *address = NULL; if ((r = getdns_list_get_dict(answer, j, &rr))) fprintf(stderr, "Could net get rr %zu from answer section", j); else if (getdns_dict_get_bindata(rr, "/rdata/ipv4_address", &address) == GETDNS_RETURN_GOOD) printf("The IPv4 address is "); else if (getdns_dict_get_bindata(rr, "/rdata/ipv6_address", &address) == GETDNS_RETURN_GOOD) printf("The IPv6 address is "); if (address) { char *address_str; if (!(address_str = getdns_display_ip_address(address))) { fprintf(stderr, "Could not convert second address to string"); r = GETDNS_RETURN_MEMORY_ERROR; break; } printf("%s\n", address_str); free(address_str); } } } if (r) { assert( r != GETDNS_RETURN_GOOD ); fprintf(stderr, ": %d\n", r); } getdns_dict_destroy(response); }
void getdns_free_sync_request_memory(struct getdns_dict *response) { getdns_dict_destroy(response); }
int main(int argc, char **argv) { getdns_dict *response = NULL; char *response_str; getdns_return_t r; getdns_dict *address = NULL; FILE *fp = NULL; name = the_root; if ((r = getdns_context_create(&context, 1))) { fprintf(stderr, "Create context failed: %d\n", r); return r; } extensions = getdns_dict_create(); if (! extensions) { fprintf(stderr, "Could not create extensions dict\n"); r = GETDNS_RETURN_MEMORY_ERROR; goto done_destroy_context; } if ((r = parse_args(argc, argv))) goto done_destroy_context; if (query_file) { fp = fopen(query_file, "rt"); if (fp == NULL) { fprintf(stderr, "Could not open query file: %s\n", query_file); goto done_destroy_context; } } /* Make the call */ do { char line[1024], *token, *linev[256]; int linec; if (interactive) { if (!query_file) { fprintf(stdout, "> "); if (!fgets(line, 1024, stdin) || !*line) break; } else { if (!fgets(line, 1024, fp) || !*line) break; fprintf(stdout,"Found query: %s", line); } linev[0] = argv[0]; linec = 1; if ( ! (token = strtok(line, " \t\f\n\r"))) continue; do linev[linec++] = token; while (linec < 256 && (token = strtok(NULL, " \t\f\n\r"))); if ((r = parse_args(linec, linev))) { if (r == CONTINUE) continue; else goto done_destroy_context; } } if (calltype == HOSTNAME && !(address = ipaddr_dict(context, name))) { fprintf(stderr, "Could not convert \"%s\" " "to an IP address", name); continue; } if (async) { switch (calltype) { case GENERAL: r = getdns_general(context, name, request_type, extensions, &response, NULL, callback); break; case ADDRESS: r = getdns_address(context, name, extensions, &response, NULL, callback); break; case HOSTNAME: r = getdns_hostname(context, address, extensions, &response, NULL, callback); break; case SERVICE: r = getdns_service(context, name, extensions, &response, NULL, callback); break; default: r = GETDNS_RETURN_GENERIC_ERROR; break; } if (r) goto done_destroy_extensions; if (!batch_mode) getdns_context_run(context); } else { switch (calltype) { case GENERAL: r = getdns_general_sync(context, name, request_type, extensions, &response); break; case ADDRESS: r = getdns_address_sync(context, name, extensions, &response); break; case HOSTNAME: r = getdns_hostname_sync(context, address, extensions, &response); break; case SERVICE: r = getdns_service_sync(context, name, extensions, &response); break; default: r = GETDNS_RETURN_GENERIC_ERROR; break; } if (r) goto done_destroy_extensions; if (!quiet) { if ((response_str = json ? getdns_print_json_dict(response, json == 1) : getdns_pretty_print_dict(response))) { fprintf( stdout, "SYNC response:\n%s\n" , response_str); free(response_str); } else { r = GETDNS_RETURN_MEMORY_ERROR; fprintf( stderr , "Could not print response\n"); } } else if (r == GETDNS_RETURN_GOOD) fprintf(stdout, "Response code was: GOOD\n"); else if (interactive) fprintf(stderr, "An error occurred: %d\n", r); } } while (interactive); if (batch_mode) getdns_context_run(context); /* Clean up */ done_destroy_extensions: getdns_dict_destroy(extensions); done_destroy_context: if (response) getdns_dict_destroy(response); getdns_context_destroy(context); if (fp) fclose(fp); if (r == CONTINUE) return 0; if (r) fprintf(stderr, "An error occurred: %d\n", r); return r; }
/** * test the list get and set routines */ void tst_listsetget(void) { char msg[TSTMSGBUF]; char key[20]; size_t index; uint32_t int1; uint32_t int2; getdns_return_t retval; struct getdns_list *newlist; struct getdns_list *anslist; struct getdns_dict *dict = NULL; tstmsg_case_begin("tst_listsetget"); dict = getdns_dict_create(); /* test get function against empty list and with bogus params */ strcpy(key, "foo"); tstmsg_case_msg("getdns_dict_get_list() empty dict"); retval = getdns_dict_get_list(NULL, key, &anslist); snprintf(msg, sizeof(msg), "test 13: getdns_dict_get_list(NULL, key, &anslist),retval = %d", retval); tstmsg_case_msg(msg); retval = getdns_dict_get_list(dict, key, NULL); snprintf(msg, sizeof(msg), "test 14: getdns_dict_get_list(dict, key, NULL),retval = %d", retval); tstmsg_case_msg(msg); tstmsg_case_msg("getdns_dict_get_list(dict, NULL, &anslist)"); retval = getdns_dict_get_list(dict, NULL, &anslist); snprintf(msg, sizeof(msg), "test 15: getdns_dict_get_list,retval = %d", retval); tstmsg_case_msg(msg); tstmsg_case_msg("getdns_dict_get_list(dict, key, &anslist)"); retval = getdns_dict_get_list(dict, key, &anslist); snprintf(msg, sizeof(msg), "test 16: getdns_list_get_list,retval = %d", retval); tstmsg_case_msg(msg); getdns_dict_destroy(dict); /* TODO: test getdns_dict_set functions with bogus params */ /* test set and get legitimate use case */ dict = getdns_dict_create(); strcpy(key, "foo"); newlist = getdns_list_create(); getdns_list_add_item(newlist, &index); getdns_list_set_int(newlist, index, 42); getdns_list_add_item(newlist, &index); getdns_list_set_int(newlist, index, 52); tstmsg_case_msg("getdns_dict_set_list(dict, key, newlist)"); retval = getdns_dict_set_list(dict, key, newlist); snprintf(msg, sizeof(msg), "test 17: getdns_dict_set_list,retval=%d,key=%s", retval, key); tstmsg_case_msg(msg); getdns_list_destroy(newlist); tstmsg_case_msg("getdns_dict_get_list(dict, key, &anslist)"); retval = getdns_dict_get_list(dict, key, &anslist); getdns_list_get_int(anslist, 0, &int1); getdns_list_get_int(anslist, 1, &int2); snprintf(msg, sizeof(msg), "test 18: getdns_dict_get_list,retval=%d,key=%s,int1=%d,int2=%d", retval, key, int1, int2); tstmsg_case_msg(msg); getdns_dict_destroy(dict); tstmsg_case_end(); return; } /* tst_listsetget */
/** * exercise the getdns_dict_get_names function */ void tst_getnames(void) { size_t index; size_t llen; uint32_t ansint; int i; getdns_return_t result; getdns_data_type dtype; struct getdns_dict *dict = NULL; struct getdns_list *list = NULL; tstmsg_case_begin("tst_getnames"); dict = getdns_dict_create(); /* degenerative use cases */ tstmsg_case_msg("getdns_dict_get_names(NULL, &list)"); getdns_dict_get_names(NULL, &list); getdns_list_destroy(list); tstmsg_case_msg("getdns_dict_get_names(dict, NULL)"); getdns_dict_get_names(dict, NULL); tstmsg_case_msg ("getdns_dict_get_names(dict, &list), empty dictionary"); getdns_dict_get_names(dict, &list); getdns_list_destroy(list); /* legit use case, add items out of order to exercise tree */ /* TODO: add elements of type dict, bindata, list to the dict */ i = 0; getdns_dict_set_int(dict, "foo", i++); getdns_dict_set_int(dict, "bar", i++); getdns_dict_set_int(dict, "quz", i++); getdns_dict_set_int(dict, "alpha", i++); getdns_dict_get_names(dict, &list); result = getdns_list_get_length(list, &llen); if (result != GETDNS_RETURN_GOOD) { tstmsg_case_msg ("getdns_list_get_length failed, exiting"); return; } if (llen != i) { tstmsg_case_msg ("getdns_list_get_length returned unreasonable length, exiting"); return; } for (index = 0; index < llen; index++) { getdns_list_get_data_type(list, index, &dtype); printf(" list item %d: ", (int) index); switch (dtype) { case t_bindata: printf("NOTIMPLEMENTED"); break; case t_dict: printf("NOTIMPLEMENTED"); break; case t_int: getdns_list_get_int(list, index, &ansint); printf("t_int, value=%d\n", ansint); break; case t_list: printf("NOTIMPLEMENTED"); break; default: printf("data type invalid"); break; } } getdns_dict_destroy(dict); getdns_list_destroy(list); tstmsg_case_end(); } /* tst_getnames */
/** * test the int get and set routines */ void tst_intsetget(void) { char msg[TSTMSGBUF]; char key[20]; uint32_t ans_int; uint32_t newint; getdns_return_t retval; struct getdns_dict *dict = NULL; getdns_data_type dtype; tstmsg_case_begin("tst_intsetget"); dict = getdns_dict_create(); /* test int get function against empty list and with bogus params */ strcpy(key, "foo"); tstmsg_case_msg("getdns_dict_get_int() empty dict"); retval = getdns_dict_get_int(NULL, key, &ans_int); snprintf(msg, sizeof(msg), "test 19: getdns_dict_get_int(NULL, key, &ans_int),retval = %d", retval); tstmsg_case_msg(msg); retval = getdns_dict_get_int(dict, key, NULL); snprintf(msg, sizeof(msg), "test 20: getdns_dict_get_int(dict, key, NULL),retval = %d", retval); tstmsg_case_msg(msg); tstmsg_case_msg("getdns_dict_get_int(dict, NULL, &ans_int)"); retval = getdns_dict_get_int(dict, NULL, &ans_int); snprintf(msg, sizeof(msg), "test 21: getdns_dict_get_int,retval = %d", retval); tstmsg_case_msg(msg); tstmsg_case_msg("getdns_dict_get_int(dict, key, &ans_int)"); retval = getdns_dict_get_int(dict, key, &ans_int); snprintf(msg, sizeof(msg), "test 22: getdns_list_get_int,retval = %d", retval); tstmsg_case_msg(msg); getdns_dict_destroy(dict); /* TODO: test getdns_dict_set functions with bogus params */ /* test set and get legitimate use case */ dict = getdns_dict_create(); strcpy(key, "foo"); newint = 42; tstmsg_case_msg("getdns_dict_set_int(dict, key, newint)"); retval = getdns_dict_set_int(dict, key, newint); snprintf(msg, sizeof(msg), "test 23: getdns_dict_set_int,retval=%d,key=%s,int=%d", retval, key, newint); tstmsg_case_msg(msg); tstmsg_case_msg("getdns_dict_get_int(dict, key, &ans_int)"); retval = getdns_dict_get_int(dict, key, &ans_int); snprintf(msg, sizeof(msg), "test 24: getdns_dict_get_int,retval=%d,key=%s,int=%d", retval, key, ans_int); tstmsg_case_msg(msg); strcpy(key, "bar"); newint = 52; tstmsg_case_msg("getdns_dict_set_int(dict, key, newint)"); retval = getdns_dict_set_int(dict, key, newint); snprintf(msg, sizeof(msg), "test 25: getdns_dict_set_int,retval=%d,key=%s,int=%d", retval, key, newint); tstmsg_case_msg(msg); tstmsg_case_msg("getdns_dict_get_int(dict, key, &ans_int)"); retval = getdns_dict_get_int(dict, key, &ans_int); snprintf(msg, sizeof(msg), "test 26: getdns_dict_get_int,retval=%d,key=%s,int=%d", retval, key, ans_int); tstmsg_case_msg(msg); tstmsg_case_msg("getdns_dict_get_data_type(dict, key, &dtype)"); retval = getdns_dict_get_data_type(dict, key, &dtype); snprintf(msg, sizeof(msg), "test 27: getdns_dict_get_data_type,retval=%d,key=%s,dtype=%d", retval, key, dtype); tstmsg_case_msg(msg); getdns_dict_destroy(dict); tstmsg_case_end(); return; } /* tst_intsetget */
getdns_return_t parse_args(int argc, char **argv) { getdns_return_t r = GETDNS_RETURN_GOOD; size_t i; char *arg, *c, *endptr; int t, print_api_info = 0, print_trust_anchors = 0; getdns_list *upstream_list = NULL; getdns_list *tas = NULL; size_t upstream_count = 0; for (i = 1; i < argc; i++) { arg = argv[i]; if ((t = get_rrtype(arg)) >= 0) { request_type = t; continue; } else if (arg[0] == '+') { if (arg[1] == 's' && arg[2] == 'i' && arg[3] == 't' && (arg[4] == '=' || arg[4] == '\0')) { if ((r = set_cookie(extensions, arg+4))) { fprintf(stderr, "Could not set cookie:" " %d", r); break; } } else if (arg[1] == '0') { /* Unset all existing extensions*/ getdns_dict_destroy(extensions); extensions = getdns_dict_create(); break; } else if ((r = getdns_dict_set_int(extensions, arg+1, GETDNS_EXTENSION_TRUE))) { fprintf(stderr, "Could not set extension " "\"%s\": %d\n", argv[i], r); break; } continue; } else if (arg[0] == '@') { getdns_dict *upstream = ipaddr_dict(context, arg + 1); if (upstream) { if (!upstream_list && !(upstream_list = getdns_list_create_with_context(context))){ fprintf(stderr, "Could not create upstream list\n"); return GETDNS_RETURN_MEMORY_ERROR; } getdns_list_set_dict(upstream_list, upstream_count++, upstream); } continue; } else if (arg[0] != '-') { name = arg; continue; } for (c = arg+1; *c; c++) { switch (*c) { case 'a': async = 1; break; case 'A': calltype = ADDRESS; break; case 'b': if (c[1] != 0 || ++i >= argc || !*argv[i]) { fprintf(stderr, "max_udp_payload_size " "expected after -b\n"); return GETDNS_RETURN_GENERIC_ERROR; } edns0_size = strtol(argv[i], &endptr, 10); if (*endptr || edns0_size < 0) { fprintf(stderr, "positive " "numeric max_udp_payload_size " "expected after -b\n"); return GETDNS_RETURN_GENERIC_ERROR; } getdns_context_set_edns_maximum_udp_payload_size( context, (uint16_t) edns0_size); goto next; case 'D': (void) getdns_context_set_edns_do_bit(context, 1); break; case 'd': (void) getdns_context_set_edns_do_bit(context, 0); break; case 'F': if (c[1] != 0 || ++i >= argc || !*argv[i]) { fprintf(stderr, "file name expected " "after -F\n"); return GETDNS_RETURN_GENERIC_ERROR; } query_file = argv[i]; interactive = 1; break; case 'G': calltype = GENERAL; break; case 'H': calltype = HOSTNAME; break; case 'h': print_usage(stdout, argv[0]); return CONTINUE; case 'i': print_api_info = 1; break; case 'I': interactive = 1; break; case 'j': json = 2; break; case 'J': json = 1; break; case 'k': print_trust_anchors = 1; break; case 'p': json = 0; case 'q': quiet = 1; break; case 'r': getdns_context_set_resolution_type( context, GETDNS_RESOLUTION_RECURSING); break; case 's': getdns_context_set_resolution_type( context, GETDNS_RESOLUTION_STUB); break; case 'S': calltype = SERVICE; break; case 't': if (c[1] != 0 || ++i >= argc || !*argv[i]) { fprintf(stderr, "timeout expected " "after -t\n"); return GETDNS_RETURN_GENERIC_ERROR; } timeout = strtol(argv[i], &endptr, 10); if (*endptr || timeout < 0) { fprintf(stderr, "positive " "numeric timeout expected " "after -t\n"); return GETDNS_RETURN_GENERIC_ERROR; } getdns_context_set_timeout( context, timeout); goto next; case 'e': if (c[1] != 0 || ++i >= argc || !*argv[i]) { fprintf(stderr, "idle timeout expected " "after -t\n"); return GETDNS_RETURN_GENERIC_ERROR; } timeout = strtol(argv[i], &endptr, 10); if (*endptr || timeout < 0) { fprintf(stderr, "positive " "numeric idle timeout expected " "after -t\n"); return GETDNS_RETURN_GENERIC_ERROR; } getdns_context_set_idle_timeout( context, timeout); goto next; case 'T': getdns_context_set_dns_transport(context, GETDNS_TRANSPORT_TCP_ONLY); break; case 'O': getdns_context_set_dns_transport(context, GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN); break; case 'L': getdns_context_set_dns_transport(context, GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN); break; case 'E': getdns_context_set_dns_transport(context, GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN); break; case 'R': getdns_context_set_dns_transport(context, GETDNS_TRANSPORT_STARTTLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN); break; case 'u': getdns_context_set_dns_transport(context, GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP); break; case 'U': getdns_context_set_dns_transport(context, GETDNS_TRANSPORT_UDP_ONLY); break; case 'l': if (c[1] != 0 || ++i >= argc || !*argv[i]) { fprintf(stderr, "transport list expected " "after -l\n"); return GETDNS_RETURN_GENERIC_ERROR; } size_t transport_count = 0; getdns_transport_list_t transports[GETDNS_TRANSPORTS_MAX]; if ((r = fill_transport_list(context, argv[i], transports, &transport_count)) || (r = getdns_context_set_dns_transport_list(context, transport_count, transports))){ fprintf(stderr, "Could not set transports\n"); return r; } break; case 'B': batch_mode = 1; break; default: fprintf(stderr, "Unknown option " "\"%c\"\n", *c); for (i = 0; i < argc; i++) fprintf(stderr, "%d: \"%s\"\n", (int)i, argv[i]); return GETDNS_RETURN_GENERIC_ERROR; } } next: ; } if (r) return r; if (upstream_count && (r = getdns_context_set_upstream_recursive_servers( context, upstream_list))) { fprintf(stderr, "Error setting upstream recursive servers\n"); } if (print_api_info) { fprintf(stdout, "%s\n", getdns_pretty_print_dict( getdns_context_get_api_information(context))); return CONTINUE; } if (print_trust_anchors) { if ((tas = getdns_root_trust_anchor(NULL))) { fprintf(stdout, "%s\n", getdns_pretty_print_list(tas)); return CONTINUE; } else return CONTINUE_ERROR; } return r; }
/*---------------------------------------- getkeyviadane fetch the smime/a key identified by the encoded keyid and host name populate *certtxt with the key record, caller must free certtxt */ void getkeyviadane(char *dname, int rrtype, char **certtxt) { int i; uint32_t status; size_t nans; size_t numrrs; int rrnum; char getdnserr[MAX_ERROR_STRING+1]; uint32_t recrrtype; getdns_return_t getdnsret; getdns_context *getdnsctx = NULL; getdns_dict *getdnsrsp = NULL; getdns_dict *dnsrec = NULL; getdns_dict *rr = NULL; getdns_dict *rrdata = NULL; getdns_list *dnsreplytree = NULL; getdns_list *dnsans = NULL; getdns_bindata *rawrdata = NULL; *certtxt = NULL; // create the context for DNS resolution using local OS system settings getdnsret = getdns_context_create(&getdnsctx, 1); if(getdnsret != GETDNS_RETURN_GOOD) { getdns_strerror(getdnsret, getdnserr, MAX_ERROR_STRING); fprintf(stderr, "error creating getdns context, %d, %s\n" , getdnsret, getdnserr); return; } // getdns_context_set_resolution_type(getdnsctx, GETDNS_RESOLUTION_STUB); // perform the DNS resolution request getdnsret = getdns_general_sync(getdnsctx, dname, rrtype, NULL, &getdnsrsp); if(getdnsret != GETDNS_RETURN_GOOD) { getdns_strerror(getdnsret, getdnserr, MAX_ERROR_STRING); fprintf(stderr, "DNS request failed, %d, %s\n", getdnsret, getdnserr); getdns_dict_destroy(getdnsrsp); getdns_context_destroy(getdnsctx); return; } // sanity check the result of the query getdnsret = getdns_dict_get_int(getdnsrsp, (char *) "status", &status); if(getdnsret != GETDNS_RETURN_GOOD || status != GETDNS_RESPSTATUS_GOOD) { fprintf(stderr, "DNS request did not return results\n"); getdns_dict_destroy(getdnsrsp); getdns_context_destroy(getdnsctx); return; } getdnsret = getdns_dict_get_list(getdnsrsp, (char *)"replies_tree", &dnsreplytree); if(getdnsret != GETDNS_RETURN_GOOD) { fprintf(stderr, "DNS reply tree empty\n"); getdns_dict_destroy(getdnsrsp); getdns_context_destroy(getdnsctx); return; } nans = 0; getdns_list_get_length(dnsreplytree, &nans); for(i=0; i<nans && *certtxt == NULL; i++) { // extract a record from the reply tree, extract answer from that record getdns_list_get_dict(dnsreplytree, i, &dnsrec); getdnsret = getdns_dict_get_list(dnsrec, (char *)"answer", &dnsans); if(getdnsret != GETDNS_RETURN_GOOD) { fprintf(stderr, "answer missing from DNS reply tree, exiting\n"); exit(1); } // walk the RRs in the DNS answer getdns_list_get_length(dnsans, &numrrs); for(rrnum=0; rrnum < numrrs && *certtxt == NULL; rrnum++) { getdns_list_get_dict(dnsans, rrnum, &rr); recrrtype = 0; getdns_dict_get_int(rr, (char *)"type", &recrrtype); if(recrrtype == rrtype) { getdns_dict_get_dict(rr, (char *)"rdata", &rrdata); getdnsret = getdns_dict_get_bindata(rrdata, (char *)"rdata_raw" , &rawrdata); if(getdnsret != GETDNS_RETURN_GOOD) { fprintf(stderr, "error, rdata missing address\n"); } else { *certtxt = (char *) malloc(rawrdata->size + 1); memcpy(*certtxt, rawrdata->data, rawrdata->size); *certtxt[rawrdata->size] = '\0'; } } } // for rrnum } // for i in nans getdns_dict_destroy(getdnsrsp); getdns_context_destroy(getdnsctx); return; } // getkeyviadane
/** * test the bindata get and set routines */ void tst_bindatasetget(void) { char msg[TSTMSGBUF]; char key[20]; getdns_return_t retval; struct getdns_dict *dict = NULL; struct getdns_bindata *ans_bdata; struct getdns_bindata *bindata; tstmsg_case_begin("tst_bindatasetget"); dict = getdns_dict_create(); /* test int get function against empty dict and with bogus params */ strcpy(key, "foo"); tstmsg_case_msg("getdns_dict_get_bindata() empty dict"); retval = getdns_dict_get_bindata(NULL, key, &ans_bdata); snprintf(msg, sizeof(msg), "test 1: getdns_dict_get_bindata(NULL, key, &ans_bdata),retval = %d", retval); tstmsg_case_msg(msg); retval = getdns_dict_get_bindata(dict, key, NULL); snprintf(msg, sizeof(msg), "test 2: getdns_dict_get_bindata(dict, key, NULL),retval = %d", retval); tstmsg_case_msg(msg); tstmsg_case_msg("getdns_dict_get_bindata(dict, NULL, &ans_bindata)"); retval = getdns_dict_get_bindata(dict, NULL, &ans_bdata); snprintf(msg, sizeof(msg), "test 3: getdns_dict_get_bindata,retval = %d", retval); tstmsg_case_msg(msg); tstmsg_case_msg("getdns_dict_get_bindata(dict, key, &ans_bdata)"); retval = getdns_dict_get_bindata(dict, key, &ans_bdata); snprintf(msg, sizeof(msg), "test 4: getdns_list_get_bindata,retval = %d", retval); tstmsg_case_msg(msg); getdns_dict_destroy(dict); /* TODO: test getdns_dict_set functions with bogus params */ /* test set and get legitimate use case */ dict = getdns_dict_create(); strcpy(key, "foo"); bindata = (struct getdns_bindata *) malloc(sizeof(struct getdns_bindata)); bindata->size = strlen("foobar") + 1; bindata->data = (void *) strdup("foobar"); tstmsg_case_msg("getdns_dict_set_bindata(dict, key, bindata)"); retval = getdns_dict_set_bindata(dict, key, bindata); snprintf(msg, sizeof(msg), "test 5: getdns_dict_set_bindata,retval=%d,key=%s", retval, key); tstmsg_case_msg(msg); tstmsg_case_msg("getdns_dict_get_bindata(dict, key, &ans_bdata)"); retval = getdns_dict_get_bindata(dict, key, &ans_bdata); snprintf(msg, sizeof(msg), "test 6: getdns_dict_get_bindata,retval=%d,key=%s,data=%s", retval, key, ans_bdata->data); tstmsg_case_msg(msg); getdns_dict_destroy(dict); free(bindata->data); free(bindata); tstmsg_case_end(); return; } /* tst_bindatasetget */
getdns_return_t _getdns_list_find_and_add( getdns_list *list, const char *key, getdns_item **item) { const char *next; char *endptr; size_t index; getdns_item *newlist, *i; if (*key == '/') { if (!(next = strchr(++key, '/'))) next = strchr(key, '\0'); } else next = strchr(key, '\0'); if (key[0] == '-' && next == key + 1) index = list->numinuse; else { index = strtoul(key, &endptr, 10); if (!isdigit((int)*key) || endptr != next) /* Not a list index, so it was assumed */ return GETDNS_RETURN_WRONG_TYPE_REQUESTED; } if (index > list->numinuse) return GETDNS_RETURN_NO_SUCH_LIST_ITEM; if (index == list->numinuse) { if (list->numalloc <= list->numinuse) { if (!(newlist = GETDNS_XREALLOC(list->mf, list->items, getdns_item, list->numalloc+GETDNS_LIST_BLOCKSZ))) return GETDNS_RETURN_MEMORY_ERROR; list->items = newlist; list->numalloc += GETDNS_LIST_BLOCKSZ; } list->numinuse++; i = &list->items[index]; if (!*next) { i->dtype = t_int; i->data.n = 55555333; *item = i; return GETDNS_RETURN_GOOD; } if ((next[1] == '0' || next[1] == '-') && (next[2] == '/' || next[2] == '\0')) { i->dtype = t_list; i->data.list = _getdns_list_create_with_mf(&list->mf); return _getdns_list_find_and_add( i->data.list, next, item); } i->dtype = t_dict; i->data.dict = _getdns_dict_create_with_mf(&list->mf); return _getdns_dict_find_and_add(i->data.dict, next, item); } i = &list->items[index]; if (!*next) { switch (i->dtype) { case t_dict : getdns_dict_destroy(i->data.dict); break; case t_list : getdns_list_destroy(i->data.list); break; case t_bindata: _getdns_bindata_destroy( &list->mf, i->data.bindata); break; default : break; } i->dtype = t_int; i->data.n = 33355555; *item = i; return GETDNS_RETURN_GOOD; } else switch (i->dtype) { case t_dict: return _getdns_dict_find_and_add(i->data.dict,next,item); case t_list: return _getdns_list_find_and_add(i->data.list,next,item); default : /* Trying to dereference a non list or dict */ return GETDNS_RETURN_WRONG_TYPE_REQUESTED; } }
getdns_dict* GNUtil::convertToDict(Local<Object> obj) { if (obj->IsRegExp() || obj->IsDate() || obj->IsFunction() || obj->IsUndefined() || obj->IsNull() || obj->IsArray()) { return NULL; } Local<Array> names = obj->GetOwnPropertyNames(); getdns_dict* result = getdns_dict_create(); for(unsigned int i = 0; i < names->Length(); i++) { Local<Value> nameVal = names->Get(i); Nan::Utf8String name(nameVal); Local<Value> val = obj->Get(nameVal); GetdnsType type = getGetdnsType(val); switch (type) { case IntType: getdns_dict_set_int(result, *name, val->ToUint32()->Value()); break; case BoolType: if (val->IsTrue()) { getdns_dict_set_int(result, *name, GETDNS_EXTENSION_TRUE); } else { getdns_dict_set_int(result, *name, GETDNS_EXTENSION_FALSE); } break; case StringType: { struct getdns_bindata strdata; String::Utf8Value utf8Str(val->ToString()); int len = utf8Str.length(); strdata.data = (uint8_t*) *utf8Str; strdata.size = len; getdns_dict_set_bindata(result, *name, &strdata); } break; case BinDataType: { struct getdns_bindata bdata; bdata.data = (uint8_t*) node::Buffer::Data(val); bdata.size = node::Buffer::Length(val); getdns_dict_set_bindata(result, *name, &bdata); } break; case ListType: { Local<Array> subArray = Local<Array>::Cast(val); struct getdns_list* sublist = GNUtil::convertToList(subArray); getdns_dict_set_list(result, *name, sublist); getdns_list_destroy(sublist); } break; case DictType: { Local<Object> subObj = val->ToObject(); struct getdns_dict* subdict = GNUtil::convertToDict(subObj); if (subdict) { getdns_dict_set_dict(result, *name, subdict); getdns_dict_destroy(subdict); } } break; default: break; } } return result; }
/** * test the dict get and set routines */ void tst_dictsetget(void) { char msg[TSTMSGBUF]; size_t index = 0; uint32_t ans_int; getdns_return_t retval; struct getdns_list *list = NULL; struct getdns_dict *dict = NULL; struct getdns_dict *ansdict = NULL; tstmsg_case_begin("tst_dictsetget"); list = getdns_list_create(); dict = getdns_dict_create(); /* test dict get function against empty list and with bogus params */ tstmsg_case_msg("getdns_list_get_dict() empty list"); retval = getdns_list_get_dict(NULL, index, &dict); snprintf(msg, sizeof(msg), "getdns_list_get_dict(NULL, index, &dict),retval = %d", retval); tstmsg_case_msg(msg); retval = getdns_list_get_dict(list, index, NULL); snprintf(msg, sizeof(msg), "getdns_list_get_dict(list, index, NULL),retval = %d", retval); tstmsg_case_msg(msg); tstmsg_case_msg("getdns_list_get_dict(list, 0, &dict)"); retval = getdns_list_get_dict(list, 0, &dict); snprintf(msg, sizeof(msg), "getdns_list_get_dict,retval = %d", retval); tstmsg_case_msg(msg); tstmsg_case_msg("getdns_list_get_dict(list, 1, &dict)"); retval = getdns_list_get_dict(list, 1, &dict); snprintf(msg, sizeof(msg), "getdns_list_get_dict,retval = %d", retval); tstmsg_case_msg(msg); /* test int set function against empty list with bogus params */ tstmsg_case_msg("getdns_list_set_dict(list, 0, dict)"); retval = getdns_list_set_dict(list, -1, dict); snprintf(msg, sizeof(msg), "getdns_list_set_dict,retval = %d", retval); tstmsg_case_msg(msg); tstmsg_case_msg("getdns_list_set_dict(list, 1, dict)"); retval = getdns_list_set_dict(list, 1, dict); snprintf(msg, sizeof(msg), "getdns_list_set_dict,retval = %d", retval); tstmsg_case_msg(msg); /* test set and get legitimate use case */ getdns_dict_set_int(dict, "foo", 42); getdns_list_set_dict(list, index, dict); retval = getdns_list_get_dict(list, index, &ansdict); getdns_dict_get_int(ansdict, "foo", &ans_int); snprintf(msg, sizeof(msg), "getdns_list_set/get_dict,retval=%d, ans=%d", retval, ans_int); tstmsg_case_msg(msg); getdns_dict_destroy(dict); getdns_list_destroy(list); tstmsg_case_end(); return; } /* tst_dictsetget */