/* $Id$ */ /* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include <stdio.h> #include <sys/types.h> #if !defined(WIN32) || defined(WATT32) #include <netinet/in.h> /* We define closesocket() here so that we can use this function all over the source code for closing sockets. */ #define closesocket(x) close(x) #endif #ifdef WATT32 #include <tcp.h> #include <sys/ioctl.h> #undef closesocket #define closesocket(s) close_s(s) #define writev(s,v,c) writev_s(s,v,c) #endif #define DEFAULT_TIMEOUT 5 #define DEFAULT_TRIES 4 #ifndef INADDR_NONE #define INADDR_NONE 0xffffffff #endif #if defined(WIN32) && !defined(WATT32) #define IS_NT() ((int)GetVersion() > 0) #define WIN_NS_9X "System\\CurrentControlSet\\Services\\VxD\\MSTCP" #define WIN_NS_NT_KEY "System\\CurrentControlSet\\Services\\Tcpip\\Parameters" #define NAMESERVER "NameServer" #define DHCPNAMESERVER "DhcpNameServer" #define DATABASEPATH "DatabasePath" #define WIN_PATH_HOSTS "\\hosts" #elif defined(WATT32) #define PATH_RESOLV_CONF "/dev/ENV/etc/resolv.conf" #elif defined(NETWARE) #define PATH_RESOLV_CONF "sys:/etc/resolv.cfg" #define PATH_HOSTS "sys:/etc/hosts" #else #define PATH_RESOLV_CONF "/etc/resolv.conf" #ifdef ETC_INET #define PATH_HOSTS "/etc/inet/hosts" #else #define PATH_HOSTS "/etc/hosts" #endif #endif struct send_request { /* Remaining data to send */ const unsigned char *data; size_t len; /* Next request in queue */ struct send_request *next; }; struct server_state { struct in_addr addr; ares_socket_t udp_socket; ares_socket_t tcp_socket; /* Mini-buffer for reading the length word */ unsigned char tcp_lenbuf[2]; int tcp_lenbuf_pos; int tcp_length; /* Buffer for reading actual TCP data */ unsigned char *tcp_buffer; int tcp_buffer_pos; /* TCP output queue */ struct send_request *qhead; struct send_request *qtail; }; struct query { /* Query ID from qbuf, for faster lookup, and current timeout */ unsigned short qid; time_t timeout; /* Query buf with length at beginning, for TCP transmission */ unsigned char *tcpbuf; int tcplen; /* Arguments passed to ares_send() (qbuf points into tcpbuf) */ const unsigned char *qbuf; int qlen; ares_callback callback; void *arg; /* Query status */ int try; int server; int *skip_server; int using_tcp; int error_status; /* Next query in chain */ struct query *next; }; /* An IP address pattern; matches an IP address X if X & mask == addr */ struct apattern { struct in_addr addr; struct in_addr mask; }; struct ares_channeldata { /* Configuration data */ int flags; int timeout; int tries; int ndots; int udp_port; int tcp_port; char **domains; int ndomains; struct apattern *sortlist; int nsort; char *lookups; /* Server addresses and communications state */ struct server_state *servers; int nservers; /* ID to use for next query */ unsigned short next_id; /* Active queries */ struct query *queries; }; void ares__send_query(ares_channel channel, struct query *query, time_t now); void ares__close_sockets(struct server_state *server); int ares__get_hostent(FILE *fp, struct hostent **host); int ares__read_line(FILE *fp, char **buf, int *bufsize); #ifdef CURLDEBUG /* This is low-level hard-hacking memory leak tracking and similar. Using the libcurl lowlevel code from within library is ugly and only works when c-ares is built and linked with a similarly debug-build libcurl, but we do this anyway for convenience. */ #ifndef CURL_EXTERN /* ugly hack to make this compile */ #define CURL_EXTERN #endif #include "../lib/memdebug.h" #endif