@@ -20,6 +20,11 @@ static ev_io io_watcher;
2020static ev_timer timer_watcher;
2121
2222static Persistent<String> errno_symbol;
23+ static Persistent<String> exchange_symbol;
24+ static Persistent<String> priority_symbol;
25+ static Persistent<String> weight_symbol;
26+ static Persistent<String> port_symbol;
27+ static Persistent<String> name_symbol;
2328
2429static inline Persistent<Function>* cb_persist (const Local<Value> &v) {
2530 Persistent<Function> *fn = new Persistent<Function>();
@@ -174,6 +179,145 @@ static void AfterResolveA6(struct dns_ctx *ctx,
174179 cb_destroy (cb);
175180}
176181
182+ static void AfterResolveMX (struct dns_ctx *ctx,
183+ struct dns_rr_mx *result,
184+ void *data) {
185+ assert (ctx == &dns_defctx);
186+
187+ HandleScope scope;
188+
189+ Persistent<Function> *cb = cb_unwrap (data);
190+
191+ if (result == NULL ) {
192+ ResolveError (cb);
193+ cb_destroy (cb);
194+ return ;
195+ }
196+
197+ /* canonical name */
198+ Local<String> cname = String::New (result->dnsmx_cname );
199+
200+ /* Time-To-Live (TTL) value */
201+ Local<Integer> ttl = Integer::New (result->dnsmx_ttl );
202+
203+ Local<Array> exchanges = Array::New (result->dnsmx_nrr );
204+ for (int i = 0 ; i < result->dnsmx_nrr ; i++) {
205+ HandleScope loop_scope;
206+
207+ Local<Object> exchange = Object::New ();
208+
209+ struct dns_mx *mx = &(result->dnsmx_mx [i]);
210+ exchange->Set (exchange_symbol, String::New (mx->name ));
211+ exchange->Set (priority_symbol, Integer::New (mx->priority ));
212+
213+ exchanges->Set (Integer::New (i), exchange);
214+ }
215+
216+ Local<Value> argv[3 ] = { exchanges, ttl, cname };
217+
218+ TryCatch try_catch;
219+
220+ (*cb)->Call (Context::GetCurrent ()->Global (), 3 , argv);
221+
222+ if (try_catch.HasCaught ()) {
223+ FatalException (try_catch);
224+ }
225+
226+ cb_destroy (cb);
227+ }
228+
229+ static void AfterResolveTXT (struct dns_ctx *ctx,
230+ struct dns_rr_txt *result,
231+ void *data) {
232+ assert (ctx == &dns_defctx);
233+
234+ HandleScope scope;
235+
236+ Persistent<Function> *cb = cb_unwrap (data);
237+
238+ if (result == NULL ) {
239+ ResolveError (cb);
240+ cb_destroy (cb);
241+ return ;
242+ }
243+
244+ /* canonical name */
245+ Local<String> cname = String::New (result->dnstxt_cname );
246+
247+ /* Time-To-Live (TTL) value */
248+ Local<Integer> ttl = Integer::New (result->dnstxt_ttl );
249+
250+ Local<Array> records = Array::New (result->dnstxt_nrr );
251+ for (int i = 0 ; i < result->dnstxt_nrr ; i++) {
252+ HandleScope loop_scope;
253+
254+ struct dns_txt *record = &(result->dnstxt_txt [i]);
255+ const char *txt = (const char *)record->txt ;
256+ records->Set (Integer::New (i), String::New (txt));
257+ }
258+
259+ Local<Value> argv[3 ] = { records, ttl, cname };
260+
261+ TryCatch try_catch;
262+
263+ (*cb)->Call (Context::GetCurrent ()->Global (), 3 , argv);
264+
265+ if (try_catch.HasCaught ()) {
266+ FatalException (try_catch);
267+ }
268+
269+ cb_destroy (cb);
270+ }
271+
272+ static void AfterResolveSRV (struct dns_ctx *ctx,
273+ struct dns_rr_srv *result,
274+ void *data) {
275+ assert (ctx == &dns_defctx);
276+
277+ HandleScope scope;
278+
279+ Persistent<Function> *cb = cb_unwrap (data);
280+
281+ if (result == NULL ) {
282+ ResolveError (cb);
283+ cb_destroy (cb);
284+ return ;
285+ }
286+
287+ /* canonical name */
288+ Local<String> cname = String::New (result->dnssrv_cname );
289+
290+ /* Time-To-Live (TTL) value */
291+ Local<Integer> ttl = Integer::New (result->dnssrv_ttl );
292+
293+ Local<Array> records = Array::New (result->dnssrv_nrr );
294+ for (int i = 0 ; i < result->dnssrv_nrr ; i++) {
295+ HandleScope loop_scope;
296+
297+ Local<Object> record = Object::New ();
298+
299+ struct dns_srv *srv = &(result->dnssrv_srv [i]);
300+ record->Set (priority_symbol, Integer::New (srv->priority ));
301+ record->Set (weight_symbol, Integer::New (srv->weight ));
302+ record->Set (port_symbol, Integer::New (srv->port ));
303+ record->Set (name_symbol, String::New (srv->name ));
304+
305+ records->Set (Integer::New (i), record);
306+ }
307+
308+ Local<Value> argv[3 ] = { records, ttl, cname };
309+
310+ TryCatch try_catch;
311+
312+ (*cb)->Call (Context::GetCurrent ()->Global (), 3 , argv);
313+
314+ if (try_catch.HasCaught ()) {
315+ FatalException (try_catch);
316+ }
317+
318+ cb_destroy (cb);
319+ }
320+
177321static Handle<Value> ResolveA (int type, const Arguments& args) {
178322 HandleScope scope;
179323
@@ -194,6 +338,18 @@ static Handle<Value> ResolveA(int type, const Arguments& args) {
194338 query = dns_submit_a6 (NULL , *name, 0 , AfterResolveA6, cb_persist (args[1 ]));
195339 break ;
196340
341+ case DNS_T_MX:
342+ query = dns_submit_mx (NULL , *name, 0 , AfterResolveMX, cb_persist (args[1 ]));
343+ break ;
344+
345+ case DNS_T_TXT:
346+ query = dns_submit_txt (NULL , *name, DNS_C_IN, 0 , AfterResolveTXT, cb_persist (args[1 ]));
347+ break ;
348+
349+ case DNS_T_SRV:
350+ query = dns_submit_srv (NULL , *name, NULL , NULL , 0 , AfterResolveSRV, cb_persist (args[1 ]));
351+ break ;
352+
197353 default :
198354 return ThrowException (Exception::Error (String::New (" Unsupported type" )));
199355 }
@@ -213,6 +369,18 @@ static Handle<Value> ResolveA6(const Arguments& args) {
213369 return ResolveA (DNS_T_AAAA, args);
214370}
215371
372+ static Handle<Value> ResolveMX (const Arguments& args) {
373+ return ResolveA (DNS_T_MX, args);
374+ }
375+
376+ static Handle<Value> ResolveTXT (const Arguments& args) {
377+ return ResolveA (DNS_T_TXT, args);
378+ }
379+
380+ static Handle<Value> ResolveSRV (const Arguments& args) {
381+ return ResolveA (DNS_T_SRV, args);
382+ }
383+
216384static void AfterReverse (struct dns_ctx *ctx,
217385 struct dns_rr_ptr *result,
218386 void *data) {
@@ -312,6 +480,12 @@ void DNS::Initialize(Handle<Object> target) {
312480
313481 errno_symbol = NODE_PSYMBOL (" errno" );
314482
483+ exchange_symbol = NODE_PSYMBOL (" exchange" );
484+ priority_symbol = NODE_PSYMBOL (" priority" );
485+ weight_symbol = NODE_PSYMBOL (" weight" );
486+ port_symbol = NODE_PSYMBOL (" port" );
487+ name_symbol = NODE_PSYMBOL (" name" );
488+
315489 target->Set (String::NewSymbol (" TEMPFAIL" ), Integer::New (DNS_E_TEMPFAIL));
316490 target->Set (String::NewSymbol (" PROTOCOL" ), Integer::New (DNS_E_PROTOCOL));
317491 target->Set (String::NewSymbol (" NXDOMAIN" ), Integer::New (DNS_E_NXDOMAIN));
@@ -325,6 +499,15 @@ void DNS::Initialize(Handle<Object> target) {
325499 Local<FunctionTemplate> resolve6 = FunctionTemplate::New (ResolveA6);
326500 target->Set (String::NewSymbol (" resolve6" ), resolve6->GetFunction ());
327501
502+ Local<FunctionTemplate> resolveMx = FunctionTemplate::New (ResolveMX);
503+ target->Set (String::NewSymbol (" resolveMx" ), resolveMx->GetFunction ());
504+
505+ Local<FunctionTemplate> resolveTxt = FunctionTemplate::New (ResolveTXT);
506+ target->Set (String::NewSymbol (" resolveTxt" ), resolveTxt->GetFunction ());
507+
508+ Local<FunctionTemplate> resolveSrv = FunctionTemplate::New (ResolveSRV);
509+ target->Set (String::NewSymbol (" resolveSrv" ), resolveSrv->GetFunction ());
510+
328511 Local<FunctionTemplate> reverse = FunctionTemplate::New (Reverse);
329512 target->Set (String::NewSymbol (" reverse" ), reverse->GetFunction ());
330513}
0 commit comments