⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hostcache.c

📁 sock protocol ,it is useful!
💻 C
字号:
/* * Copyright (c) 1997, 1998, 1999 *      Inferno Nettverk A/S, Norway.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. The above copyright notice, this list of conditions and the following *    disclaimer must appear in all copies of the software, derivative works *    or modified versions, and any portions thereof, aswell as in all *    supporting documentation. * 2. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *      This product includes software developed by *      Inferno Nettverk A/S, Norway. * 3. The name of the author may not be used to endorse or promote products *    derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Inferno Nettverk A/S requests users of this software to return to * *  Software Distribution Coordinator  or  sdc@inet.no *  Inferno Nettverk A/S *  Oslo Research Park *  Gaustadal閑n 21 *  N-0349 Oslo *  Norway * * any improvements or extensions that they make and grant Inferno Nettverk A/S * the rights to redistribute these changes. * */#include "common.h"static const char rcsid[] ="$Id: hostcache.c,v 1.15 1999/12/22 09:29:24 karls Exp $";__BEGIN_DECLS#if SOCKS_SERVER/* we want the real thing. */#undef gethostbyname#undef gethostbyaddrstatic struct hostent *hostentupdate __P((struct hostent *old, const struct hostent *new));/* * Updates "old" with the contents of "new", freeing any * resources currently used by "old". * Returns: *		On success: "old", updated. *		On failure: NULL.*/static inthosthash __P((const char *name, size_t size));/* * Calculates a hashvalue for "name" and returns it's value. * Size of hashtable is given by "size".*/static intaddrhash __P((in_addr_t addr, size_t size));/* * Calculates a hashvalue for "addr" and returns it's value. * Size of hashtable is given by "size".*/#endif /* SOCKS_SERVER */static char **listrealloc __P((char ***old, const char ***new, int length));/* * Reallocates "old" and copies in the contents of "new". * The last element of both "old" and "new" must be NULL. * If "length" is less than 0, each element is assumed to * be NUL terminated, otherwise "length" gives the total length * of every string. * Returns: *		On success: "**old", with the contents of "new". *		On failure: NULL.*/__END_DECLSstruct hostent *hostentdup(hostent)	const struct hostent *hostent;{	static struct hostent dupedinit;	struct hostent *duped;	if ((duped = (struct hostent *)malloc(sizeof(*duped))) == NULL)		return NULL;	*duped = dupedinit;	if ((duped->h_name = strdup(hostent->h_name)) == NULL) {		hostentfree(duped);		return NULL;	}	if (listrealloc(&duped->h_aliases, (const char ***)&hostent->h_aliases, -1)	== NULL) {		hostentfree(duped);		return NULL;	}	duped->h_addrtype = hostent->h_addrtype;	duped->h_length	= hostent->h_length;	if (listrealloc(&duped->h_addr_list, (const char ***)&hostent->h_addr_list,	hostent->h_length) == NULL) {		hostentfree(duped);		return NULL;	}	return duped;}voidhostentfree(hostent)	struct hostent *hostent;{	char **p;	if (hostent == NULL)		return;	free(hostent->h_name);	hostent->h_name = NULL;	if (hostent->h_aliases != NULL)		for (p = hostent->h_aliases; *p != NULL; ++p)			free(*p);	free(hostent->h_aliases);	hostent->h_aliases = NULL;	if (hostent->h_addr_list != NULL)		for (p = hostent->h_addr_list; *p != NULL; ++p)			free(*p);	free(hostent->h_addr_list);	hostent->h_addr_list = NULL;	free(hostent);}static char **listrealloc(old, new, length)	char ***old;	const char ***new;	int length;{	int i, oldi, newi;	/* entries we can reallocate, starting at 0. */	oldi = 0;	if (*old != NULL)		while ((*old)[oldi] != NULL)			++oldi;	newi = 0;	while ((*new)[newi] != NULL)		++newi;	for (i = newi; i < oldi; ++i)		free((*old)[i]);	if ((*old = (char **)realloc(*old, sizeof(**new) * (newi + 1))) == NULL)		return NULL;	for (newi = 0; (*new)[newi] != NULL; ++newi, --oldi) {		if (((*old)[newi] = (char *)realloc(oldi > 0 ? (*old)[newi] : NULL,		length < 0 ? (strlen((*new)[newi]) + 1) : length)) == NULL)			return NULL;		if (length < 0)			strcpy((*old)[newi], (*new)[newi]);		else			memcpy((*old)[newi], (*new)[newi], (size_t)length);	}	(*old)[newi] = NULL;	return *old;}#if SOCKS_SERVERstruct hostent *cgethostbyname(name)	const char *name;{	const char *function = "cgethostbyname()";	static struct {		unsigned				allocated:1;		char					host[MAXHOSTNAMELEN];		time_t				written;		struct hostent		hostent;	} table[SOCKD_HOSTCACHE], *freehost;	static unsigned int hit, miss, count;	const time_t timenow = time(NULL);	const int hashi = hosthash(name, ELEMENTS(table));	size_t i;	struct hostent *hostent;#if SOCKD_CACHESTAT	if (++count % SOCKD_CACHESTAT == 0)		slog(LOG_INFO, "%s: hit: %d, miss: %d", function, hit, miss);#endif /* SOCKD_CACHESTAT */	for (i = hashi, freehost = NULL; i < ELEMENTS(table); ++i) {		if (!table[i].allocated) {			if (freehost == NULL)				freehost = &table[i];			continue;		}		if (strcasecmp(table[i].host, name) == 0) {			if (difftime(timenow, table[i].written) >= SOCKD_CACHETIMEOUT) {				freehost = &table[i];				break;			}			++hit;			return &table[i].hostent;		}	}	++miss;	if ((hostent = gethostbyname(name)) == NULL)		return NULL;	if (freehost == NULL)		for (i = hashi, freehost = &table[i]; i < ELEMENTS(table); ++i) {			if (difftime(timenow, table[i].written) >= SOCKD_CACHETIMEOUT) {				freehost = &table[i];				break;			}			if (freehost->written < table[i].written) {				freehost = &table[i]; /* oldest. */				break;			}		}	if (hostentupdate(&freehost->hostent, hostent) == NULL) {		freehost->allocated = 0;		slog(LOG_WARNING, "%s: %s", NOMEM, function);		return NULL;	}	SASSERTX(strlen(name) < sizeof(freehost->host));	strcpy(freehost->host, name);	time(&freehost->written);	freehost->allocated = 1;	return &freehost->hostent;}struct hostent *cgethostbyaddr(addr, len, type)	const char *addr;	int len;	int type;{	const char *function = "cgethostbyaddr()";	static struct {		unsigned			allocated:1;		in_addr_t			addr;		time_t				written;		struct hostent		hostent;	} table[SOCKD_ADDRESSCACHE], *freehost;	static unsigned long int hit, miss, count;	const time_t timenow = time(NULL);	/* LINTED pointer casts may be troublesome */	const int hashi	= addrhash(((const struct in_addr *)addr)->s_addr, ELEMENTS(table));	size_t i;	struct hostent *hostent;#if SOCKD_CACHESTAT	if (++count % SOCKD_CACHESTAT == 0)		slog(LOG_INFO, "%s: hit: %d, miss: %d", function, hit, miss);#endif /* SOCKD_CACHESTAT */	for (i = hashi, freehost = NULL; i < ELEMENTS(table); ++i) {		if (!table[i].allocated) {			if (freehost == NULL)				freehost = &table[i];			continue;		}		/* LINTED pointer casts may be troublesome */		if (table[i].addr == ((const struct in_addr *)addr)->s_addr) {			if (difftime(timenow, table[i].written) >= SOCKD_CACHETIMEOUT) {				freehost = &table[i];				break;			}			++hit;			return &table[i].hostent;		}	}	++miss;	if ((hostent = gethostbyaddr(addr, len, type)) == NULL)		return NULL;	if (freehost == NULL)		for (i = hashi, freehost = &table[i]; i < ELEMENTS(table); ++i) {			if (difftime(timenow, table[i].written) >= SOCKD_CACHETIMEOUT) {				freehost = &table[i];				break;			}			if (freehost->written < table[i].written) {				freehost = &table[i]; /* oldest. */				break;			}		}	if (hostentupdate(&freehost->hostent, hostent) == NULL) {		freehost->allocated = 0;		slog(LOG_WARNING, "%s: %s", NOMEM, function);		return NULL;	}	/* LINTED pointer casts may be troublesome */	freehost->addr = ((const struct in_addr *)addr)->s_addr;	time(&freehost->written);	freehost->allocated = 1;	return &freehost->hostent;}static inthosthash(name, size)	const char *name;	size_t size;{	char *end;	unsigned int value;	/* end at second dot. */	if ((end = strchr(name, '.')) != NULL)		end = strchr(end, '.');	if (end == NULL)		end = strchr(name, NUL);	SASSERTX(name <= end);	value = 0;	while (name != end)		value = (value << 5) + *name++;	/* MAW - DS&A: Horner's rule. */	return value % size;}static intaddrhash(addr, size)	in_addr_t addr;	size_t size;{	return addr % size;}static struct hostent *hostentupdate(old, new)	struct hostent *old;	const struct hostent *new;{	if ((old->h_name = (char *)realloc(old->h_name, strlen(new->h_name) + 1))	== NULL)		return NULL;	strcpy(old->h_name, new->h_name);	if (listrealloc(&old->h_aliases, (const char ***)&new->h_aliases, -1)	== NULL)		return NULL;	old->h_addrtype	= new->h_addrtype;	old->h_length		= new->h_length;	if (listrealloc(&old->h_addr_list, (const char ***)&new->h_addr_list,	new->h_length) == NULL)		return NULL;	return old;}#endif /* SOCKS_SERVER */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -