getdns_return_t getdns_extension_set_libevent_base(getdns_context *context, struct event_base *base) { static getdns_eventloop_vmt getdns_libevent_vmt = { getdns_libevent_cleanup, getdns_libevent_schedule, getdns_libevent_clear, getdns_libevent_run, getdns_libevent_run_once }; getdns_libevent *ext; if (!context) return GETDNS_RETURN_BAD_CONTEXT; if (!base) return GETDNS_RETURN_INVALID_PARAMETER; ext = GETDNS_MALLOC(*priv_getdns_context_mf(context), getdns_libevent); if (!ext) return GETDNS_RETURN_MEMORY_ERROR; ext->vmt = &getdns_libevent_vmt; ext->base = base; ext->mf = *priv_getdns_context_mf(context); return getdns_context_set_eventloop(context, (getdns_eventloop *)ext); }
getdns_return_t getdns_extension_set_libuv_loop(getdns_context *context, uv_loop_t *loop) { static getdns_eventloop_vmt getdns_libuv_vmt = { getdns_libuv_cleanup, getdns_libuv_schedule, getdns_libuv_clear, getdns_libuv_run, getdns_libuv_run_once }; getdns_libuv *ext; if (!context) return GETDNS_RETURN_BAD_CONTEXT; if (!loop) return GETDNS_RETURN_INVALID_PARAMETER; ext = GETDNS_MALLOC(*priv_getdns_context_mf(context), getdns_libuv); if (!ext) return GETDNS_RETURN_MEMORY_ERROR; ext->vmt = &getdns_libuv_vmt; ext->loop = loop; ext->mf = *priv_getdns_context_mf(context); return getdns_context_set_eventloop(context, (getdns_eventloop *)ext); }
/* create a new dns req to be submitted */ getdns_dns_req * dns_req_new(struct getdns_context *context, const char *name, uint16_t request_type, struct getdns_dict *extensions) { getdns_dns_req *result = NULL; getdns_network_req *req = NULL; result = GETDNS_MALLOC(context->mf, getdns_dns_req); if (result == NULL) { return NULL; } result->my_mf = context->mf; result->name = getdns_strdup(&(result->my_mf), name); result->context = context; result->canceled = 0; result->current_req = NULL; result->first_req = NULL; result->trans_id = ldns_get_random(); getdns_dict_copy(extensions, &result->extensions); result->return_dnssec_status = context->return_dnssec_status; /* will be set by caller */ result->user_pointer = NULL; result->user_callback = NULL; result->local_timeout_id = 0; /* create the requests */ req = network_req_new(result, request_type, LDNS_RR_CLASS_IN, extensions); if (!req) { dns_req_free(result); return NULL; } result->current_req = req; result->first_req = req; /* tack on A or AAAA if needed */ if (is_extension_set(extensions, "return_both_v4_and_v6") && (request_type == GETDNS_RRTYPE_A || request_type == GETDNS_RRTYPE_AAAA)) { uint16_t next_req_type = (request_type == GETDNS_RRTYPE_A) ? GETDNS_RRTYPE_AAAA : GETDNS_RRTYPE_A; getdns_network_req *next_req = network_req_new(result, next_req_type, LDNS_RR_CLASS_IN, extensions); if (!next_req) { dns_req_free(result); return NULL; } req->next = next_req; } return result; }
getdns_return_t _getdns_get_pubkey_pinset_from_list(const getdns_list *pinset_list, struct mem_funcs *mf, sha256_pin_t **pinset_out) { getdns_return_t r; size_t pins, i; sha256_pin_t *out = NULL, *onext = NULL; getdns_dict * pin; getdns_bindata * data = NULL; if (r = getdns_list_get_length(pinset_list, &pins), r) return r; for (i = 0; i < pins; i++) { if (r = getdns_list_get_dict(pinset_list, i, &pin), r) goto fail; /* does the pin have the right digest type? */ if (r = getdns_dict_get_bindata(pin, "digest", &data), r) goto fail; if (data->size != sha256.size || memcmp(data->data, sha256.data, sha256.size)) { r = GETDNS_RETURN_INVALID_PARAMETER; goto fail; } /* if it does, is the value the right length? */ if (r = getdns_dict_get_bindata(pin, "value", &data), r) goto fail; if (data->size != SHA256_DIGEST_LENGTH) { r = GETDNS_RETURN_INVALID_PARAMETER; goto fail; } /* make a new pin */ onext = GETDNS_MALLOC(*mf, sha256_pin_t); if (onext == NULL) { r = GETDNS_RETURN_MEMORY_ERROR; goto fail; } onext->next = out; memcpy(onext->pin, data->data, SHA256_DIGEST_LENGTH); out = onext; } *pinset_out = out; return GETDNS_RETURN_GOOD; fail: while (out) { onext = out->next; GETDNS_FREE(*mf, out); out = onext; } return r; }
static getdns_return_t getdns_libuv_schedule(getdns_eventloop *loop, int fd, uint64_t timeout, getdns_eventloop_event *el_ev) { getdns_libuv *ext = (getdns_libuv *)loop; poll_timer *my_ev; uv_poll_t *my_poll; uv_timer_t *my_timer; assert(el_ev); assert(!(el_ev->read_cb || el_ev->write_cb) || fd >= 0); assert( el_ev->read_cb || el_ev->write_cb || el_ev->timeout_cb); DEBUG_UV("enter libuv_schedule(el_ev = %p, el_ev->ev = %p)\n" , el_ev, el_ev->ev); if (!(my_ev = GETDNS_MALLOC(ext->mf, poll_timer))) return GETDNS_RETURN_MEMORY_ERROR; my_ev->to_close = 0; my_ev->mf = ext->mf; el_ev->ev = my_ev; if (el_ev->read_cb) { my_poll = &my_ev->read; my_poll->data = el_ev; uv_poll_init(ext->loop, my_poll, fd); uv_poll_start(my_poll, UV_READABLE, getdns_libuv_read_cb); } if (el_ev->write_cb) { my_poll = &my_ev->write; my_poll->data = el_ev; uv_poll_init(ext->loop, my_poll, fd); uv_poll_start(my_poll, UV_WRITABLE, getdns_libuv_write_cb); } if (el_ev->timeout_cb) { my_timer = &my_ev->timer; my_timer->data = el_ev; uv_timer_init(ext->loop, my_timer); uv_timer_start(my_timer, getdns_libuv_timeout_cb, timeout, 0); } DEBUG_UV("exit libuv_schedule(el_ev = %p, el_ev->ev = %p)\n" , el_ev, el_ev->ev); return GETDNS_RETURN_GOOD; }
getdns_network_req * network_req_new(getdns_dns_req * owner, uint16_t request_type, uint16_t request_class, struct getdns_dict *extensions) { getdns_network_req *net_req = GETDNS_MALLOC( owner->my_mf , getdns_network_req); if (!net_req) { return NULL; } net_req->result = NULL; net_req->next = NULL; net_req->request_type = request_type; net_req->request_class = request_class; net_req->unbound_id = -1; net_req->state = NET_REQ_NOT_SENT; net_req->owner = owner; /* TODO: records and other extensions */ return net_req; }