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;