1
0
mirror of https://github.com/unrealircd/unrealircd.git synced 2026-07-01 09:46:40 +02:00

*nix resolver for Windows

This commit is contained in:
codemastr
2003-08-21 16:11:08 +00:00
parent bf156f47b6
commit a450522052
13 changed files with 411 additions and 452 deletions
+4
View File
@@ -2356,3 +2356,7 @@ seen. gmtime warning still there
and badword quit lists... could be useful :p.
- Little config.h cleanup (removed obsolete non-working defines).
- Allow opers to talk in channel even if +m (#0001109).
- Implemented the *nix resolver under windows. This should solve 90% of the problems that
exist in the Windows version. There may be some problems with the resolver that still
need to be worked out, however it should be much more stable than before. Some of this
code is based on the ircu Windows NT port by run.
-4
View File
@@ -371,11 +371,7 @@ extern void add_client_to_list(aClient *);
extern void checklist();
extern void remove_client_from_list(aClient *);
extern void initlists();
#ifndef _WIN32
extern struct hostent *get_res(char *);
#else
extern struct hostent *get_res(char *, long);
#endif
extern struct hostent *gethost_byaddr(char *, Link *);
extern struct hostent *gethost_byname(char *, Link *);
extern void flush_cache();
-9
View File
@@ -39,22 +39,13 @@ typedef struct reslist {
char *name;
struct reslist *next;
Link cinfo;
#ifndef _WIN32
struct hent he;
#else
struct hostent *he;
char locked;
#endif
} ResRQ;
typedef struct cache {
time_t expireat;
time_t ttl;
#ifndef _WIN32
struct hostent he;
#else
struct hostent *he;
#endif
struct cache *hname_next, *hnum_next, *list_next;
} aCache;
+6
View File
@@ -215,7 +215,12 @@ static const struct in6_addr in6addr_any = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
#define P_ECONNABORTED ECONNABORTED
#define P_ECONNRESET ECONNRESET
#define P_ENOTCONN ENOTCONN
#define P_EMSGSIZE EMSGSIZE
#else
/* WIN32 */
#define NETDB_INTERNAL -1 /* see errno */
#define NETDB_SUCCESS 0 /* no problem */
/* IO and Error portability macros */
#define READ_SOCK(fd, buf, len) recv((fd), (buf), (len), 0)
@@ -239,6 +244,7 @@ static const struct in6_addr in6addr_any = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
#define P_ECONNABORTED WSAECONNABORTED
#define P_ECONNRESET WSAECONNRESET
#define P_ENOTCONN WSAENOTCONN
#define P_EMSGSIZE WSAEMSGSIZE
#endif
#endif /* __sys_include__ */
+7 -1
View File
@@ -31,7 +31,7 @@ OBJ_FILES=SRC/CHANNEL.OBJ SRC/SEND.OBJ SRC/SOCKET.OBJ \
SRC/S_DEBUG.OBJ SRC/SUPPORT.OBJ SRC/LIST.OBJ \
SRC/S_ERR.OBJ SRC/PACKET.OBJ SRC/S_BSD.OBJ \
SRC/S_SERV.OBJ SRC/S_USER.OBJ SRC/WIN32GUI.OBJ \
SRC/VERSION.OBJ SRC/RES_INIT.OBJ \
SRC/VERSION.OBJ SRC/RES_INIT.OBJ SRC/RES_COMP.OBJ SRC/RES_MKQUERY.OBJ SRC/RES_SKIPNAME.OBJ \
SRC/S_KLINE.OBJ SRC/S_EXTRA.OBJ SRC/IRCSPRINTF.OBJ SRC/LUSERS.OBJ \
SRC/SCACHE.OBJ SRC/ALN.OBJ SRC/BADWORDS.OBJ SRC/WEBTV.OBJ SRC/RES.OBJ SRC/MODULES.OBJ \
SRC/S_SVS.OBJ SRC/EVENTS.OBJ SRC/UMODES.OBJ SRC/AUTH.OBJ SRC/CIDR.OBJ SRC/SSL.OBJ \
@@ -142,6 +142,12 @@ src/list.obj: src/list.c $(INCLUDES)
src/res.obj: src/res.c $(INCLUDES)
$(CC) $(CFLAGS) src/res.c
src/res_mkquery.obj: src/res_mkquery.c $(INCLUDES)
$(CC) $(CFLAGS) src/res_mkquery.c
src/res_skipname.obj: src/res_skipname.c $(INCLUDES)
$(CC) $(CFLAGS) src/res_skipname.c
src/s_bsd.obj: src/s_bsd.c $(INCLUDES)
$(CC) $(CFLAGS) src/s_bsd.c
+7 -1
View File
@@ -34,7 +34,7 @@ OBJ_FILES=SRC/CHANNEL.OBJ SRC/SEND.OBJ SRC/SOCKET.OBJ \
SRC/S_DEBUG.OBJ SRC/SUPPORT.OBJ SRC/LIST.OBJ \
SRC/S_ERR.OBJ SRC/PACKET.OBJ SRC/S_BSD.OBJ \
SRC/S_SERV.OBJ SRC/S_USER.OBJ SRC/WIN32GUI.OBJ \
SRC/VERSION.OBJ SRC/RES_INIT.OBJ \
SRC/VERSION.OBJ SRC/RES_INIT.OBJ SRC/RES_COMP.OBJ SRC/RES_MKQUERY.OBJ SRC/RES_SKIPNAME.OBJ \
SRC/S_KLINE.OBJ SRC/S_EXTRA.OBJ SRC/IRCSPRINTF.OBJ SRC/LUSERS.OBJ \
SRC/SCACHE.OBJ SRC/ALN.OBJ SRC/BADWORDS.OBJ SRC/WEBTV.OBJ SRC/RES.OBJ SRC/MODULES.OBJ \
SRC/S_SVS.OBJ SRC/EVENTS.OBJ SRC/UMODES.OBJ SRC/AUTH.OBJ SRC/CIDR.OBJ SRC/SSL.OBJ \
@@ -145,6 +145,12 @@ src/list.obj: src/list.c $(INCLUDES)
src/res.obj: src/res.c $(INCLUDES)
$(CC) $(CFLAGS) src/res.c
src/res_mkquery.obj: src/res_mkquery.c $(INCLUDES)
$(CC) $(CFLAGS) src/res_mkquery.c
src/res_skipname.obj: src/res_skipname.c $(INCLUDES)
$(CC) $(CFLAGS) src/res_skipname.c
src/s_bsd.obj: src/s_bsd.c $(INCLUDES)
$(CC) $(CFLAGS) src/s_bsd.c
+7 -1
View File
@@ -41,7 +41,7 @@ OBJ_FILES=SRC/CHANNEL.OBJ SRC/SEND.OBJ SRC/SOCKET.OBJ \
SRC/S_DEBUG.OBJ SRC/SUPPORT.OBJ SRC/LIST.OBJ \
SRC/S_ERR.OBJ SRC/PACKET.OBJ SRC/S_BSD.OBJ \
SRC/S_SERV.OBJ SRC/S_USER.OBJ SRC/WIN32GUI.OBJ \
SRC/VERSION.OBJ SRC/RES_INIT.OBJ \
SRC/VERSION.OBJ SRC/RES_INIT.OBJ SRC/RES_COMP.OBJ SRC/RES_MKQUERY.OBJ SRC/RES_SKIPNAME.OBJ \
SRC/S_KLINE.OBJ SRC/S_EXTRA.OBJ SRC/IRCSPRINTF.OBJ SRC/LUSERS.OBJ \
SRC/SCACHE.OBJ SRC/ALN.OBJ SRC/BADWORDS.OBJ SRC/WEBTV.OBJ SRC/RES.OBJ SRC/MODULES.OBJ \
SRC/S_SVS.OBJ SRC/EVENTS.OBJ SRC/UMODES.OBJ SRC/AUTH.OBJ SRC/CIDR.OBJ SRC/SSL.OBJ \
@@ -152,6 +152,12 @@ src/list.obj: src/list.c $(INCLUDES)
src/res.obj: src/res.c $(INCLUDES)
$(CC) $(CFLAGS) src/res.c
src/res_mkquery.obj: src/res_mkquery.c $(INCLUDES)
$(CC) $(CFLAGS) src/res_mkquery.c
src/res_skipname.obj: src/res_skipname.c $(INCLUDES)
$(CC) $(CFLAGS) src/res_skipname.c
src/s_bsd.obj: src/s_bsd.c $(INCLUDES)
$(CC) $(CFLAGS) src/s_bsd.c
+7 -1
View File
@@ -36,7 +36,7 @@ OBJ_FILES=SRC/CHANNEL.OBJ SRC/SEND.OBJ SRC/SOCKET.OBJ \
SRC/S_DEBUG.OBJ SRC/SUPPORT.OBJ SRC/LIST.OBJ \
SRC/S_ERR.OBJ SRC/PACKET.OBJ SRC/S_BSD.OBJ \
SRC/S_SERV.OBJ SRC/S_USER.OBJ SRC/WIN32GUI.OBJ \
SRC/VERSION.OBJ SRC/RES_INIT.OBJ \
SRC/VERSION.OBJ SRC/RES_INIT.OBJ SRC/RES_COMP.OBJ SRC/RES_MKQUERY.OBJ SRC/RES_SKIPNAME.OBJ \
SRC/S_KLINE.OBJ SRC/S_EXTRA.OBJ SRC/IRCSPRINTF.OBJ SRC/LUSERS.OBJ \
SRC/SCACHE.OBJ SRC/ALN.OBJ SRC/BADWORDS.OBJ SRC/WEBTV.OBJ SRC/RES.OBJ SRC/MODULES.OBJ \
SRC/S_SVS.OBJ SRC/EVENTS.OBJ SRC/UMODES.OBJ SRC/AUTH.OBJ SRC/CIDR.OBJ SRC/SSL.OBJ \
@@ -147,6 +147,12 @@ src/list.obj: src/list.c $(INCLUDES)
src/res.obj: src/res.c $(INCLUDES)
$(CC) $(CFLAGS) src/res.c
src/res_mkquery.obj: src/res_mkquery.c $(INCLUDES)
$(CC) $(CFLAGS) src/res_mkquery.c
src/res_skipname.obj: src/res_skipname.c $(INCLUDES)
$(CC) $(CFLAGS) src/res_skipname.c
src/s_bsd.obj: src/s_bsd.c $(INCLUDES)
$(CC) $(CFLAGS) src/s_bsd.c
+34 -379
View File
@@ -40,26 +40,13 @@ static char rcsid[] = "@(#)$Id$";
#if 0
#undef DEBUG /* because there is a lot of debug code in here :-) */
#endif
#ifdef _WIN32
#define HE(x) (x)->he
#else
#define HE(x) (&((x)->he))
#endif
static char hostbuf[HOSTLEN + 1 + 100]; /* +100 for INET6 */
static char dot[] = ".";
static int incache = 0;
static CacheTable hashtable[ARES_CACSIZE];
static aCache *cachetop = NULL;
static ResRQ *last, *first;
/* control access to request queue - allow only one thread at a time.
** Currently the list is only protected on Windows because we don't use
** threads to access it on Unix
*/
#ifdef _WIN32
static MUTEX g_hResMutex;
#endif
static int lock_request();
static int unlock_request();
static void rem_cache(aCache *);
static void rem_request(ResRQ *);
@@ -79,14 +66,9 @@ static int hash_number(unsigned char *);
static void update_list(ResRQ *, aCache *);
static int hash_name(char *);
static int bad_hostname(char *, int);
#ifdef _WIN32
static void async_dns(void *parm);
#endif
#define CLI_HASH_VALUE local[tcc % 256]
#ifndef _WIN32
extern TS nextexpire;
#endif
static struct cacheinfo {
int ca_adds;
@@ -117,16 +99,6 @@ int init_resolver(int op)
{
int ret = 0;
#ifdef _WIN32
IRCCreateMutex(g_hResMutex);
if (g_hResMutex == NULL)
{
ircd_log(LOG_ERROR, "IRCCreateMutex failed: %s:%i. %s",
__FILE__, __LINE__,strerror(GetLastError()));
return ret;
}
#endif
if (op & RES_INITLIST)
{
bzero((char *)&reinfo, sizeof(reinfo));
@@ -154,7 +126,6 @@ int init_resolver(int op)
if (op & RES_INITSOCK)
{
#ifndef _WIN32
int on = 0;
#ifdef INET6
@@ -164,7 +135,6 @@ int init_resolver(int op)
ret = resfd = socket(AF_INET, SOCK_DGRAM, 0);
#endif
(void)setsockopt(ret, SOL_SOCKET, SO_BROADCAST, &on, on);
#endif
}
#ifdef DEBUGMODE
if (op & RES_INITDEBG)
@@ -180,54 +150,10 @@ int init_resolver(int op)
return ret;
}
/* get access to resolver request queue */
static int lock_request()
{
int iRc = 1;
#ifdef _WIN32
DWORD dwWaitRes;
if (g_hResMutex)
{
dwWaitRes = IRCMutexLock(g_hResMutex);
if (dwWaitRes != WAIT_OBJECT_0)
{
ircd_log(LOG_ERROR, "IRCMutexLock failed with %d: %s:%i. %s",
dwWaitRes, __FILE__, __LINE__,strerror(GetLastError()));
iRc = 0;
}
}
#endif
return iRc;
}
/* release access to resolver request queue */
static int unlock_request()
{
int iRc = 1;
#ifdef _WIN32
BOOL bRc;
if (g_hResMutex)
{
bRc = IRCMutexUnlock(g_hResMutex);
if (!bRc)
{
ircd_log(LOG_ERROR, "IRCMutexUnlock failed: %s:%i. %s",
__FILE__, __LINE__,strerror(GetLastError()));
iRc = 0;
}
}
#endif
return iRc;
}
static int add_request(ResRQ *new)
{
if (!new)
return -1;
lock_request();
if (!first)
first = last = new;
else
@@ -237,7 +163,6 @@ static int add_request(ResRQ *new)
}
new->next = NULL;
reinfo.re_requests++;
unlock_request();
return 0;
}
@@ -254,14 +179,6 @@ static void rem_request(ResRQ *old)
if (!old)
return;
#ifdef _WIN32
/* don't remove if async_dns() thread is running because it needs this memory
** we should consider terminating the thread here esp.
** if exit_client() called us
*/
if (old->locked)
return;
#endif
for (rptr = &first; *rptr; r2ptr = *rptr, rptr = &(*rptr)->next)
if (*rptr == old)
{
@@ -274,16 +191,11 @@ static void rem_request(ResRQ *old)
Debug((DEBUG_INFO, "rem_request:Remove %#x at %#x %#x", old, *rptr, r2ptr));
#endif
r2ptr = old;
#ifndef _WIN32
if (r2ptr->he.h_name)
MyFree(r2ptr->he.h_name);
for (i = 0; i < MAXALIASES; i++)
if ((s = r2ptr->he.h_aliases[i]))
MyFree(s);
#else
if (r2ptr->he)
MyFree(r2ptr->he);
#endif
if (r2ptr->name)
MyFree(r2ptr->name);
MyFree(r2ptr);
@@ -309,16 +221,9 @@ static ResRQ *make_request(Link *lp)
else
bzero((char *)&nreq->cinfo, sizeof(Link));
nreq->timeout = HOST_TIMEOUT; /* start at 4 and exponential inc. */
#ifndef _WIN32
nreq->he.h_addrtype = AFINET;
nreq->he.h_name = NULL;
nreq->he.h_aliases[0] = NULL;
#else
nreq->he = (struct hostent *)MyMalloc(MAXGETHOSTSTRUCT);
bzero((char *)nreq->he, MAXGETHOSTSTRUCT);
nreq->he->h_addrtype = AFINET;
nreq->he->h_name = NULL;
#endif
(void)add_request(nreq);
return nreq;
}
@@ -334,16 +239,11 @@ time_t timeout_query_list(time_t now)
aClient *cptr;
Debug((DEBUG_DNS, "timeout_query_list at %s", myctime(now)));
lock_request();
for (rptr = first; rptr; rptr = r2ptr)
{
r2ptr = rptr->next;
tout = rptr->sentat + rptr->timeout;
#ifndef _WIN32
if (now >= tout)
#else
if (now >= tout && !rptr->locked)
#endif
{
if (--rptr->retries <= 0)
{
@@ -373,9 +273,7 @@ time_t timeout_query_list(time_t now)
{
rptr->sentat = now;
rptr->timeout += rptr->timeout;
#ifndef _WIN32
resend_query(rptr);
#endif
tout = now + rptr->timeout;
#ifdef DEBUGMODE
Debug((DEBUG_INFO, "r %x now %d retry %d c %x",
@@ -387,7 +285,6 @@ time_t timeout_query_list(time_t now)
if (!next || tout < next)
next = tout;
}
unlock_request();
return (next > now) ? next : (now + AR_TTL);
}
@@ -399,14 +296,12 @@ void del_queries(char *cp)
{
ResRQ *rptr, *r2ptr;
lock_request();
for (rptr = first; rptr; rptr = r2ptr)
{
r2ptr = rptr->next;
if (cp == rptr->cinfo.value.cp)
rem_request(rptr);
}
unlock_request();
}
/*
@@ -416,7 +311,6 @@ void del_queries(char *cp)
* isnt present. Returns number of messages successfully sent to
* nameservers or -1 if no successful sends.
*/
#ifndef _WIN32
static int send_res_msg(char *msg, int len, int rcount)
{
#ifdef DEBUGMODE
@@ -469,7 +363,6 @@ static int send_res_msg(char *msg, int len, int rcount)
#else
ircd_res.nsaddr_list[i].sin_family = AF_INET;
#endif
ERRNO = 0;
#ifdef INET6
if (sendto(resfd, msg, len, 0,
(struct sockaddr *)&(ircd_res.nsaddr_list[i]),
@@ -487,12 +380,11 @@ static int send_res_msg(char *msg, int len, int rcount)
}
else
Debug((DEBUG_ERROR, "s_r_m:sendto: %d on %d",
errno, resfd));
ERRNO, resfd));
}
return (sent) ? sent : -1;
}
#endif
/*
* find a dns request id (id is determined by dn_mkquery)
@@ -501,11 +393,9 @@ static ResRQ *find_id(int id)
{
ResRQ *rptr;
lock_request();
for (rptr = first; rptr; rptr = rptr->next)
if (rptr->id == id)
break;
unlock_request();
return rptr;
}
@@ -515,11 +405,7 @@ struct hostent *gethost_byname(char *name, Link *lp)
reinfo.re_na_look++;
if ((cp = find_cache_name(name)))
#ifndef _WIN32
return (struct hostent *)&(cp->he);
#else
return (struct hostent *)cp->he;
#endif
if (!lp)
return NULL;
(void)do_query_name(lp, name, NULL);
@@ -532,11 +418,7 @@ struct hostent *gethost_byaddr(char *addr, Link *lp)
reinfo.re_nu_look++;
if ((cp = find_cache_number(NULL, addr)))
#ifndef _WIN32
return (struct hostent *)&(cp->he);
#else
return (struct hostent *)cp->he;
#endif
if (!lp)
return NULL;
(void)do_query_number(lp, (struct IN_ADDR *)addr, NULL);
@@ -545,7 +427,6 @@ struct hostent *gethost_byaddr(char *addr, Link *lp)
static int do_query_name(Link *lp, char *name, ResRQ *rptr)
{
#ifndef _WIN32
char hname[HOSTLEN + 1];
int len;
@@ -559,7 +440,6 @@ static int do_query_name(Link *lp, char *name, ResRQ *rptr)
(void)strncat(hname, ircd_res.defdname,
sizeof(hname) - len - 1);
}
#endif
/*
* Store the name passed as the one to lookup and generate other host
@@ -577,17 +457,11 @@ static int do_query_name(Link *lp, char *name, ResRQ *rptr)
(void)strcpy(rptr->name, name);
}
Debug((DEBUG_DNS, "do_query_name(): %s ", hname));
#ifndef _WIN32
#ifdef INET6
return (query_name(hname, C_IN, T_ANY, rptr)); /* Was T_AAAA: now using T_ANY so we fetch both A and AAAA -- Syzop */
#else
return (query_name(hname, C_IN, T_A, rptr));
#endif
#else
rptr->id = _beginthread(async_dns, 0, (void *)rptr);
rptr->sends++;
return 0;
#endif
}
/*
@@ -597,7 +471,6 @@ static int do_query_number(Link *lp, struct IN_ADDR *numb, ResRQ *rptr)
{
char ipbuf[128];
u_char *cp;
#ifndef _WIN32
#ifdef INET6
cp = (u_char *)&numb->s6_addr;
if (cp[0] == 0 && cp[1] == 0 && cp[2] == 0 && cp[3] == 0 && cp[4] == 0
@@ -640,7 +513,6 @@ static int do_query_number(Link *lp, struct IN_ADDR *numb, ResRQ *rptr)
cp = (u_char *)&numb->s_addr;
(void)ircsprintf(ipbuf, "%u.%u.%u.%u.in-addr.arpa.",
(u_int)(cp[3]), (u_int)(cp[2]), (u_int)(cp[1]), (u_int)(cp[0]));
#endif
#endif
Debug((DEBUG_DNS, "do_query_number: built %s rptr = %lx",
ipbuf, rptr));
@@ -649,7 +521,6 @@ static int do_query_number(Link *lp, struct IN_ADDR *numb, ResRQ *rptr)
{
rptr = make_request(lp);
rptr->type = T_PTR;
#ifndef _WIN32
#ifdef INET6
bcopy(numb->s6_addr, rptr->addr.s6_addr, IN6ADDRSZ);
bcopy((char *)numb->s6_addr,
@@ -660,31 +531,10 @@ static int do_query_number(Link *lp, struct IN_ADDR *numb, ResRQ *rptr)
(char *)&rptr->he.h_addr, sizeof(struct in_addr));
#endif
rptr->he.h_length = sizeof(struct IN_ADDR);
#else
#ifndef INET6
rptr->addr.S_ADDR = numb->S_ADDR;
#else
bcopy(numb->s6_addr, rptr->addr.s6_addr, IN6ADDRSZ);
#endif
rptr->he->h_length = sizeof(struct IN_ADDR);
/* rptr->addr.s_addr = numb->s_addr;
bcopy((char *)&numb->s_addr,
(char *)&rptr->he->h_addr, sizeof(struct in_addr));
rptr->he->h_length = sizeof(struct IN_ADDR);*/
#endif
}
#ifndef _WIN32
return (query_name(ipbuf, C_IN, T_PTR, rptr));
#else
rptr->id = _beginthread(async_dns, 0, (void *)rptr);
rptr->sends++;
return 0;
#endif
}
#ifndef _WIN32
/*
* generate a query based on class, type and name.
*/
@@ -701,10 +551,11 @@ static int query_name(char *name, int class, int type, ResRQ *rptr)
if (r <= 0)
{
Debug((DEBUG_DNS, "query_name: NO_RECOVERY"));
h_errno = NO_RECOVERY;
SET_ERRNO(NO_RECOVERY);
return r;
}
hptr = (HEADER *) buf;
#ifndef _WIN32
(void)gettimeofday(&tv, NULL);
do
{
@@ -720,6 +571,11 @@ static int query_name(char *name, int class, int type, ResRQ *rptr)
hptr->id = htons(nstmp);
k++;
}
#else
/* WIN32: actually this should be safe since it was seeded already */
hptr->id = htons(rand() & 0xffff);
#endif
while (find_id(ntohs(hptr->id)));
rptr->id = ntohs(hptr->id);
rptr->sends++;
@@ -727,7 +583,7 @@ static int query_name(char *name, int class, int type, ResRQ *rptr)
if (s == -1)
{
Debug((DEBUG_DNS, "query_name: TRY_AGAIN"));
h_errno = TRY_AGAIN;
SET_ERRNO(TRY_AGAIN);
return -1;
}
else
@@ -810,17 +666,13 @@ static int proc_answer(ResRQ *rptr, HEADER *hptr, char *buf, char *eob)
cp += 2; /* INT16SZ */
rptr->type = type;
len = strlen(hostbuf);
/* name server never returns with trailing '.' */
if (!index(hostbuf, '.') && (ircd_res.options & RES_DEFNAMES))
{
(void)strlcat(hostbuf, dot, sizeof hostbuf);
len++;
(void)strncat(hostbuf, ircd_res.defdname,
sizeof(hostbuf) - 1 - len);
len = MIN(len + strlen(ircd_res.defdname),
sizeof(hostbuf) - 1);
(void)strlcat(hostbuf, ircd_res.defdname, sizeof hostbuf);
}
len = strlen(hostbuf);
switch (type)
{
@@ -936,18 +788,11 @@ static int proc_answer(ResRQ *rptr, HEADER *hptr, char *buf, char *eob)
}
return ans;
}
#endif
/*
* read a dns reply from the nameserver and process it.
*/
#ifndef _WIN32
struct hostent *get_res(char *lp)
#else
struct hostent *get_res(char *lp,long id)
#endif
{
#ifndef _WIN32
static char buf[sizeof(HEADER) + MAXPACKET];
HEADER *hptr;
#ifdef INET6
@@ -957,14 +802,12 @@ struct hostent *get_res(char *lp,long id)
#endif
int rc, a, max;
SOCK_LEN_TYPE len = sizeof(sin);
#else
struct hostent *he;
#endif
ResRQ *rptr = NULL;
aCache *cp = NULL;
#ifndef _WIN32
(void)alarm((unsigned)4);
#endif
#ifdef INET6
rc = recvfrom(resfd, buf, sizeof(buf), 0, (struct sockaddr *)&sin,
&len);
@@ -972,8 +815,9 @@ struct hostent *get_res(char *lp,long id)
rc = recvfrom(resfd, buf, sizeof(buf), 0, (struct sockaddr *)&sin,
&len);
#endif
#ifndef _WIN32
(void)alarm((unsigned)0);
#endif
if (rc <= sizeof(HEADER))
goto getres_err;
/*
@@ -988,25 +832,18 @@ struct hostent *get_res(char *lp,long id)
#ifdef DEBUGMODE
Debug((DEBUG_NOTICE, "get_res:id = %d rcode = %d ancount = %d",
hptr->id, hptr->rcode, hptr->ancount));
#endif
#endif
reinfo.re_replies++;
/*
* response for an id which we have already received an answer for
* just ignore this response.
*/
lock_request();
#ifndef _WIN32
rptr = find_id(hptr->id);
#else
rptr = find_id(id);
#endif
if (!rptr)
goto getres_err;
/*
* check against possibly fake replies
*/
#ifndef _WIN32
max = MIN(ircd_res.nscount, rptr->sends);
if (!max)
max = 1;
@@ -1035,19 +872,19 @@ struct hostent *get_res(char *lp,long id)
switch (hptr->rcode)
{
case NXDOMAIN:
h_errno = TRY_AGAIN;
SET_ERRNO(TRY_AGAIN);
break;
case SERVFAIL:
h_errno = TRY_AGAIN;
SET_ERRNO(TRY_AGAIN);
break;
case NOERROR:
h_errno = NO_DATA;
SET_ERRNO(NO_DATA);
break;
case FORMERR:
case NOTIMP:
case REFUSED:
default:
h_errno = NO_RECOVERY;
SET_ERRNO(NO_RECOVERY);
break;
}
reinfo.re_errors++;
@@ -1055,10 +892,10 @@ struct hostent *get_res(char *lp,long id)
** If a bad error was returned, we stop here and dont send
** send any more (no retries granted).
*/
if (h_errno != TRY_AGAIN)
if (ERRNO != TRY_AGAIN)
{
Debug((DEBUG_DNS, "Fatal DNS error %d for %d",
h_errno, hptr->rcode));
ERRNO, hptr->rcode));
rptr->resend = 0;
rptr->retries = 0;
}
@@ -1135,7 +972,7 @@ struct hostent *get_res(char *lp,long id)
*/
if (rptr)
{
if (h_errno != TRY_AGAIN)
if (ERRNO != TRY_AGAIN)
{
/*
* If we havent tried with the default domain and its
@@ -1173,49 +1010,6 @@ struct hostent *get_res(char *lp,long id)
else if (lp)
bcopy((char *)&rptr->cinfo, lp, sizeof(Link));
}
#else
/* WIN32 */
he = rptr->he;
if (he && he->h_name && ((struct IN_ADDR *)he->h_addr)->S_ADDR &&
rptr->locked < 2)
{
/*
* We only need to re-check the DNS if its a "byaddr" call,
* the "byname" calls will work correctly. -Cabal95
*/
char tempname[120];
int i;
long amt;
struct hostent *hp, *he = rptr->he;
strlcpy(tempname, he->h_name, sizeof tempname);
hp = gethostbyname(tempname);
if (hp && !bcmp(hp->h_addr, he->h_addr, sizeof(struct IN_ADDR)))
{
}
else
rptr->he->h_name = NULL;
}
if (lp)
bcopy((char *)&rptr->cinfo, lp, sizeof(Link));
cp = make_cache(rptr);
# ifdef DEBUG
Debug((DEBUG_INFO,"get_res:cp=%#x rptr=%#x (made)", cp, rptr));
# endif
rptr->locked = 0;
rem_request(rptr);
unlock_request();
return cp ? (struct hostent *)cp->he : NULL;
getres_err:
if (lp && rptr)
bcopy((char *)&rptr->cinfo, lp, sizeof(Link));
unlock_request();
#endif
return (struct hostent *)NULL;
}
@@ -1339,7 +1133,6 @@ static void update_list(ResRQ *rptr, aCache *cachep)
*cpp = cp->list_next;
cp->list_next = cachetop;
cachetop = cp;
#ifndef _WIN32
if (!rptr)
return;
@@ -1446,7 +1239,6 @@ static void update_list(ResRQ *rptr, aCache *cachep)
bcopy(s, (char *)*--ab, sizeof(struct IN_ADDR));
}
}
#endif
return;
}
@@ -1584,17 +1376,12 @@ static aCache *make_cache(ResRQ *rptr)
/*
** shouldn't happen but it just might...
*/
#ifndef _WIN32
if (!rptr->he.h_name || !WHOSTENTP(rptr->he.h_addr.S_ADDR) )
#else
if (!rptr->he->h_name || !((struct IN_ADDR *)rptr->he->h_addr)->S_ADDR)
#endif
return NULL;
/*
** Make cache entry. First check to see if the cache already exists
** and if so, return a pointer to it.
*/
#ifndef _WIN32
for (i = 0; WHOSTENTP(rptr->he.h_addr_list[i].S_ADDR); i++)
if ((cp = find_cache_number(rptr,
#ifdef INET6
@@ -1603,25 +1390,12 @@ static aCache *make_cache(ResRQ *rptr)
(char *)&(rptr->he.h_addr_list[i].S_ADDR))))
#endif
return cp;
#else
for (i = 0; rptr->he->h_addr_list[i] &&
((struct IN_ADDR *)rptr->he->h_addr_list[i])->S_ADDR; i++)
if ((cp = find_cache_number(rptr,
(char *)&((struct IN_ADDR *)rptr->he->h_addr_list[i])->S_ADDR)))
return cp;
#endif
/*
** a matching entry wasnt found in the cache so go and make one up.
*/
cp = (aCache *)MyMalloc(sizeof(aCache));
bzero((char *)cp, sizeof(aCache));
#ifdef _WIN32
cp->he = (struct hostent *)MyMalloc(MAXGETHOSTSTRUCT);
res_copyhostent(rptr->he, cp->he);
#else
hp = &cp->he;
for (i = 0; i < MAXADDRS - 1; i++)
if (!WHOSTENTP(rptr->he.h_addr_list[i].S_ADDR))
@@ -1661,7 +1435,6 @@ static aCache *make_cache(ResRQ *rptr)
hp->h_addrtype = rptr->he.h_addrtype;
hp->h_length = rptr->he.h_length;
hp->h_name = rptr->he.h_name;
#endif
if (rptr->ttl < AR_TTL)
{
reinfo.re_shortttl++;
@@ -1670,7 +1443,6 @@ static aCache *make_cache(ResRQ *rptr)
else
cp->ttl = rptr->ttl;
cp->expireat = TStime() + cp->ttl;
#ifndef _WIN32
/* Update next dns cache clean time, this way it will be cleaned when needed.
* I don't know how to do multithreaded (win32), as a consequence it can take
* AR_TTL (300s) too much before we expire this entry at win32 -- Syzop
@@ -1679,7 +1451,6 @@ static aCache *make_cache(ResRQ *rptr)
nextexpire = cp->expireat;
Debug((DEBUG_DNS, "Adjusting nextexpire to %lu", nextexpire));
}
#endif
HE(rptr)->h_name = NULL;
#ifdef DEBUGMODE
Debug((DEBUG_INFO, "make_cache:made cache %#x", cp));
@@ -1716,11 +1487,7 @@ static aCache *rem_list(aCache *cp)
static void rem_cache(aCache *ocp)
{
aCache **cp;
#ifndef _WIN32
struct hostent *hp = &ocp->he;
#else
struct hostent *hp = ocp->he;
#endif
int hashv;
aClient *cptr;
@@ -1779,9 +1546,6 @@ static void rem_cache(aCache *ocp)
*cp = ocp->hnum_next;
break;
}
#ifdef _WIN32
MyFree(hp);
#else
/*
* free memory used to hold the various host names and the array
* of alias pointers.
@@ -1804,7 +1568,6 @@ static void rem_cache(aCache *ocp)
MyFree(*hp->h_addr_list);
MyFree(hp->h_addr_list);
}
#endif
MyFree(ocp);
incache--;
@@ -1898,6 +1661,19 @@ int m_dns(aClient *cptr, aClient *sptr, int parc, char *parv[])
}
return 2;
}
if (IsOper(sptr) && parv[1] && *parv[1] == 'i')
{
int i;
/* Display nameserver list */
sendto_one(sptr, "NOTICE %s :Nameserver list has %d server(s):", sptr->name, ircd_res.nscount);
for (i = 0; i < ircd_res.nscount; i++)
sendto_one(sptr, "NOTICE %s :%d. %s",
sptr->name, i, Inet_ia2pNB(&ircd_res.nsaddr_list[i].sin_addr, 0));
sendto_one(sptr, "NOTICE %s :retrans=%d s, retry=%d times", sptr->name, ircd_res.retrans, ircd_res.retry);
sendto_one(sptr, "NOTICE %s :Default domain name: %s", sptr->name, ircd_res.defdname);
sendto_one(sptr, "NOTICE %s :End of info.", sptr->name);
return 2;
}
sendto_one(sptr, "NOTICE %s :Ca %d Cd %d Ce %d Cl %d Ch %d:%d Cu %d",
sptr->name,
cainfo.ca_adds, cainfo.ca_dels, cainfo.ca_expires,
@@ -1923,11 +1699,7 @@ u_long cres_mem(aClient *sptr, char *nick)
for (; c; c = c->list_next)
{
sm += sizeof(*c);
#ifndef _WIN32
h = &c->he;
#else
h = c->he;
#endif
#ifdef INET6
for (i = 0; h->h_addr_list[i]; i++)
#else
@@ -1966,120 +1738,3 @@ static int bad_hostname(char *name, int len)
return -1;
return 0;
}
#ifdef _WIN32
/*
* Main thread function for handling DNS requests.
*/
void async_dns(void *parm)
{
ResRQ *rptr = (ResRQ *)parm;
struct hostent *hp, *he = rptr->he;
int i, x;
long amt;
if (rptr->type == T_A)
{
rptr->locked = 2;
hp = gethostbyname(rptr->name);
}
else
{
rptr->locked = 1;
hp = gethostbyaddr((char *)(&rptr->addr.S_ADDR), 4, PF_INET);
}
if ( !hp )
{
/*
* Now heres a stupid check to forget, this apprently is
* what hasbeen causing most of the crashes. I hope anyway.
*/
do_dns_async(rptr->id);
_endthread();
}
if ( (hp->h_aliases[0] && (hp->h_aliases[0]-(char *)hp)>MAXGETHOSTSTRUCT) ||
(hp->h_addr_list[0] && (hp->h_addr_list[0]-(char *)hp)>MAXGETHOSTSTRUCT))
{
/*
* Seems windows does some weird, aka stupid, stuff with DNS.
* If the address is resolved from the HOSTS file, then the
* pointers will exceed MAXGETHOSTSTRUCT. Good and bad. Good
* because its an easy way to tell if the Admin is spoofing
* with his HOSTS file, bad because it also causes invalid
* pointers without this check. -Cabal95
*/
do_dns_async(rptr->id);
_endthread();
}
res_copyhostent(hp, rptr->he);
do_dns_async(rptr->id);
_endthread();
}
int res_copyhostent(struct hostent *from, struct hostent *to)
{
int amt, x, i;
to->h_addrtype = from->h_addrtype;
to->h_length = from->h_length;
/*
* Get to "primary" offset in to hostent buffer and copy over
* to hostname.
*/
amt = (long)to + sizeof(struct hostent);
to->h_name = (char *)amt;
/*
* WIN32: FIXME: THIS LOOKS BAD
*/
strcpy(to->h_name, from->h_name);
amt += strlen(to->h_name)+1;
/* Setup tto alias list */
if (amt&0x3)
amt = (amt&0xFFFFFFFC)+4;
to->h_aliases = (char **)amt;
for (x = 0; from->h_aliases[x]; x++)
;
x *= sizeof(char *);
amt += sizeof(char *) + x;
for (i = 0; from->h_aliases[i]; i++)
{
to->h_aliases[i] = (char *)amt;
strcpy(to->h_aliases[i], from->h_aliases[i]);
amt += strlen(to->h_aliases[i])+1;
if (amt&0x3)
amt = (amt&0xFFFFFFFC)+4;
}
to->h_aliases[i] = NULL;
/* Setup tto IP address list */
to->h_addr_list = (char **)amt;
for (x = 0; from->h_addr_list[x]; x++)
;
x *= sizeof(char *);
amt += sizeof(char *) + x;
for (i = 0; from->h_addr_list[i]; i++)
{
to->h_addr_list[i] = (char *)amt;
#ifndef INET6
((struct IN_ADDR *)to->h_addr_list[i])->S_ADDR = ((struct IN_ADDR *)from->h_addr_list[i])->S_ADDR;
#else
bcopy(((struct IN_ADDR *)from->h_addr_list[i])->S_ADDR,((struct IN_ADDR *)to->h_addr_list[i])->S_ADDR, IN6ADDRSZ);
#endif
amt += sizeof(struct IN_ADDR); /* Prolly 4 */
}
to->h_addr_list[i] = NULL;
#ifdef WINDNSDEBUG
{
int aliascnt = 0, addrcnt = 0;
for (aliascnt = 0; from->h_aliases[aliascnt]; aliascnt++);
for (addrcnt = 0; from->h_addr_list[addrcnt]; addrcnt++);
ircd_log(LOG_ERROR, "resolver: amt=0x%x, to=0x%x, len=%d, max=%d [%d aliases, %d addrs]",
amt, to, (char *)amt - (char *)to, MAXGETHOSTSTRUCT, aliascnt, addrcnt);
}
#endif
if ((char *)amt + 4 > (char *)to + MAXGETHOSTSTRUCT)
ircd_log(LOG_ERROR, "resolver: overflow???");
return 1;
}
#endif /*_WIN32*/
+37 -37
View File
@@ -349,21 +349,21 @@ static int ns_name_ntop(const u_char *src, char *dst, size_t dstsiz)
if ((n & NS_CMPRSFLGS) != 0)
{
/* Some kind of compression pointer. */
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
if (dn != dst)
{
if (dn >= eom)
{
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
*dn++ = '.';
}
if (dn + n >= eom)
{
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
for ((void)NULL; n > 0; n--)
@@ -373,7 +373,7 @@ static int ns_name_ntop(const u_char *src, char *dst, size_t dstsiz)
{
if (dn + 1 >= eom)
{
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
*dn++ = '\\';
@@ -383,7 +383,7 @@ static int ns_name_ntop(const u_char *src, char *dst, size_t dstsiz)
{
if (dn + 3 >= eom)
{
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
*dn++ = '\\';
@@ -395,7 +395,7 @@ static int ns_name_ntop(const u_char *src, char *dst, size_t dstsiz)
{
if (dn >= eom)
{
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
*dn++ = (char)c;
@@ -406,14 +406,14 @@ static int ns_name_ntop(const u_char *src, char *dst, size_t dstsiz)
{
if (dn >= eom)
{
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
*dn++ = '.';
}
if (dn >= eom)
{
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
*dn++ = '\0';
@@ -452,20 +452,20 @@ static int ns_name_pton(const char *src, u_char *dst, size_t dstsiz)
if ((c = *src++) == 0 ||
(cp = strchr(digits, c)) == NULL)
{
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
n += (cp - digits) * 10;
if ((c = *src++) == 0 ||
(cp = strchr(digits, c)) == NULL)
{
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
n += (cp - digits);
if (n > 255)
{
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
c = n;
@@ -482,12 +482,12 @@ static int ns_name_pton(const char *src, u_char *dst, size_t dstsiz)
c = (bp - label - 1);
if ((c & NS_CMPRSFLGS) != 0)
{ /* Label too big. */
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
if (label >= eom)
{
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
*label = c;
@@ -498,21 +498,21 @@ static int ns_name_pton(const char *src, u_char *dst, size_t dstsiz)
{
if (bp >= eom)
{
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
*bp++ = '\0';
}
if ((bp - dst) > MAXCDNAME)
{
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
return (1);
}
if (c == 0)
{
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
label = bp++;
@@ -520,7 +520,7 @@ static int ns_name_pton(const char *src, u_char *dst, size_t dstsiz)
}
if (bp >= eom)
{
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
*bp++ = (u_char)c;
@@ -528,12 +528,12 @@ static int ns_name_pton(const char *src, u_char *dst, size_t dstsiz)
c = (bp - label - 1);
if ((c & NS_CMPRSFLGS) != 0)
{ /* Label too big. */
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
if (label >= eom)
{
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
*label = c;
@@ -541,14 +541,14 @@ static int ns_name_pton(const char *src, u_char *dst, size_t dstsiz)
{
if (bp >= eom)
{
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
*bp++ = 0;
}
if ((bp - dst) > MAXCDNAME)
{ /* src too big */
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
return (0);
@@ -573,7 +573,7 @@ static int ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *sr
dstlim = dst + dstsiz;
if (srcp < msg || srcp >= eom)
{
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
/* Fetch next label in domain name. */
@@ -586,7 +586,7 @@ static int ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *sr
/* Limit checks. */
if (dstp + n + 1 >= dstlim || srcp + n >= eom)
{
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
checked += n + 1;
@@ -599,7 +599,7 @@ static int ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *sr
case NS_CMPRSFLGS:
if (srcp >= eom)
{
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
if (len < 0)
@@ -607,7 +607,7 @@ static int ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *sr
srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
if (srcp < msg || srcp >= eom)
{ /* Out of range. */
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
checked += 2;
@@ -618,13 +618,13 @@ static int ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *sr
*/
if (checked >= eom - msg)
{
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
break;
default:
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1); /* flag error */
}
}
@@ -681,13 +681,13 @@ static int ns_name_pack(const u_char *src, u_char *dst, int dstsiz, const u_char
n = *srcp;
if ((n & NS_CMPRSFLGS) != 0)
{
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
l += n + 1;
if (l > MAXCDNAME)
{
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
srcp += n + 1;
@@ -707,7 +707,7 @@ static int ns_name_pack(const u_char *src, u_char *dst, int dstsiz, const u_char
{
if (dstp + 1 >= eob)
{
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
*dstp++ = (l >> 8) | NS_CMPRSFLGS;
@@ -725,12 +725,12 @@ static int ns_name_pack(const u_char *src, u_char *dst, int dstsiz, const u_char
/* copy label to buffer */
if (n & NS_CMPRSFLGS)
{ /* Should not happen. */
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
if (dstp + 1 + n >= eob)
{
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
memcpy(dstp, srcp, n + 1);
@@ -743,7 +743,7 @@ static int ns_name_pack(const u_char *src, u_char *dst, int dstsiz, const u_char
{
if (msg != NULL)
*lpp = NULL;
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
return (dstp - dst);
@@ -817,14 +817,14 @@ static int ns_name_skip(const u_char **ptrptr, const u_char *eom)
cp++;
break;
default: /* illegal type */
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
break;
}
if (cp > eom)
{
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
*ptrptr = cp;
@@ -925,13 +925,13 @@ static int dn_find(const u_char *domain, const u_char *msg, const u_char *const
break;
default: /* illegal type */
errno = EMSGSIZE;
SET_ERRNO(P_EMSGSIZE);
return (-1);
}
}
next:;
}
errno = ENOENT;
SET_ERRNO(ENOENT);
return (-1);
}
+301 -2
View File
@@ -151,11 +151,294 @@ struct __res_state ircd_res
* machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1"
* in the configuration file.
*
* Copied WIN32 specific code from ircu NT port :p.
*
* Return 0 if completes successfully, -1 on error
*/
#ifdef _WIN32
extern OSVERSIONINFO VerInfo;
void get_res_from_reg_9x()
{
register char *cp, **pp, *ap;
register int n;
HKEY hKey;
char buf[BUFSIZ];
int key_len = BUFSIZ;
int key_type;
ircd_res.nscount = 0;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\VxD\\MSTCP",
0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
{
Debug((DEBUG_DNS, "Error: get_res_from_reg_9x: unable to open registry key"));
return;
}
/* Retreive the Domain key */
if (RegQueryValueEx(hKey, "Domain", 0, &key_type, buf, &key_len) != ERROR_SUCCESS)
{
Debug((DEBUG_DNS, "get_res_from_reg_9x: RegQueryValueEx: Domain failed"));
}
else
strlcpy(ircd_res.defdname, buf, sizeof(ircd_res.defdname));
key_len = BUFSIZ;
/* Retreive the SearchList key */
if (RegQueryValueEx(hKey, "SearchList", 0, &key_type, buf, &key_len) != ERROR_SUCCESS)
{
Debug((DEBUG_DNS, "get_res_from_reg_9x: RegQueryValueEx: SearchList failed"));
}
else
{
cp = ircd_res.defdname;
pp = ircd_res.dnsrch;
*pp++ = cp;
for (n = 0; *cp && pp < ircd_res.dnsrch + MAXDNSRCH; cp++)
{
if (*cp == ',')
{
*cp = 0;
n = 1;
}
else if (n)
{
*pp++ = cp;
n = 0;
}
}
/* null terminate the last domain if there are excess */
while (*cp && *cp != ',')
++cp;
*cp = 0;
*pp++ = 0;
}
key_len = BUFSIZ;
/* Retreive the NameServer key */
if (RegQueryValueEx(hKey, "NameServer", 0, &key_type, buf, &key_len) != ERROR_SUCCESS)
{
Debug((DEBUG_DNS, "get_res_from_reg_9x: RegQueryValueEx: NameServer failed"));
}
else
{
struct in_addr a;
cp = ap = buf;
if (*buf != '\0')
{
do {
n = 0;
while (*cp && *cp != ',')
++cp;
if (*cp)
{
*cp = 0;
n = 1;
}
if (inet_addr(ap) != INADDR_NONE)
{
ircd_res.nsaddr_list[ircd_res.nscount].sin_addr.s_addr = inet_addr(ap);
ircd_res.nsaddr_list[ircd_res.nscount].sin_family = AF_INET;
ircd_res.nsaddr_list[ircd_res.nscount].sin_port = htons(NAMESERVER_PORT);
ircd_res.nscount++;
}
if (!n)
break;
ap = ++cp;
} while (ircd_res.nscount <= MAXNS);
}
}
RegCloseKey(hKey);
}
int get_res_nt(HKEY hKey, char *subkey, char *obuf, int *size)
{
if (RegQueryValueEx(hKey, subkey, 0, NULL, obuf, size) != ERROR_SUCCESS)
{
*size = 0;
return 0;
}
if (*size == 1)
{
*size = 0;
return 0;
}
return 1;
}
int get_res_interfaces_nt(HKEY hKey, char *subkey, char *obuf, int *size)
{
char buf[BUFSIZ];
int key_len = BUFSIZ;
int idx = 0;
FILETIME lastwrite;
HKEY hVal;
while (RegEnumKeyEx(hKey, idx++, buf, &key_len, 0, NULL, NULL, &lastwrite) != ERROR_NO_MORE_ITEMS)
{
if (RegOpenKeyEx(hKey, buf, 0, KEY_QUERY_VALUE, &hVal) != ERROR_SUCCESS)
continue;
key_len = BUFSIZ;
if (!get_res_nt(hVal, subkey, obuf, &key_len))
{
RegCloseKey(hVal);
key_len = BUFSIZ;
continue;
}
else
{
RegCloseKey(hVal);
*size = key_len;
return 1;
}
key_len = BUFSIZ;
}
*size = 0;
return 0;
}
void get_res_from_reg_nt()
{
register char *cp, **pp, *ap;
register int n;
HKEY hKey, hInter;
char buf[BUFSIZ];
int key_len = BUFSIZ;
ircd_res.nscount = 0;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\Tcpip\\Parameters",
0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
{
Debug((DEBUG_DNS, "Error: get_res_from_reg_nt: unable to open registry key"));
return;
}
RegOpenKeyEx(hKey, "Interfaces", 0, KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &hInter);
/* Retreive the Domain key */
if (!get_res_nt(hKey, "Domain", buf, &key_len))
{
key_len = BUFSIZ;
/* Try DHCP key */
if (!get_res_nt(hKey, "DhcpDomain", buf, &key_len))
{
key_len = BUFSIZ;
if (!get_res_interfaces_nt(hInter, "Domain", buf, &key_len))
{
key_len = BUFSIZ;
if (!get_res_interfaces_nt(hInter, "DhcpDomain", buf, &key_len))
{
Debug((DEBUG_DNS, "get_res_from_reg_nt: RegQueryValueEx: Domain failed"));
}
}
}
}
if (key_len > 0)
strlcpy(ircd_res.defdname, buf, sizeof(ircd_res.defdname));
/* Retreive the SearchList key */
key_len = BUFSIZ;
if (!get_res_nt(hKey, "SearchList", buf, &key_len))
{
key_len = BUFSIZ;
/* Try DHCP key */
if (!get_res_nt(hKey, "DhcpSearchList", buf, &key_len))
{
key_len = BUFSIZ;
if (!get_res_interfaces_nt(hInter, "SearchList", buf, &key_len))
{
key_len = BUFSIZ;
if (!get_res_interfaces_nt(hInter, "DhcpSearchList", buf, &key_len))
{
Debug((DEBUG_DNS, "get_res_from_reg_nt: RegQueryValueEx: SearchList failed"));
}
}
}
}
if (key_len > 0)
{
/*
* Set search list to be blank-separated strings
* on rest of line.
*/
cp = ircd_res.defdname;
pp = ircd_res.dnsrch;
*pp++ = cp;
for (n = 0; *cp && pp < ircd_res.dnsrch + MAXDNSRCH; cp++)
{
if (*cp == ' ' || *cp == '\t')
{
*cp = 0;
n = 1;
} else
if (n)
{
*pp++ = cp;
n = 0;
}
}
/* null terminate the last domain if there are excess */
while (*cp && *cp != ' ' && *cp != '\t')
++cp;
*cp = 0;
*pp++ = 0;
}
/* Retreive the NameServer key */
key_len = BUFSIZ;
if (!get_res_nt(hKey, "NameServer", buf, &key_len))
{
key_len = BUFSIZ;
/* Try DHCP key */
if (!get_res_nt(hKey, "DhcpNameServer", buf, &key_len))
{
key_len = BUFSIZ;
if (!get_res_interfaces_nt(hInter, "NameServer", buf, &key_len))
{
key_len = BUFSIZ;
if (!get_res_interfaces_nt(hInter, "NameServer", buf, &key_len))
{
Debug((DEBUG_DNS, "get_res_from_reg_nt: RegQueryValue: NameServer failed"));
}
}
}
}
if (key_len > 0)
{
struct in_addr a;
cp = ap = buf;
if (*buf != '\0')
{
do {
n = 0;
while (*cp && *cp != ' ' && *cp != '\t')
++cp;
if (*cp)
{
*cp = 0;
n = 1;
}
if (inet_addr(ap) != INADDR_NONE)
{
ircd_res.nsaddr_list[ircd_res.nscount].sin_addr.s_addr = inet_addr(ap);
ircd_res.nsaddr_list[ircd_res.nscount].sin_family = AF_INET;
ircd_res.nsaddr_list[ircd_res.nscount].sin_port = htons(NAMESERVER_PORT);
ircd_res.nscount++;
}
if (!n)
break;
ap = ++cp;
} while (ircd_res.nscount <= MAXNS);
}
}
RegCloseKey(hInter);
RegCloseKey(hKey);
}
#endif
int ircd_res_init(void)
{
#ifndef _WIN32
register FILE *fp;
#endif
register char *cp, **pp;
register int n;
char buf[MAXDNAME];
@@ -254,6 +537,7 @@ int ircd_res_init(void)
*pp++ = 0;
}
#ifndef _WIN32
#define MATCH(line, name) \
(!strncmp(line, name, sizeof(name) - 1) && \
(line[sizeof(name) - 1] == ' ' || \
@@ -262,7 +546,6 @@ int ircd_res_init(void)
#ifdef NEXT
if (ircd_netinfo_res_init(&haveenv, &havesearch) == 0)
#endif
#ifndef _WIN32
if ((fp = fopen(IRC_RESCONF, "r")) != NULL)
{
/* read the config file */
@@ -460,7 +743,14 @@ int ircd_res_init(void)
#endif
(void)fclose(fp);
}
#endif
#else /* WIN32-specific code follows: */
if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
get_res_from_reg_9x();
else if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
get_res_from_reg_nt();
#endif /* WIN32 */
if (ircd_res.defdname[0] == 0 &&
gethostname(buf, sizeof(ircd_res.defdname) - 1) == 0 &&
(cp = strchr(buf, '.')) != NULL)
@@ -502,6 +792,15 @@ int ircd_res_init(void)
if ((cp = getenv("RES_OPTIONS")) != NULL)
ircd_res_setoptions(cp, "env");
ircd_res.options |= RES_INIT;
#ifdef DEBUGMODE
{
int i;
Debug((DEBUG_DNS, "res_init: %d nameserver(s):", ircd_res.nscount));
for (i=0; i < ircd_res.nscount; i++)
Debug((DEBUG_DNS, "%d. %s", i, Inet_ia2pNB(&ircd_res.nsaddr_list[i].sin_addr, 0)));
}
#endif
return (0);
}
+1 -1
View File
@@ -89,7 +89,7 @@ const u_char *newrr_in, u_char *buf, int buflen)
if ((ircd_res.options & RES_INIT) == 0 && ircd_res_init() == -1)
{
h_errno = NETDB_INTERNAL;
SET_ERRNO(NETDB_INTERNAL);
return (-1);
}
#ifdef DEBUGMODE
-16
View File
@@ -112,12 +112,8 @@ static struct SOCKADDR_IN mysk;
static struct SOCKADDR *connect_inet(ConfigItem_link *, aClient *, int *);
int completed_connection(aClient *);
static int check_init(aClient *, char *, size_t);
#ifndef _WIN32
static void do_dns_async();
void set_sock_opts(int, aClient *);
#else
void set_sock_opts(int, aClient *);
#endif
static char readbuf[READBUF_SIZE];
char zlinebuf[BUFSIZE];
extern char *version;
@@ -1718,10 +1714,8 @@ int read_message(time_t delay, fdlist *listp)
}
}
#ifndef _WIN32
if (resfd >= 0)
FD_SET(resfd, &read_set);
#endif
if (me.fd >= 0)
FD_SET(me.fd, &read_set);
@@ -1751,7 +1745,6 @@ int read_message(time_t delay, fdlist *listp)
Sleep(10000);
#endif
}
#ifndef _WIN32
if (resfd >= 0 && FD_ISSET(resfd, &read_set))
{
Debug((DEBUG_DNS, "Doing DNS async.."));
@@ -1759,7 +1752,6 @@ int read_message(time_t delay, fdlist *listp)
nfds--;
FD_CLR(resfd, &read_set);
}
#endif
/*
* Check fd sets for the auth fd's (if set and valid!) first
* because these can not be processed using the normal loops below.
@@ -2552,11 +2544,7 @@ static struct SOCKADDR *connect_inet(ConfigItem_link *aconf, aClient *cptr, int
* reading.
*/
#ifndef _WIN32
static void do_dns_async(void)
#else
void do_dns_async(int id)
#endif
{
static Link ln;
aClient *cptr;
@@ -2568,11 +2556,7 @@ void do_dns_async(int id)
do {
ln.flags = -1;
#ifndef _WIN32
hp = get_res((char *)&ln);
#else
hp = get_res((char *)&ln, id);
#endif
Debug((DEBUG_DNS,"%#x = get_res(%d,%#x)", hp, ln.flags,
ln.value.cptr));