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

📄 chlookup.c

📁 早期freebsd实现
💻 C
字号:
/* $Header: CHlookup.c,v 2.4 87/03/14 06:41:56 jqj Exp $ *//* contains: * CH_LookupAddr * CH_GetFirstCH * CH_GetOtherCH *//* $Log:	CHlookup.c,v $ * Revision 2.4  87/03/14  06:41:56  jqj * major changes to CH location algorithm. * changed LookupAddressDN to use new simpler semantics (can call GetOtherCH * many times) *  * Revision 2.3  87/01/05  11:58:47  ed * Webster changes *  * Revision 2.3  87/01/05  11:58:47  ed * Eliminate hard file name for BFS and use BFS definition instead *  * Revision 2.2  86/06/30  12:23:48  jqj * 1/ convert BDT read to dynamically allocate a buffer, and grow it if * necessary using realloc().  This should fix problems with support at * Xerox, where they have so many CHes that we were running out of space. * 2/ convert CH_GetFirstCH() to use /usr/new/xnsbfs if CH.default fails * to find a CH.  xnsbfs does an expanding ring, or at least a local, * broadcast for servers. *  * Revision 2.1  86/06/05  09:12:48  jqj * Split out CHdefault.c from this file.  The path to the addresses file * is now found in that file. *  * Revision 2.0  85/11/21  07:22:32  jqj * 4.3BSD standard release *  * Revision 1.3  85/11/21  07:14:19  jqj * first try at 4.3BSD standard release *  * Revision 1.2  85/10/21  12:41:55  jqj * Gould version:  work around a Gould compiler bug.  Default to /usr/new * for consistency. *  * Revision 1.1  85/10/18  09:14:53  jqj * Initial revision *  * Revision 1.1  85/03/26  06:27:00  jqj * Initial revision *  */#include <stdio.h>#include <sys/types.h>#include <netns/ns.h>#include <xnscourier/Clearinghouse2.h>#include <xnscourier/CHEntries.h>#include <xnscourier/except.h>#include <sys/file.h>#ifndef BFS#define BFS "/usr/new/xnsbfs"#endif/* data structures for very simple (null) authentication */static Cardinal nullpasswd = 0;static Clearinghouse2_Authenticator nullagent = {{0,{0,0}},{1,&nullpasswd}};/* * This is an entry in the in-core cache of known clearinghouses. * chl_name	Each entry has a name, which may be null for entries  *   obtained by expanding ring broadcast or initial table lookup.  A  *   particular address may appear in the list multiple times with  *   different or null names, but mostly the entries are unique. * chl_addr	The address is one of the addresses given for this  *   host.  For multihomed CHs, no attempt is made to make sure that  *   this address is optimal. * chl_status	The status of the entry, one of: *	chunknown	address invalid. *	chdown		did not answer when probed. *	chup		address valid, and responds to RetrieveAddresses. *	chused		has been returned to caller of GetCH routines *			as a valid CH.  Hence GetOtherCH will not return it  *			again.  Note that GetFirstCH resets chused->chup. * chl_next	Link to next clearinghouse in database. * chl_domains	[NOT YET USED] List of domains served, for efficiency */struct chlist {	Clearinghouse2_ObjectName *chl_name;	struct ns_addr chl_addr;	enum {chunknown, chup, chdown, chused} chl_status;	struct Clearinghouse2_TwoPartName *chl_domains;	struct chlist *chl_next;};struct chlist *namelist = NULL;/* * add a clearinghouse name to the ch list if it isn't already there. * Initial state is chunknown, since we don't know its address and can't * probe it. */static struct chlist *addtochlist(ch_name)	Clearinghouse2_ObjectName *ch_name;{	struct chlist *chptr;	extern char *malloc();	if (ch_name != NULL) /* don't eliminate duplicate anonymous entries */	    for (chptr = namelist; chptr != NULL; chptr = chptr->chl_next) {		if ( chptr->chl_name &&		    (strcmp(chptr->chl_name->object,ch_name->object)==0) &&		    (strcmp(chptr->chl_name->domain,ch_name->domain)==0) &&		    (strcmp(chptr->chl_name->organization,			    ch_name->organization)==0)) {			clear_Clearinghouse2_ObjectName(ch_name); /* dealloc */			return NULL;	/* already in list */		}	    }	chptr = (struct chlist *) malloc(sizeof(struct chlist));	chptr->chl_name = ch_name;	chptr->chl_status = chunknown;	chptr->chl_next = namelist;	namelist = chptr;	return chptr;}staticGetData(conn)	CourierConnection *conn;{	int count, i;	int bufused, bufsize;	Unspecified *buffer, *bp;	Clearinghouse2_StreamOfObjectName obnames;		bufsize = MAXWORDS*4;    /* end of available space */	buffer = Allocate(bufsize);	bufused = 0;		/* number of words used */	while (count = BDTread(conn, (char*)(buffer+bufused), 				MAXWORDS*sizeof(Unspecified))		) {		bufused += count/sizeof(Unspecified);		/* leave room for one last packet */		if (bufused+MAXWORDS > bufsize) {			bufsize += bufsize;	/* double our space */			buffer = (Unspecified *) realloc((char *) buffer,						bufsize*sizeof(Unspecified));		}	}	bp = buffer;	while (bp-buffer < bufused) {		bp += internalize_Clearinghouse2_StreamOfObjectName(&obnames,bp);		if (0 == (int) obnames.designator) {		   for (i = 0; i < obnames.nextSegment_case.segment.length; i++)			addtochlist(				&obnames.nextSegment_case.segment.sequence[i]);		} else {		   for (i = 0; i < obnames.lastSegment_case.length; i++)			addtochlist(				&obnames.lastSegment_case.sequence[i]);		   Deallocate(buffer);		   return;		}	}	Deallocate(buffer);	return;}static struct ns_addr*itemtonsaddr(itemptr)	Clearinghouse2_Item *itemptr;	/* i.e. a sequence of Unspecified */{	static union {		struct ns_addr addr;		u_short shrt[6];	} result;	register int i;	register Unspecified *seq;	if (itemptr->length < 7)		return(0);	seq = itemptr->sequence +1;	/* itemptr->sequence[0] == number of addresses */	for (i = 0; i < 6; i++, seq++)		result.shrt[i] = ntohs(*seq);	return(&result.addr);}/* * Open an SPP connection to the address given as chaddr, then * check whether the CHS pointed to by conn is up.  If not, close * conn and return 0.  If so, return the connection. */static CourierConnection*ClearinghouseOpen(chaddr)	struct ns_addr chaddr;{	CourierConnection *conn;	Clearinghouse2_RetrieveAddressesResults raresult;	conn.x_port = 0;	if ((conn = CourierOpen(&chaddr)) == NULL)		return(conn);	DURING	    raresult = Clearinghouse2_RetrieveAddresses(conn,NULL);	HANDLER {	    CourierClose(conn);	    conn = NULL;	} END_HANDLER;	clear_Clearinghouse2_RetrieveAddressesResults(&raresult);	return(conn);}/* * path to look for the addresses file on * (I wish I'd picked a shorter name, so we could rendezvous in /etc. *  But long file names in /etc are very unpopular!). * This path is defined n CHdefault.c, and used by CH_NameDefault() */extern char *chaddrpath[];CourierConnection*CH_GetFirstCH(){	struct ns_addr chaddr;	extern struct ns_addr *getXNSaddr();	extern struct ns_addr ns_addr();	char buf[BUFSIZ];	CourierConnection *result;	FILE *chfile;	struct chlist *chptr;	int i;	result = (CourierConnection *) NULL;	/* first, look in the process cache */	for (chptr = namelist; chptr != NULL; chptr = chptr->chl_next) {		switch (chptr->chl_status) {		case chunknown:		case chdown:			break;		case chused:			chptr->chl_status = chup;		case chup:			if (result == NULL)				result = ClearinghouseOpen(chptr->chl_addr);		}	}	if (result) return(result);	/* Now, use hard-coded CH */	/* eventually we'll do an expanding-ring or something */	for (i = 0; chaddrpath[i] != NULL; i++) {		if ((chfile = fopen(chaddrpath[i],"r")) == NULL)			continue;		flock(fileno(chfile),LOCK_SH);		while (fgets(buf, BUFSIZ, chfile) != NULL)			if ((buf[0] != '#') &&			    (chaddr = ns_addr(buf),			     result = ClearinghouseOpen((chaddr)))) {				if ((chptr = addtochlist(NULL))) {					chptr->chl_addr = chaddr;					chptr->chl_status = chused;				}				flock(fileno(chfile),LOCK_UN);				fclose(chfile);				return(result);			}		flock(fileno(chfile),LOCK_UN);		fclose(chfile);		break;	/* don't look for other files */	}	/* try expanding-ring here -- this could be more efficient! */	if ((chfile = popen(BFS,"r")) != NULL) {		while (fgets(buf, BUFSIZ, chfile) != NULL)			if ((buf[0] != '#') &&			    (chaddr=ns_addr(buf),			     result = ClearinghouseOpen(chaddr))) {				if ((chptr = addtochlist(NULL))) {					chptr->chl_addr = chaddr;					chptr->chl_status = chused;				}				pclose(chfile);				return(result);			}		pclose(chfile);	}	return(result);}CourierConnection *CH_GetOtherCH(conn,hint)	CourierConnection *conn;	Clearinghouse2_ObjectName hint;{	struct ns_addr *ch2addr;	CourierConnection *ch2conn, *chresult;	Clearinghouse2_RetrieveItemResults riresult;	Clearinghouse2_RetrieveMembersResults rmresult;	struct chlist *chptr;	Clearinghouse2_Property clearinghouseNames = 3;	Clearinghouse2_Property clearinghouseAddresses = 4;	if (hint.object != NULL && *hint.object != '\0') {	    DURING		    /* get list of possible other clearinghouses */		    rmresult = Clearinghouse2_RetrieveMembers(conn, GetData, hint, 			    clearinghouseNames, BulkData1_immediateSink,			    nullagent);	    HANDLER {		    /* some race condition */		    return(NULL);	    } END_HANDLER;	    /* throw away the distinguished name, which we don't need */	    clear_Clearinghouse2_RetrieveMembersResults(&rmresult);	}	/* for each member of potentials list, probe it */	ch2conn = chresult = NULL;	for (chptr = namelist; chptr != NULL; chptr = chptr->chl_next) {	    switch (chptr->chl_status) {	    case chunknown:	/* a new entry, presumably */		/* get its address */		DURING			riresult = Clearinghouse2_RetrieveItem(conn, NULL, 				*(chptr->chl_name),				clearinghouseAddresses, nullagent);		HANDLER			break;	/* try next in namelist */		END_HANDLER;		chptr->chl_addr = *itemtonsaddr(&riresult.value);		clear_Clearinghouse2_RetrieveItemResults(&riresult);		chptr->chl_status = chdown;		/* fall through to: */	    case chdown:	/* check down CH to see if it has revived */		/* make sure the second CH is really there */		if ((ch2conn = ClearinghouseOpen(chptr->chl_addr))) {			chptr->chl_status = chup; /* we got it! */			if (chresult == NULL) {				chresult = ch2conn;				chptr->chl_status = chused;			}			else CourierClose(ch2conn);			ch2conn = NULL;		}		break;	    case chup:	    case chused:		break;	    } /* end of switch */	} /* inspect next in list */	/* 	 * if no new one, return an old one	 */	for (chptr= namelist; chptr && (chresult==NULL); chptr= chptr->chl_next) {		if (chptr->chl_status == chup) {		    chptr->chl_status =		    	(chresult=ClearinghouseOpen(chptr->chl_addr))					? chused : chdown;		}	}	return(chresult);}/* * Given a Clearinghouse three part name (possibly containing wild cards) * and the property number on which a NetworkAddress is expected to occur, * returns the ns_addr structure associated with that name. * Note that the ns_addr structure is statically allocated! * Resets pattern to be the distinguished name of the object found. */struct ns_addr *CH_LookupAddr(pattern,property)	Clearinghouse2_ObjectNamePattern pattern;	Clearinghouse2_Property property;{	struct ns_addr* CH_LookupAddrDN();	return(CH_LookupAddrDN(pattern,property,0,0));}/* * Lookup a clearinghouse address, returning the address and the * distinguished name of the object found. */struct ns_addr *CH_LookupAddrDN(pattern,property,distnamep,distnamelen)	Clearinghouse2_ObjectNamePattern pattern;	Clearinghouse2_Property property;	char *distnamep;	int distnamelen;{	struct ns_addr *chaddr, *resultaddr;	CourierConnection *conn, *ch2conn;	Clearinghouse2_ObjectName hint;		/* from WrongServer errors */	Clearinghouse2_RetrieveItemResults riresult;	int i;	if ((long) property <= 0) 	/* default to addressList i.e. 4 */		property = CHEntries0_addressList;	if (pattern.object == NULL ||	    pattern.domain == NULL ||	    pattern.organization == NULL)		return(NULL);			/* can't handle defaults */		if ((conn = CH_GetFirstCH()) == NULL) {		fprintf(stderr,"Can't open connection to local Clearinghouse\n");		exit(1);	}	/* ask our primary clearinghouse for the address of this thing */	for (i = 5; i > 0; i--) {	    DURING {		riresult = Clearinghouse2_RetrieveItem(conn, NULL,				pattern, property, nullagent);		i = -1;	    } HANDLER {		if (Exception.Code == REJECT_ERROR) {			fprintf(stderr,"Problem with CH.addrs.  CH rejected request\n");			hint.object = hint.domain = hint.organization = NULL;		}		else if (Exception.Code != Clearinghouse2_WrongServer) {			/* some random error */			hint.object = hint.domain = hint.organization = NULL;		}		else hint = CourierErrArgs(Clearinghouse2_WrongServerArgs, hint);		ch2conn = CH_GetOtherCH(conn, hint);		CourierClose(conn);		if (ch2conn == NULL) return(0);		conn = ch2conn;	    } END_HANDLER;	}	if (i >= 0) {	    return(0);	}	resultaddr = itemtonsaddr(&riresult.value);	if (distnamep != NULL &&	    distnamelen >= (2+strlen(riresult.distinguishedObject.object)+			    strlen(riresult.distinguishedObject.domain)+			    strlen(riresult.distinguishedObject.organization)))		strcpy(distnamep,CH_NameToString(riresult.distinguishedObject));	clear_Clearinghouse2_RetrieveItemResults(&riresult);	CourierClose(conn);	return(resultaddr);}

⌨️ 快捷键说明

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