11 int adns__internal_submit(adns_state ads, adns_query *query_r,
12 adns_rrtype type, vbuf *qumsg_vb, int id,
13 adns_queryflags flags, struct timeval now,
14 adns_status failstat, const qcontext *ctx) {
19 const typeinfo *typei;
22 qu= malloc(sizeof(*qu)); if (!qu) goto x_nomemory;
23 qu->answer= malloc(sizeof(*qu->answer)); if (!qu->answer) goto x_freequ_nomemory;
26 qu->back= qu->next= qu->parent= 0;
27 LIST_INIT(qu->children);
28 qu->siblings.next= qu->siblings.back= 0;
30 qu->interim_allocd= 0;
33 qu->typei= adns__findtype(type);
34 adns__vbuf_init(&qu->vb);
37 qu->cname_dglen= qu->cname_begin= 0;
43 qu->udpsent= qu->tcpfailed= 0;
44 timerclear(&qu->timeout);
45 memcpy(&qu->context,ctx,sizeof(qu->context));
46 memcpy(qu->owner,owner,ol); qu->owner[ol]= 0;
48 qu->answer->status= adns_s_ok;
50 qu->answer->type= type;
55 qu->answer->rrsz= qu->rrsz;
58 failstat= adns_s_notimplemented;
63 qu->query_dgram= malloc(qumsg_vb->used);
64 if (!qu->query_dgram) {
65 adns__query_fail(ads,qu,adns_s_nomemory);
68 memcpy(qu->query_dgram,qumsg_vb->buf,qumsg_vb->used);
70 adns__vbuf_init(qumsg_vb);
73 adns__query_fail(ads,qu,failstat);
76 adns__query_udp(ads,qu,now);
77 adns__autosys(ads,now);
85 return adns_s_nomemory;
88 int adns_submit(adns_state ads,
91 adns_queryflags flags,
93 adns_query *query_r) {
99 r= gettimeofday(&now,0); if (r) return errno;
102 adns__vbuf_init(&vb);
105 if (ol<=1 || ol>DNS_MAXDOMAIN+1) { stat= adns_s_invaliddomain; goto xit; }
107 if (owner[ol-1]=='.' && owner[ol-2]!='\\') { flags &= ~adns_qf_search; ol--; }
109 stat= adns__mkquery(ads,&vb, &id, owner,ol, typei,flags);
112 return adns__internal_submit(ads,query_r, type,&vb,id, flags,now, stat,&ctx);
115 int adns_synchronous(adns_state ads,
118 adns_queryflags flags,
119 adns_answer **answer_r) {
123 r= adns_submit(ads,owner,type,flags,0,&qu);
127 r= adns_wait(ads,&qu,answer_r,0);
129 if (r) adns_cancel(ads,qu);
133 void adns_cancel(adns_state ads, adns_query query) {
137 void adns__makefinal_str(adns_query qu, char **strp) {
139 char *before, *after;
143 after= adns__alloc_final(qu,l);
144 memcpy(after,before,l);
148 void adns__makefinal_block(adns__query qu, void **blpp, size_t sz) {
151 after= adns__alloc_final(qu,sz);
152 memcpy(after,*blpp,sz);
156 void *adns__alloc_interim(adns_state ads, adns_query qu, size_t sz) {
159 assert(!qu->final_allocspace);
161 an= malloc(MEM_ROUND(MEM_ROUND(sizeof(*an)) + sz));
163 adns__query_fail(ads,qu,adns_s_nolocalmem);
166 qu->permalloclen += sz;
167 an->next= qu->allocations;
169 return (byte*)an + MEM_ROUND(sizeof(*an));
172 void *adns__alloc_final(adns_query qu, size_t sz) {
173 /* When we're in the _final stage, we _subtract_ from interim_alloc'd
174 * each allocation, and use final_allocspace to point to the next free
180 rp= qu->final_allocspace;
182 qu->interim_allocd -= sz;
183 assert(qu->interim_allocd>=0);
184 qu->final_allocspace= (byte*)rp + sz;