On Thu, Nov 27, 2008 at 12:32:31PM +0100, Gregor Jasny wrote:
> Daniel Stenberg wrote:
> > * I would like to have the callback able to fail the operation by
> >   returning an error code
> >
> > * I would like the callback to work on both UDP and TCP sockets
> >
> > * I would like the callback to get some private context pointer passed in
> >   from the app as callbacks without any such so often will have to rely on
> >   global variables etc soon when they need app-specific data to work with.

Done. I've added the socket type (DGRAM/STREAM) to the callabck for
convenience. Strictly speaking, this information is available via
getsockopt().

Maybe you want to rename ares_set_socket_callback to match the new
option getter/setter scheme.

Cheers,
Gregor
? ChangeLog
? acountry
Index: ares.h
===================================================================
RCS file: /cvsroot/curl/curl/ares/ares.h,v
retrieving revision 1.42
diff -u -3 -p -r1.42 ares.h
--- ares.h	19 Nov 2008 15:16:16 -0000	1.42
+++ ares.h	27 Nov 2008 23:42:07 -0000
@@ -212,6 +212,8 @@ typedef void (*ares_host_callback)(void 
                                    struct hostent *hostent);
 typedef void (*ares_nameinfo_callback)(void *arg, int status, int timeouts,
                                        char *node, char *service);
+typedef int  (*ares_sock_create_callback)(ares_socket_t socket_fd,
+                                          int type, void *data);
 
 int ares_init(ares_channel *channelptr);
 int ares_init_options(ares_channel *channelptr, struct ares_options *options,
@@ -220,6 +222,9 @@ int ares_save_options(ares_channel chann
 void ares_destroy_options(struct ares_options *options);
 void ares_destroy(ares_channel channel);
 void ares_cancel(ares_channel channel);
+void ares_set_socket_callback(ares_channel channel,
+                              ares_sock_create_callback callback,
+                              void *user_data);
 void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen,
                ares_callback callback, void *arg);
 void ares_query(ares_channel channel, const char *name, int dnsclass,
Index: ares_init.c
===================================================================
RCS file: /cvsroot/curl/curl/ares/ares_init.c,v
retrieving revision 1.82
diff -u -3 -p -r1.82 ares_init.c
--- ares_init.c	25 Nov 2008 16:26:58 -0000	1.82
+++ ares_init.c	27 Nov 2008 23:42:07 -0000
@@ -159,6 +159,8 @@ int ares_init_options(ares_channel *chan
   channel->servers = NULL;
   channel->sock_state_cb = NULL;
   channel->sock_state_cb_data = NULL;
+  channel->sock_create_cb = NULL;
+  channel->sock_create_cb_data = NULL;
 
   channel->last_server = 0;
   channel->last_timeout_processed = (time_t)now.tv_sec;
@@ -1509,3 +1511,11 @@ unsigned short ares__generate_new_id(rc4
   ares__rc4(key, (unsigned char *)&r, sizeof(r));
   return r;
 }
+
+void ares_set_socket_callback(ares_channel channel,
+                              ares_sock_create_callback cb,
+                              void *data)
+{
+  channel->sock_create_cb = cb;
+  channel->sock_create_cb_data = data;
+}
Index: ares_private.h
===================================================================
RCS file: /cvsroot/curl/curl/ares/ares_private.h,v
retrieving revision 1.40
diff -u -3 -p -r1.40 ares_private.h
--- ares_private.h	25 Nov 2008 16:26:58 -0000	1.40
+++ ares_private.h	27 Nov 2008 23:42:07 -0000
@@ -294,6 +294,9 @@ struct ares_channeldata {
 
   ares_sock_state_cb sock_state_cb;
   void *sock_state_cb_data;
+
+  ares_sock_create_callback sock_create_cb;
+  void *sock_create_cb_data;
 };
 
 /* return true if now is exactly check time or later */
Index: ares_process.c
===================================================================
RCS file: /cvsroot/curl/curl/ares/ares_process.c,v
retrieving revision 1.71
diff -u -3 -p -r1.71 ares_process.c
--- ares_process.c	13 Nov 2008 18:56:56 -0000	1.71
+++ ares_process.c	27 Nov 2008 23:42:07 -0000
@@ -927,6 +927,17 @@ static int open_tcp_socket(ares_channel 
         }
     }
 
+  if (channel->sock_create_cb)
+    {
+      int err = channel->sock_create_cb(s, SOCK_STREAM,
+                                        channel->sock_create_cb_data);
+      if (err < 0)
+        {
+          closesocket(s);
+          return err;
+        }
+    }
+
   SOCK_STATE_CALLBACK(channel, s, 1, 0);
   server->tcp_buffer_pos = 0;
   server->tcp_socket = s;
@@ -967,6 +978,17 @@ static int open_udp_socket(ares_channel 
         }
     }
 
+  if (channel->sock_create_cb)
+    {
+      int err = channel->sock_create_cb(s, SOCK_DGRAM,
+                                        channel->sock_create_cb_data);
+      if (err < 0)
+        {
+          closesocket(s);
+          return err;
+        }
+    }
+
   SOCK_STATE_CALLBACK(channel, s, 1, 0);
 
   server->udp_socket = s;

Reply via email to