ri= adns_rr_info(ans->type, &rrtn,&fmtn,&len, 0,0);
fprintf(stdout, "%s type ",domain);
dumptype(ri,rrtn,fmtn);
- fprintf(stdout, " flags %d: %s; nrrs=%d; cname=%s; ttl=%ld\n",
+ fprintf(stdout, " flags %d: %s; nrrs=%d; cname=%s; owner=%s; ttl=%ld\n",
qflags, adns_strerror(ans->status),
- ans->nrrs, ans->cname ? ans->cname : "$",
+ ans->nrrs,
+ ans->cname ? ans->cname : "$",
+ ans->owner ? ans->owner : "$",
(long)ans->expires - (long)now.tv_sec);
if (ans->nrrs) {
assert(!ri);
typedef enum {
adns_qf_search= 0x000001, /* use the searchlist */
adns_qf_usevc= 0x000002, /* use a virtual circuit (TCP connection) */
- adns_qf_owner= 0x000004, /* fill in the owner field in the answer fixme:do */
+ adns_qf_owner= 0x000004, /* fill in the owner field in the answer */
adns_qf_quoteok_query= 0x000010, /* allow quote-requiring chars in query domain */
adns_qf_quoteok_cname= 0x000020, /* allow ... in CNAME we go via */
adns_qf_quoteok_anshost= 0x000040, /* allow ... in answers expected to be hostnames */
typedef struct {
adns_status status;
char *cname; /* always NULL if query was for CNAME records */
- char *owner; /* often NULL, depending on query flags */
+ char *owner; /* only set if requested in query flags */
adns_rrtype type; /* guaranteed to be same as in query */
time_t expires; /* expiry time, defined only if _s_ok, nxdomain or nodata. NOT TTL! */
int nrrs, rrsz;
* we found a cname (this corresponds to cname_dgram in the query
* structure). type is set from the word go. nrrs and rrs
* are set together, when we find how many rrs there are.
+ * owner is set during querying unless we're doing searchlist,
+ * in which case it is set only when we find an answer.
*/
byte *cname_dgram;
* absolute query yet (0=not yet, 1=done, -1=must do straight away,
* but not done yet). If flags doesn't have adns_qf_search then
* the vbuf is initialised but empty and everything else is zero.
- *
- * fixme: actually implement this!
*/
int id, flags, udpretries;
memset(&qu->ctx,0,sizeof(qu->ctx));
qu->answer->status= adns_s_ok;
- qu->answer->cname= 0;
+ qu->answer->cname= qu->answer->owner= 0;
qu->answer->type= typei->type;
qu->answer->expires= -1;
qu->answer->nrrs= 0;
adns__query_fail(qu,stat);
}
+static int save_owner(adns_query qu, const char *owner, int ol) {
+ /* Returns 1 if OK, otherwise there was no memory. */
+ adns_answer *ans;
+
+ ans= qu->answer;
+ assert(!ans->owner);
+
+ ans->owner= adns__alloc_interim(qu,ol+1); if (!ans->owner) return 0;
+
+ memcpy(ans->owner,owner,ol);
+ ans->owner[ol]= 0;
+ return 1;
+}
+
int adns_submit(adns_state ads,
const char *owner,
adns_rrtype type,
qu->search_origlen= ol;
adns__search_next(ads,qu,now);
} else {
+ if (flags & adns_qf_owner) {
+ if (!save_owner(qu,owner,ol)) { stat= adns_s_nomemory; goto x_adnsfail; }
+ }
query_simple(ads,qu, owner,ol, typei,flags, now);
}
return 0;
qu->final_allocspace= (byte*)ans + MEM_ROUND(sizeof(*ans));
adns__makefinal_str(qu,&ans->cname);
+ adns__makefinal_str(qu,&ans->owner);
if (ans->nrrs) {
adns__makefinal_block(qu, &ans->rrs.untyped, ans->nrrs*ans->rrsz);
qu->id= -1;
ans= qu->answer;
+ if (qu->flags & adns_qf_owner && qu->flags & adns_qf_search &&
+ ans->status != adns_s_nomemory) {
+ if (!save_owner(qu, qu->search_vb.buf, qu->search_vb.used)) {
+ adns__query_fail(qu,adns_s_nomemory);
+ return;
+ }
+ }
+
if (ans->nrrs && qu->typei->diff_needswap) {
if (!adns__vbuf_ensure(&qu->vb,qu->typei->rrsz)) {
adns__query_fail(qu,adns_s_nomemory);