1 /* Name resolution using adns */
7 #error secnet requires ADNS version 1.0 or above
10 #include <arpa/inet.h>
16 struct resolver_if ops
;
25 resolve_answer_fn
*answer
;
29 static resolve_request_fn resolve_request
;
30 static bool_t
resolve_request(void *sst
, cstring_t name
,
31 int port
, struct comm_if
*comm
,
32 resolve_answer_fn
*cb
, void *cst
)
37 const int maxlitlen
=50;
39 ssize_t l
=strlen(name
);
40 if (name
[0]=='[' && l
<maxlitlen
&& l
>2 && name
[l
-1]==']') {
41 char trimmed
[maxlitlen
+1];
42 memcpy(trimmed
,name
+1,l
-2);
47 ca
.ia
.sin
.sin_family
=AF_INET
;
48 ca
.ia
.sin
.sin_port
=htons(port
);
49 if (inet_aton(trimmed
,&ca
.ia
.sin
.sin_addr
))
56 q
=safe_malloc(sizeof *q
,"resolve_request");
62 rv
=adns_submit(st
->ast
, name
, adns_r_addr
, 0, q
, &q
->query
);
65 "resolver: failed to submit lookup for %s: %s",name
,
74 static int resolver_beforepoll(void *sst
, struct pollfd
*fds
, int *nfds_io
,
78 return adns_beforepoll(st
->ast
, fds
, nfds_io
, timeout_io
, tv_now
);
81 static void resolver_afterpoll(void *sst
, struct pollfd
*fds
, int nfds
)
90 adns_afterpoll(st
->ast
, fds
, nfds
, tv_now
);
94 rv
=adns_check(st
->ast
, &aq
, &ans
, &qp
);
97 if (ans
->status
!=adns_s_ok
) {
98 q
->answer(q
->cst
,NULL
,0,0); /* Failure */
102 int rslot
, wslot
, total
;
103 int ca_len
=MIN(ans
->nrrs
,MAX_PEER_ADDRS
);
104 struct comm_addr ca_buf
[ca_len
];
106 for (rslot
=0, wslot
=0, total
=0;
110 if (!(wslot
<ca_len
)) continue;
111 adns_rr_addr
*ra
=&ans
->rrs
.addr
[rslot
];
112 struct comm_addr
*ca
=&ca_buf
[wslot
];
114 /* copy fields individually so we leave holes zeroed: */
115 switch (ra
->addr
.sa
.sa_family
) {
117 assert(ra
->len
== sizeof(ca
->ia
.sin
));
118 ca
->ia
.sin
.sin_family
=ra
->addr
.inet
.sin_family
;
119 ca
->ia
.sin
.sin_addr
= ra
->addr
.inet
.sin_addr
;
120 ca
->ia
.sin
.sin_port
= htons(q
->port
);
127 q
->answer(q
->cst
,ca_buf
,wslot
,total
);
131 } else if (rv
==EAGAIN
|| rv
==ESRCH
) {
134 fatal("resolver_afterpoll: adns_check() returned %d",rv
);
141 /* Initialise adns, using parameters supplied */
142 static list_t
*adnsresolver_apply(closure_t
*self
, struct cloc loc
,
143 dict_t
*context
, list_t
*args
)
150 st
=safe_malloc(sizeof(*st
),"adnsresolver_apply");
151 st
->cl
.description
="adns";
152 st
->cl
.type
=CL_RESOLVER
;
154 st
->cl
.interface
=&st
->ops
;
157 st
->ops
.request
=resolve_request
;
160 if (!i
|| i
->type
!=t_dict
) {
161 cfgfatal(st
->loc
,"adns","first argument must be a dictionary\n");
164 conf
=dict_read_string(d
,"config",False
,"adns",loc
);
167 if (adns_init_strcfg(&st
->ast
, 0, 0, conf
)) {
168 fatal_perror("Failed to initialise ADNS");
171 if (adns_init(&st
->ast
, 0, 0)) {
172 fatal_perror("Failed to initialise ADNS");
176 register_for_poll(st
, resolver_beforepoll
, resolver_afterpoll
,
177 ADNS_POLLFDS_RECOMMENDED
+5,"resolver");
179 return new_closure(&st
->cl
);
182 void resolver_module(dict_t
*dict
)
184 add_closure(dict
,"adns",adnsresolver_apply
);