< Previous by Date Date Index Next by Date >
  Thread Index Next in Thread >

[reSIProcate] [Patch] Add support for AfterSocketCreationFuncPtr when using c-ares


Now that c-ares 1.6.0 supports socket creation callback functions, I
have added support for the AfterSocketCreationFuncPtr resiprocate
callback when using c-ares.

In detail:

 - Implemented AfterSocketCreationFuncPtr when using c-ares (requires
   1.6.0)

 - Added TODOs for supporting IPv6 DNS server addresses with c-ares
   (coming soon)

I tested with resiprocate-1.4.1 using c-ares-1.6.0 with and without an
AfterSocketCreationFuncPtr callback set using testDns.  The attached
patch applies against svn main.

BTW, sorry for getting the log messages backwards in my last patch.
   
-- 
----------------------------------------------------------
Brad Spencer - spencer@xxxxxxxxxxxxx - www.starscale.com
Index: rutil/dns/AresDns.cxx
===================================================================
--- rutil/dns/AresDns.cxx	(revision 8364)
+++ rutil/dns/AresDns.cxx	(working copy)
@@ -21,6 +21,25 @@
 
 #define RESIPROCATE_SUBSYSTEM resip::Subsystem::DNS
 
+namespace
+{
+   // When we're using c-ares, this is used to tie its socket creation
+   // callback to ours.  The data must be set to the
+   // AfterSocketCreationFuncPtr that we're chaining to (and can't be NULL).
+   int caresSocketCreationCallback(const ares_socket_t socket_fd,
+                                   const int type,
+                                   void * const data)
+   {
+      // We don't have the file and line from c-ares, but ours will do to
+      // identify that this is a c-ares DNS socket, which is probably enough.
+      reinterpret_cast<AfterSocketCreationFuncPtr>(data)(socket_fd, type,
+                                                         __FILE__, __LINE__);
+
+      // We can't fail, so say everything is okay
+      return ARES_SUCCESS;
+   }
+}
+
 int 
 AresDns::init(const std::vector<GenericIPAddress>& additionalNameservers,
               AfterSocketCreationFuncPtr socketfunc,
@@ -117,7 +136,8 @@
 #if defined(USE_ARES)
       status = ares_init_options_with_socket_function(channel, &opt, optmask, socketfunc);
 #elif defined(USE_CARES)
-      // TODO: Does the socket function matter?
+      // Initialize the channel, but set the socket creation callback later,
+      // once the status has been checked.
       status = ares_init_options(channel, &opt, optmask);
 #endif
    }
@@ -129,6 +149,8 @@
 #if defined(USE_IPV6) && defined(USE_ARES)
       // With contrib/ares, you can configure IPv6 addresses for the
       // nameservers themselves.
+      //
+      // TODO: Support IPv6 server addresses once c-ares does.
       opt.servers = new multiFamilyAddr[additionalNameservers.size()];
       for (size_t i =0; i < additionalNameservers.size(); i++)
       {
@@ -169,7 +191,8 @@
 #if defined(USE_ARES)
       status = ares_init_options_with_socket_function(channel, &opt, optmask, socketfunc);
 #elif defined(USE_CARES)
-      // TODO: Does the socket function matter?
+      // Again, initialize the channel, but set the socket creation callback
+      // later, once the status has been checked.
       status = ares_init_options(channel, &opt, optmask);
 #endif
       
@@ -205,6 +228,15 @@
 
 #elif defined(USE_CARES)
       {
+         // For c-ares, we can only set the socket creation callback once the
+         // channel has been created, so do it now that that's the case.  This
+         // can't fail.
+         if(socketfunc != NULL)
+         {
+            ares_set_socket_callback(*channel, caresSocketCreationCallback,
+                                     reinterpret_cast<void *>(socketfunc));
+         }
+         
          // Log which version of c-ares we're using
          InfoLog(<< "DNS initialization: using c-ares v"
                  << ::ares_version(NULL));
@@ -221,6 +253,8 @@
             // Log them all
             for (int i = 0; i < options.nservers; ++i)
             {
+               // TODO: Support logging IPv6 server addresses once c-ares
+               // supports that.
                InfoLog(<< " name server: "
                        << DnsUtil::inet_ntop(options.servers[i]));
             }

Attachment: signature.asc
Description: Digital signature