@@ -372,6 +372,69 @@ struct CaresAsyncData {
372
372
uv_async_t async_handle;
373
373
};
374
374
375
+ void SetupCaresChannel (Environment* env) {
376
+ struct ares_options options;
377
+ memset (&options, 0 , sizeof (options));
378
+ options.flags = ARES_FLAG_NOCHECKRESP;
379
+ options.sock_state_cb = ares_sockstate_cb;
380
+ options.sock_state_cb_data = env;
381
+
382
+ /* We do the call to ares_init_option for caller. */
383
+ int r = ares_init_options (env->cares_channel_ptr (),
384
+ &options,
385
+ ARES_OPT_FLAGS | ARES_OPT_SOCK_STATE_CB);
386
+
387
+ if (r != ARES_SUCCESS) {
388
+ ares_library_cleanup ();
389
+ return env->ThrowError (ToErrorCodeString (r));
390
+ }
391
+ }
392
+
393
+
394
+ /* *
395
+ * This function is to check whether current servers are fallback servers
396
+ * when cares initialized.
397
+ *
398
+ * The fallback servers of cares is [ "127.0.0.1" ] with no user additional
399
+ * setting.
400
+ */
401
+ void AresEnsureServers (Environment* env) {
402
+ /* if last query is OK or servers are set by user self, do not check */
403
+ if (env->cares_query_last_ok () || !env->cares_is_servers_default ()) {
404
+ return ;
405
+ }
406
+
407
+ ares_channel channel = env->cares_channel ();
408
+ ares_addr_node* servers = nullptr ;
409
+
410
+ ares_get_servers (channel, &servers);
411
+
412
+ /* if no server or multi-servers, ignore */
413
+ if (servers == nullptr ) return ;
414
+ if (servers->next != nullptr ) {
415
+ ares_free_data (servers);
416
+ env->set_cares_is_servers_default (false );
417
+ return ;
418
+ }
419
+
420
+ /* if the only server is not 127.0.0.1, ignore */
421
+ if (servers[0 ].family != AF_INET ||
422
+ servers[0 ].addr .addr4 .s_addr != htonl (INADDR_LOOPBACK)) {
423
+ ares_free_data (servers);
424
+ env->set_cares_is_servers_default (false );
425
+ return ;
426
+ }
427
+
428
+ ares_free_data (servers);
429
+ servers = nullptr ;
430
+
431
+ /* destroy channel and reset channel */
432
+ ares_destroy (channel);
433
+
434
+ SetupCaresChannel (env);
435
+ }
436
+
437
+
375
438
class QueryWrap : public AsyncWrap {
376
439
public:
377
440
QueryWrap (Environment* env, Local<Object> req_wrap_obj)
@@ -402,6 +465,13 @@ class QueryWrap : public AsyncWrap {
402
465
return static_cast <void *>(this );
403
466
}
404
467
468
+ static void AresQuery (Environment* env, const char * name,
469
+ int dnsclass, int type, ares_callback callback,
470
+ void * arg) {
471
+ AresEnsureServers (env);
472
+ ares_query (env->cares_channel (), name, dnsclass, type, callback, arg);
473
+ }
474
+
405
475
static void CaresAsyncClose (uv_handle_t * handle) {
406
476
uv_async_t * async = reinterpret_cast <uv_async_t *>(handle);
407
477
auto data = static_cast <struct CaresAsyncData *>(async->data );
@@ -453,6 +523,7 @@ class QueryWrap : public AsyncWrap {
453
523
async_handle,
454
524
CaresAsyncCb));
455
525
526
+ wrap->env ()->set_cares_query_last_ok (status != ARES_ECONNREFUSED);
456
527
async_handle->data = data;
457
528
uv_async_send (async_handle);
458
529
}
@@ -478,6 +549,7 @@ class QueryWrap : public AsyncWrap {
478
549
async_handle,
479
550
CaresAsyncCb));
480
551
552
+ wrap->env ()->set_cares_query_last_ok (status != ARES_ECONNREFUSED);
481
553
async_handle->data = data;
482
554
uv_async_send (async_handle);
483
555
}
@@ -522,12 +594,7 @@ class QueryAWrap: public QueryWrap {
522
594
}
523
595
524
596
int Send (const char * name) override {
525
- ares_query (env ()->cares_channel (),
526
- name,
527
- ns_c_in,
528
- ns_t_a,
529
- Callback,
530
- GetQueryArg ());
597
+ AresQuery (env (), name, ns_c_in, ns_t_a, Callback, GetQueryArg ());
531
598
return 0 ;
532
599
}
533
600
@@ -570,12 +637,7 @@ class QueryAaaaWrap: public QueryWrap {
570
637
}
571
638
572
639
int Send (const char * name) override {
573
- ares_query (env ()->cares_channel (),
574
- name,
575
- ns_c_in,
576
- ns_t_aaaa,
577
- Callback,
578
- GetQueryArg ());
640
+ AresQuery (env (), name, ns_c_in, ns_t_aaaa, Callback, GetQueryArg ());
579
641
return 0 ;
580
642
}
581
643
@@ -618,12 +680,7 @@ class QueryCnameWrap: public QueryWrap {
618
680
}
619
681
620
682
int Send (const char * name) override {
621
- ares_query (env ()->cares_channel (),
622
- name,
623
- ns_c_in,
624
- ns_t_cname,
625
- Callback,
626
- GetQueryArg ());
683
+ AresQuery (env (), name, ns_c_in, ns_t_cname, Callback, GetQueryArg ());
627
684
return 0 ;
628
685
}
629
686
@@ -659,12 +716,7 @@ class QueryMxWrap: public QueryWrap {
659
716
}
660
717
661
718
int Send (const char * name) override {
662
- ares_query (env ()->cares_channel (),
663
- name,
664
- ns_c_in,
665
- ns_t_mx,
666
- Callback,
667
- GetQueryArg ());
719
+ AresQuery (env (), name, ns_c_in, ns_t_mx, Callback, GetQueryArg ());
668
720
return 0 ;
669
721
}
670
722
@@ -710,12 +762,7 @@ class QueryNsWrap: public QueryWrap {
710
762
}
711
763
712
764
int Send (const char * name) override {
713
- ares_query (env ()->cares_channel (),
714
- name,
715
- ns_c_in,
716
- ns_t_ns,
717
- Callback,
718
- GetQueryArg ());
765
+ AresQuery (env (), name, ns_c_in, ns_t_ns, Callback, GetQueryArg ());
719
766
return 0 ;
720
767
}
721
768
@@ -748,12 +795,7 @@ class QueryTxtWrap: public QueryWrap {
748
795
}
749
796
750
797
int Send (const char * name) override {
751
- ares_query (env ()->cares_channel (),
752
- name,
753
- ns_c_in,
754
- ns_t_txt,
755
- Callback,
756
- GetQueryArg ());
798
+ AresQuery (env (), name, ns_c_in, ns_t_txt, Callback, GetQueryArg ());
757
799
return 0 ;
758
800
}
759
801
@@ -805,12 +847,7 @@ class QuerySrvWrap: public QueryWrap {
805
847
}
806
848
807
849
int Send (const char * name) override {
808
- ares_query (env ()->cares_channel (),
809
- name,
810
- ns_c_in,
811
- ns_t_srv,
812
- Callback,
813
- GetQueryArg ());
850
+ AresQuery (env (), name, ns_c_in, ns_t_srv, Callback, GetQueryArg ());
814
851
return 0 ;
815
852
}
816
853
@@ -861,12 +898,7 @@ class QueryPtrWrap: public QueryWrap {
861
898
}
862
899
863
900
int Send (const char * name) override {
864
- ares_query (env ()->cares_channel (),
865
- name,
866
- ns_c_in,
867
- ns_t_ptr,
868
- Callback,
869
- GetQueryArg ());
901
+ AresQuery (env (), name, ns_c_in, ns_t_ptr, Callback, GetQueryArg ());
870
902
return 0 ;
871
903
}
872
904
@@ -904,12 +936,7 @@ class QueryNaptrWrap: public QueryWrap {
904
936
}
905
937
906
938
int Send (const char * name) override {
907
- ares_query (env ()->cares_channel (),
908
- name,
909
- ns_c_in,
910
- ns_t_naptr,
911
- Callback,
912
- GetQueryArg ());
939
+ AresQuery (env (), name, ns_c_in, ns_t_naptr, Callback, GetQueryArg ());
913
940
return 0 ;
914
941
}
915
942
@@ -968,12 +995,7 @@ class QuerySoaWrap: public QueryWrap {
968
995
}
969
996
970
997
int Send (const char * name) override {
971
- ares_query (env ()->cares_channel (),
972
- name,
973
- ns_c_in,
974
- ns_t_soa,
975
- Callback,
976
- GetQueryArg ());
998
+ AresQuery (env (), name, ns_c_in, ns_t_soa, Callback, GetQueryArg ());
977
999
return 0 ;
978
1000
}
979
1001
@@ -1434,6 +1456,9 @@ static void SetServers(const FunctionCallbackInfo<Value>& args) {
1434
1456
1435
1457
delete[] servers;
1436
1458
1459
+ if (err == ARES_SUCCESS)
1460
+ env->set_cares_is_servers_default (false );
1461
+
1437
1462
args.GetReturnValue ().Set (err);
1438
1463
}
1439
1464
@@ -1468,20 +1493,7 @@ static void Initialize(Local<Object> target,
1468
1493
if (r != ARES_SUCCESS)
1469
1494
return env->ThrowError (ToErrorCodeString (r));
1470
1495
1471
- struct ares_options options;
1472
- memset (&options, 0 , sizeof (options));
1473
- options.flags = ARES_FLAG_NOCHECKRESP;
1474
- options.sock_state_cb = ares_sockstate_cb;
1475
- options.sock_state_cb_data = env;
1476
-
1477
- /* We do the call to ares_init_option for caller. */
1478
- r = ares_init_options (env->cares_channel_ptr (),
1479
- &options,
1480
- ARES_OPT_FLAGS | ARES_OPT_SOCK_STATE_CB);
1481
- if (r != ARES_SUCCESS) {
1482
- ares_library_cleanup ();
1483
- return env->ThrowError (ToErrorCodeString (r));
1484
- }
1496
+ SetupCaresChannel (env);
1485
1497
1486
1498
/* Initialize the timeout timer. The timer won't be started until the */
1487
1499
/* first socket is opened. */
0 commit comments