chiark / gitweb /
d0867de3b44590a3e0975408937bda7a10654bd8
[adns.git] / src / submit.c
1 /**/
2
3 #include <stdlib.h>
4 #include <unistd.h>
5 #include <errno.h>
6
7 #include <sys/time.h>
8
9 #include "internal.h"
10
11 static adns_query allocquery(adns_state ads, const char *owner, int ol,
12                              int id, adns_rrtype type,
13                              adns_queryflags flags, const qcontext *ctx) {
14   /* Query message used is the one assembled in ads->rqbuf */
15   adns_query qu;
16   
17   qu= malloc(sizeof(*qu)+ol+1+ads->rqbuf.used); if (!qu) return 0;
18   qu->state= query_udp;
19   qu->next= qu->back= qu->parent= 0;
20   LIST_INIT(qu->children);
21   qu->siblings.next= qu->siblings.back= 0;
22   qu->type= type;
23   adns__vbuf_init(&qu->answer);
24   qu->id= id;
25   qu->flags= flags;
26   qu->udpretries= 0;
27   qu->udpnextserver= 0;
28   qu->udpsent= qu->tcpfailed= 0;
29   timerclear(&qu->timeout);
30   memcpy(&qu->context,ctx,sizeof(qu->context));
31   memcpy(qu->owner,owner,ol); qu->owner[ol]= 0;
32   qu->querymsg= qu->owner+ol+1;
33   memcpy(qu->owner+ol+1,ads->rqbuf.buf,ads->rqbuf.used);
34   qu->querylen= ads->rqbuf.used;
35   return qu;
36 }
37
38 static int failsubmit(adns_state ads, const qcontext *ctx, adns_query *query_r,
39                       adns_rrtype type, adns_queryflags flags,
40                       int id, adns_status stat) {
41   adns_query qu;
42
43   ads->rqbuf.used= 0;
44   qu= allocquery(ads,0,0,id,type,flags,ctx); if (!qu) return errno;
45   adns__query_fail(ads,qu,stat);
46   *query_r= qu;
47   return 0;
48 }
49
50 int adns_submit(adns_state ads,
51                 const char *owner,
52                 adns_rrtype type,
53                 adns_queryflags flags,
54                 void *context,
55                 adns_query *query_r) {
56   adns_query qu;
57   adns_status stat;
58   int ol, id, r;
59   qcontext ctx;
60   struct timeval now;
61
62   ctx.ext= context;
63   id= ads->nextid++;
64
65   r= gettimeofday(&now,0); if (r) return errno;
66
67   ol= strlen(owner);
68   if (ol<=1 || ol>MAXDNAME+1)
69     return failsubmit(ads,context,query_r,type,flags,id,adns_s_invaliddomain);
70   if (owner[ol-1]=='.' && owner[ol-2]!='\\') { flags &= ~adns_qf_search; ol--; }
71
72   stat= adns__mkquery(ads,owner,ol,id,type,flags);
73   if (stat) return failsubmit(ads,context,query_r,type,flags,id,stat);
74
75   qu= allocquery(ads,owner,ol,id,type,flags,&ctx); if (!qu) return errno;
76   adns__query_udp(ads,qu,now);
77   adns__autosys(ads,now);
78
79   *query_r= qu;
80   return 0;
81 }
82
83 int adns_synchronous(adns_state ads,
84                      const char *owner,
85                      adns_rrtype type,
86                      adns_queryflags flags,
87                      adns_answer **answer_r) {
88   adns_query qu;
89   int r;
90   
91   r= adns_submit(ads,owner,type,flags,0,&qu);
92   if (r) return r;
93
94   do {
95     r= adns_wait(ads,&qu,answer_r,0);
96   } while (r==EINTR);
97   if (r) adns_cancel(ads,qu);
98   return r;
99 }
100
101 void adns_cancel(adns_state ads, adns_query query) {
102   abort(); /* fixme */
103 }