Local<Value> GNUtil::convertToJSObj(struct getdns_dict* dict) { if (!dict) { return Nan::Null(); } // try it as an IP char* ipStr = getdns_dict_to_ip_string(dict); if (ipStr) { Local<Value> result = Nan::New<String>(ipStr).ToLocalChecked(); free(ipStr); return result; } getdns_list* names; getdns_dict_get_names(dict, &names); size_t len = 0; Local<Object> result = Nan::New<Object>(); getdns_list_get_length(names, &len); for (size_t i = 0; i < len; ++i) { getdns_bindata* nameBin; getdns_list_get_bindata(names, i, &nameBin); Local<Value> name = Nan::New<String>((char*) nameBin->data).ToLocalChecked(); getdns_data_type type; getdns_dict_get_data_type(dict, (char*)nameBin->data, &type); switch (type) { case t_bindata: { getdns_bindata* data = NULL; getdns_dict_get_bindata(dict, (char*)nameBin->data, &data); result->Set(name, convertBinData(data, (char*) nameBin->data)); break; } case t_int: { uint32_t res = 0; getdns_dict_get_int(dict, (char*)nameBin->data, &res); result->Set(name, Nan::New<Integer>(res)); break; } case t_dict: { getdns_dict* subdict = NULL; getdns_dict_get_dict(dict, (char*)nameBin->data, &subdict); result->Set(name, GNUtil::convertToJSObj(subdict)); break; } case t_list: { getdns_list* list = NULL; getdns_dict_get_list(dict, (char*)nameBin->data, &list); result->Set(name, GNUtil::convertToJSArray(list)); break; } default: break; } } getdns_list_destroy(names); return result; }
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; }
/*---------------------------------------- _getdns_list_copy */ getdns_return_t _getdns_list_copy(const struct getdns_list * srclist, struct getdns_list ** dstlist) { int i; getdns_return_t retval; if (!dstlist) return GETDNS_RETURN_INVALID_PARAMETER; if (!srclist) { *dstlist = NULL; return GETDNS_RETURN_GOOD; } *dstlist = getdns_list_create_with_extended_memory_functions( srclist->mf.mf_arg, srclist->mf.mf.ext.malloc, srclist->mf.mf.ext.realloc, srclist->mf.mf.ext.free ); if (!dstlist) return GETDNS_RETURN_GENERIC_ERROR; for (i = 0; i < srclist->numinuse; i++) { switch (srclist->items[i].dtype) { case t_int: retval = _getdns_list_append_int(*dstlist, srclist->items[i].data.n); break; case t_list: retval = _getdns_list_append_list(*dstlist, srclist->items[i].data.list); break; case t_bindata: retval = _getdns_list_append_bindata(*dstlist, srclist->items[i].data.bindata); break; case t_dict: retval = _getdns_list_append_dict(*dstlist, srclist->items[i].data.dict); break; } if (retval != GETDNS_RETURN_GOOD) { getdns_list_destroy(*dstlist); *dstlist = NULL; return retval; } } return GETDNS_RETURN_GOOD; } /* _getdns_list_copy */
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_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; } }
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_list */ getdns_return_t getdns_list_set_list( getdns_list *list, size_t index, const getdns_list *child_list) { getdns_list *newlist; getdns_return_t r; if (!list || !child_list) return GETDNS_RETURN_INVALID_PARAMETER; if ((r = _getdns_list_copy(child_list, &newlist))) return r; if ((r = _getdns_list_request_index(list, index))) { getdns_list_destroy(newlist); return r; } list->items[index].dtype = t_list; list->items[index].data.list = newlist; return GETDNS_RETURN_GOOD; } /* getdns_list_set_list */
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; }
static getdns_return_t validate_chain(getdns_dict *response) { getdns_return_t r; getdns_list *validation_chain; getdns_list *replies_tree; getdns_dict *reply; getdns_list *to_validate; getdns_list *trust_anchor; size_t i; int s; if (!(to_validate = getdns_list_create())) return GETDNS_RETURN_MEMORY_ERROR; trust_anchor = getdns_root_trust_anchor(NULL); if ((r = getdns_dict_get_list( response, "validation_chain", &validation_chain))) goto error; if ((r = getdns_dict_get_list( response, "replies_tree", &replies_tree))) goto error; fprintf(stdout, "replies_tree dnssec_status: "); switch ((s = getdns_validate_dnssec( replies_tree, validation_chain, trust_anchor))) { case GETDNS_DNSSEC_SECURE: fprintf(stdout, "GETDNS_DNSSEC_SECURE\n"); break; case GETDNS_DNSSEC_BOGUS: fprintf(stdout, "GETDNS_DNSSEC_BOGUS\n"); break; case GETDNS_DNSSEC_INDETERMINATE: fprintf(stdout, "GETDNS_DNSSEC_INDETERMINATE\n"); break; case GETDNS_DNSSEC_INSECURE: fprintf(stdout, "GETDNS_DNSSEC_INSECURE\n"); break; case GETDNS_DNSSEC_NOT_PERFORMED: fprintf(stdout, "GETDNS_DNSSEC_NOT_PERFORMED\n"); break; default: fprintf(stdout, "%d\n", (int)s); } i = 0; while (!(r = getdns_list_get_dict(replies_tree, i++, &reply))) { if ((r = getdns_list_set_dict(to_validate, 0, reply))) goto error; fprintf( stdout , "reply %zu, dnssec_status: ", i); switch ((s = getdns_validate_dnssec( to_validate, validation_chain, trust_anchor))) { case GETDNS_DNSSEC_SECURE: fprintf(stdout, "GETDNS_DNSSEC_SECURE\n"); break; case GETDNS_DNSSEC_BOGUS: fprintf(stdout, "GETDNS_DNSSEC_BOGUS\n"); break; case GETDNS_DNSSEC_INDETERMINATE: fprintf(stdout, "GETDNS_DNSSEC_INDETERMINATE\n"); break; case GETDNS_DNSSEC_INSECURE: fprintf(stdout, "GETDNS_DNSSEC_INSECURE\n"); break; case GETDNS_DNSSEC_NOT_PERFORMED: fprintf(stdout, "GETDNS_DNSSEC_NOT_PERFORMED\n"); break; default: fprintf(stdout, "%d\n", (int)s); } } if (r == GETDNS_RETURN_NO_SUCH_LIST_ITEM) r = GETDNS_RETURN_GOOD; error: getdns_list_destroy(trust_anchor); getdns_list_destroy(to_validate); return GETDNS_RETURN_GOOD; }
/** * test the int get and set routines */ void tst_intsetget(void) { char msg[TSTMSGBUF]; size_t index = 0; uint32_t ans_int; getdns_return_t retval; struct getdns_list *list = NULL; tstmsg_case_begin("tst_intsetget"); list = getdns_list_create(); /* test int get function against empty list and with bogus params */ tstmsg_case_msg("getdns_list_get_int() empty list"); retval = getdns_list_get_int(NULL, index, &ans_int); snprintf(msg, sizeof(msg), "getdns_list_get_int(NULL, index, &ans_int),retval = %d", retval); tstmsg_case_msg(msg); retval = getdns_list_get_int(list, index, NULL); snprintf(msg, sizeof(msg), "getdns_list_get_int(list, index, NULL),retval = %d", retval); tstmsg_case_msg(msg); tstmsg_case_msg("getdns_list_get_int(list, 0, &ans_int)"); retval = getdns_list_get_int(list, 0, &ans_int); snprintf(msg, sizeof(msg), "getdns_list_get_int,retval = %d", retval); tstmsg_case_msg(msg); tstmsg_case_msg("getdns_list_get_int(list, 1, &ans_int)"); retval = getdns_list_get_int(list, 1, &ans_int); snprintf(msg, sizeof(msg), "getdns_list_get_int,retval = %d", retval); tstmsg_case_msg(msg); /* test int set function against empty list with bogus params */ tstmsg_case_msg("getdns_list_set_int(list, -1, ans_int)"); retval = getdns_list_set_int(list, -1, ans_int); snprintf(msg, sizeof(msg), "getdns_list_set_int,retval = %d", retval); tstmsg_case_msg(msg); tstmsg_case_msg("getdns_list_set_int(list, 1, ans_int)"); retval = getdns_list_set_int(list, 1, ans_int); snprintf(msg, sizeof(msg), "getdns_list_set_int,retval = %d", retval); tstmsg_case_msg(msg); /* test set and get legitimate use case */ getdns_list_set_int(list, index, 42); retval = getdns_list_get_int(list, index, &ans_int); snprintf(msg, sizeof(msg), "getdns_list_set/get_int,retval = %d, ans = %d", retval, ans_int); tstmsg_case_msg(msg); getdns_list_destroy(list); tstmsg_case_end(); return; } /* tst_intsetget */
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; }
/** * 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 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 */
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; } }
/** * test the list get and set routines */ void tst_bindatasetget(void) { char msg[TSTMSGBUF]; size_t index = 0; getdns_return_t retval; struct getdns_list *list = NULL; struct getdns_bindata *new_bindata = NULL; struct getdns_bindata *ans_bindata = NULL; tstmsg_case_begin("tst_bindatasetget"); list = getdns_list_create(); /* test get function against empty list and with bogus params */ tstmsg_case_msg("getdns_list_get_bindata() empty list"); retval = getdns_list_get_bindata(NULL, index, &ans_bindata); snprintf(msg, sizeof(msg), "getdns_list_get_bindata(NULL, index, &ans_bindata),retval = %d", retval); tstmsg_case_msg(msg); retval = getdns_list_get_bindata(list, index, NULL); snprintf(msg, sizeof(msg), "getdns_list_get_bindata(list, index, NULL),retval = %d", retval); tstmsg_case_msg(msg); tstmsg_case_msg("getdns_list_get_bindata(list, 0, &ans_bindata)"); retval = getdns_list_get_bindata(list, 0, &ans_bindata); snprintf(msg, sizeof(msg), "getdns_list_get_bindata,retval = %d", retval); tstmsg_case_msg(msg); tstmsg_case_msg("getdns_list_get_bindata(list, 1, &ans_bindata)"); retval = getdns_list_get_bindata(list, 1, &ans_bindata); snprintf(msg, sizeof(msg), "getdns_list_get_bindata,retval = %d", retval); tstmsg_case_msg(msg); /* test set function against empty list with bogus params */ tstmsg_case_msg("getdns_list_set_bindata(list, -1, ans_bindata)"); retval = getdns_list_set_bindata(list, -1, NULL); snprintf(msg, sizeof(msg), "getdns_list_set_bindata,retval = %d", retval); tstmsg_case_msg(msg); tstmsg_case_msg("getdns_list_set_bindata(list, 1, ans_bindata)"); retval = getdns_list_set_bindata(list, 1, NULL); snprintf(msg, sizeof(msg), "getdns_list_set_bindata,retval = %d", retval); tstmsg_case_msg(msg); /* test set and get legitimate use case */ new_bindata = (struct getdns_bindata *) malloc(sizeof(struct getdns_bindata)); new_bindata->size = strlen("foobar") + 1; new_bindata->data = (uint8_t *) "foobar"; getdns_list_set_bindata(list, index, new_bindata); retval = getdns_list_get_bindata(list, index, &ans_bindata); snprintf(msg, sizeof(msg), "getdns_list_set/get_bindata,retval = %d, bindata->data = %d,%s", retval, (int) ans_bindata->size, (char *) ans_bindata->data); tstmsg_case_msg(msg); getdns_list_destroy(list); tstmsg_case_end(); return; } /* tst_bindatasetget */
/** * test the create, destroy and allocation functions */ void tst_create(void) { char msg[TSTMSGBUF]; size_t index; int i; getdns_return_t retval; struct getdns_list *list = NULL; /* make sure we can do a simple create/destroy first */ tstmsg_case_begin("tst_create"); tstmsg_case_msg("getdns_list_create"); list = getdns_list_create(); if (list != NULL) { tstmsg_case_msg("getdns_list_destroy(list)"); getdns_list_destroy(list); } tstmsg_case_msg("getdns_list_destroy(NULL)"); getdns_list_destroy(NULL); /* add items until we force it to allocate more storage */ tstmsg_case_msg("getdns_list_set_int(list, i) past block size"); list = getdns_list_create(); for (i = 0; i < GETDNS_LIST_BLOCKSZ + 2; i++) { retval = getdns_list_set_int(list, i, i); if (retval != GETDNS_RETURN_GOOD) { snprintf(msg, sizeof(msg), "getdns_list_set_int,i=%d,retval = %d", i, retval); tstmsg_case_msg(msg); } } tstmsg_case_msg("getdns_list_get_length(list)"); retval = getdns_list_get_length(list, &index); snprintf(msg, sizeof(msg), "list length = %d", (int) index); tstmsg_case_msg(msg); tstmsg_case_msg("getdns_list_get_length()"); retval = getdns_list_get_length(NULL, &index); snprintf(msg, sizeof(msg), "NUll, %i, retval = %d", (int)index, retval); tstmsg_case_msg(msg); retval = getdns_list_get_length(NULL, NULL); snprintf(msg, sizeof(msg), "NUll, NULL, retval = %d", retval); tstmsg_case_msg(msg); retval = getdns_list_get_length(list, NULL); snprintf(msg, sizeof(msg), "list, NULL, retval = %d", retval); tstmsg_case_msg(msg); getdns_list_destroy(list); tstmsg_case_end(); return; } /* tst_create */
int main(int argc, char const * const argv[]) { getdns_return_t r; getdns_dict *rr_dict; getdns_bindata *dns_name; getdns_bindata address = { 4, "\xb9\x31\x8d\x25" }; getdns_bindata fourth = { 11, "last string" }; size_t length; char *str; uint8_t *wire, *prev_wire; size_t wire_len; getdns_list *rr_list; FILE *in; uint8_t wire_buf[8200]; size_t i; size_t uavailable; int available; char str_buf[10000]; int str_len = sizeof(str_buf); /* Convert string to rr_dict */ if ((r = getdns_str2rr_dict( "some.domain.tld. 60 IN TXT \"first string\" second \"and third\"", &rr_dict, NULL, 3600))) FAIL_r("getdns_str2rr_dict"); /* Add a fourth text element. */ if ((r = getdns_dict_set_bindata(rr_dict, "/rdata/txt_strings/-", &fourth))) FAIL_r("getdns_list_set_bindata"); print_dict(rr_dict); /* Convert to wireformat from rdata_raw. * Added fourth list element should NOT show. */ wire = NULL; if ((r = getdns_rr_dict2wire(rr_dict, &wire, &wire_len))) FAIL_r("getdns_rr_dict2wire"); print_wire(wire, wire_len); free(wire); /* Convert to wireformat from parsing rdata fields. * Added fourth list element should show. */ if ((r = getdns_dict_remove_name(rr_dict, "/rdata/rdata_raw"))) FAIL_r("getdns_dict_remove_name"); printf("\nremoved \"/rdata/rdata_raw\":\n\n"); if ((r = getdns_rr_dict2wire(rr_dict, &wire, &wire_len))) FAIL_r("getdns_rr_dict2wire"); print_wire(wire, wire_len); free(wire); /* Remove second and third string elements and show text format. */ if ((r = getdns_dict_remove_name(rr_dict, "/rdata/txt_strings/1"))) FAIL_r("getdns_dict_remove_name"); if ((r = getdns_dict_remove_name(rr_dict, "/rdata/txt_strings/1"))) FAIL_r("getdns_dict_remove_name"); if ((r = getdns_rr_dict2str(rr_dict, &str))) FAIL_r("getdns_rr_dict2str"); printf("\n%s", str); free(str); /* Remove all string elements and show text format. */ if ((r = getdns_dict_remove_name(rr_dict, "/rdata/txt_strings/0"))) FAIL_r("getdns_dict_remove_name"); if ((r = getdns_dict_remove_name(rr_dict, "/rdata/txt_strings/0"))) FAIL_r("getdns_dict_remove_name"); if ((r = getdns_rr_dict2str(rr_dict, &str))) FAIL_r("getdns_rr_dict2str"); printf("%s", str); free(str); getdns_dict_destroy(rr_dict); /* Construct rr_dict and convert to string */ if (!(rr_dict = getdns_dict_create())) FAIL("getdns_dict_create returned NULL"); if ((r = getdns_convert_fqdn_to_dns_name("www.getdnsapi.net", &dns_name))) FAIL_r("getdns_convert_fqdn_to_dns_name"); r = getdns_dict_set_bindata(rr_dict, "name", dns_name); free(dns_name->data); free(dns_name); if (r) FAIL_r("getdns_dict_set_bindata"); if ((r = getdns_dict_set_int(rr_dict, "type", GETDNS_RRTYPE_A))) FAIL_r("getdns_dict_set_int"); if ((r = getdns_dict_set_bindata(rr_dict, "/rdata/ipv4_address", &address))) FAIL_r("getdns_dict_set_int"); if ((r = getdns_rr_dict2str(rr_dict, &str))) FAIL_r("getdns_rr_dict2str"); printf("\n%s\n", str); free(str); if ((r = getdns_rr_dict2wire(rr_dict, &wire, &wire_len))) FAIL_r("getdns_rr_dict2wire"); getdns_dict_destroy(rr_dict); print_wire(wire, wire_len); free(wire); /* Convert RR with special rdata fields and repeating last element * from string to rr_dict */ if ((r = getdns_str2rr_dict( "hip2 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs1.example.com. rvs2.example.com.", &rr_dict, "nlnetlabs.nl", 3600))) FAIL_r("getdns_str2rr_dict"); if ((r = getdns_dict_remove_name(rr_dict, "/rdata/rdata_raw"))) FAIL_r("getdns_dict_remove_name"); printf("\n"); print_dict(rr_dict); /* Convert RR with special rdata fields and repeating last element * back to string. */ if ((r = getdns_rr_dict2str(rr_dict, &str))) FAIL_r("getdns_rr_dict2str"); printf("%s", str); free(str); /* Convert RR with special rdata fields without repeating last element * to string. */ if ((r = getdns_dict_remove_name(rr_dict, "/rdata/rendezvous_servers"))) FAIL_r("getdns_dict_remove_name"); if ((r = getdns_dict_get_bindata(rr_dict, "name", &dns_name))) FAIL_r("getdns_dict_get_bindata"); dns_name->data[4] = '0'; if ((r = getdns_rr_dict2str(rr_dict, &str))) FAIL_r("getdns_rr_dict2str"); printf("%s\n", str); free(str); getdns_dict_destroy(rr_dict); /* Convert RR with repeat block from string to rr_dict */ if ((r = getdns_str2rr_dict( "apl APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42.128/25 1:224.0.0.0/4 2:FF00:0:0:0:0:0:0:0/8", &rr_dict, "net-dns.org", 3600))) FAIL_r("getdns_str2rr_dict"); if ((r = getdns_dict_remove_name(rr_dict, "/rdata/rdata_raw"))) FAIL_r("getdns_dict_remove_name"); print_dict(rr_dict); /* Convert repeat block from rr_dict back to string. */ if ((r = getdns_rr_dict2str(rr_dict, &str))) FAIL_r("getdns_rr_dict2str"); printf("%s", str); free(str); getdns_dict_destroy(rr_dict); if (!(in = fopen(argv[1], "r"))) FAIL("Could not fopen %s\n", argv[1]); if ((r = getdns_fp2rr_list(in, &rr_list, NULL, 0))) FAIL_r("getdns_fp2rr_list"); fclose(in); print_list(rr_list); print_json_list(rr_list, 1); /* Fill the wire_buf with wireformat RR's in rr_list * wire_buf is too small for last two rr's. */ wire = wire_buf; available = sizeof(wire_buf); for (i = 0; !(r = getdns_list_get_dict(rr_list, i, &rr_dict)); i++) { prev_wire = wire; if ((r = getdns_rr_dict2wire_scan(rr_dict,&wire,&available))) { if (r == GETDNS_RETURN_NEED_MORE_SPACE) { printf("record %.3zu, available buffer space: " "%d\n", i, available); /* The buffer was too small to fit the wire- * format representation. available now holds * a negative number. the wire pointer is this * much beyond the end of the buffer space. * * If we would add available to wire, wire * would be positioned at the end of the buffer * but would not be positioned at a clean RR * border. Therefore we have to remember the * previous position of wire, so we can reset * it at the end of the wireformat representa- * tion of the previously converted rr_dict. */ wire = prev_wire; break; } else FAIL_r("getdns_rr_dict2wire_scan"); } printf("record %3zu, available buffer space: " "%d\n", i, available); fflush(stdout); } if (r == GETDNS_RETURN_NO_SUCH_LIST_ITEM) r = GETDNS_RETURN_GOOD; getdns_list_destroy(rr_list); /* Now scan over the wireformat buffer and convert to rr_dicts again. * Then fill a string buffer with those rr_dicts. */ available = wire - wire_buf; if (available < 0) { fprintf(stderr, "Negative sized buffer!\n"); exit(EXIT_FAILURE); } uavailable = available; wire = wire_buf; str = str_buf; str_len = sizeof(str_buf); while (uavailable > 0 && str_len > 0) { rr_dict = NULL; if ((r = getdns_wire2rr_dict_scan( (const uint8_t **)&wire, &uavailable, &rr_dict))) FAIL_r("getdns_wire2rr_dict_scan"); if ((r = getdns_rr_dict2str_scan(rr_dict, &str, &str_len))) FAIL_r("getdns_rr_dict2str_scan"); getdns_dict_destroy(rr_dict); } *str = 0; /* Print the entire buffer */ printf("%s", str_buf); exit(EXIT_SUCCESS); }