Annotation of 43BSDTahoe/new/xns/morexnslib/ch/CHlookup.c.org, revision 1.1

1.1     ! root        1: /* $Header: CHlookup.c,v 2.4 87/03/14 06:41:56 jqj Exp $ */
        !             2: 
        !             3: /* contains:
        !             4:  * CH_LookupAddr
        !             5:  * CH_GetFirstCH
        !             6:  * CH_GetOtherCH
        !             7:  */
        !             8: 
        !             9: /* $Log:       CHlookup.c,v $
        !            10:  * Revision 2.4  87/03/14  06:41:56  jqj
        !            11:  * major changes to CH location algorithm.
        !            12:  * changed LookupAddressDN to use new simpler semantics (can call GetOtherCH
        !            13:  * many times)
        !            14:  * 
        !            15:  * Revision 2.3  87/01/05  11:58:47  ed
        !            16:  * Webster changes
        !            17:  * 
        !            18:  * Revision 2.3  87/01/05  11:58:47  ed
        !            19:  * Eliminate hard file name for BFS and use BFS definition instead
        !            20:  * 
        !            21:  * Revision 2.2  86/06/30  12:23:48  jqj
        !            22:  * 1/ convert BDT read to dynamically allocate a buffer, and grow it if
        !            23:  * necessary using realloc().  This should fix problems with support at
        !            24:  * Xerox, where they have so many CHes that we were running out of space.
        !            25:  * 2/ convert CH_GetFirstCH() to use /usr/new/xnsbfs if CH.default fails
        !            26:  * to find a CH.  xnsbfs does an expanding ring, or at least a local,
        !            27:  * broadcast for servers.
        !            28:  * 
        !            29:  * Revision 2.1  86/06/05  09:12:48  jqj
        !            30:  * Split out CHdefault.c from this file.  The path to the addresses file
        !            31:  * is now found in that file.
        !            32:  * 
        !            33:  * Revision 2.0  85/11/21  07:22:32  jqj
        !            34:  * 4.3BSD standard release
        !            35:  * 
        !            36:  * Revision 1.3  85/11/21  07:14:19  jqj
        !            37:  * first try at 4.3BSD standard release
        !            38:  * 
        !            39:  * Revision 1.2  85/10/21  12:41:55  jqj
        !            40:  * Gould version:  work around a Gould compiler bug.  Default to /usr/new
        !            41:  * for consistency.
        !            42:  * 
        !            43:  * Revision 1.1  85/10/18  09:14:53  jqj
        !            44:  * Initial revision
        !            45:  * 
        !            46:  * Revision 1.1  85/03/26  06:27:00  jqj
        !            47:  * Initial revision
        !            48:  * 
        !            49:  */
        !            50: #include <stdio.h>
        !            51: #include <sys/types.h>
        !            52: #include <netns/ns.h>
        !            53: #include <xnscourier/Clearinghouse2.h>
        !            54: #include <xnscourier/CHEntries.h>
        !            55: #include <xnscourier/except.h>
        !            56: #include <sys/file.h>
        !            57: 
        !            58: #ifndef BFS
        !            59: #define BFS "/usr/new/xnsbfs"
        !            60: #endif
        !            61: 
        !            62: /* data structures for very simple (null) authentication */
        !            63: static Cardinal nullpasswd = 0;
        !            64: static Clearinghouse2_Authenticator nullagent = {{0,{0,0}},{1,&nullpasswd}};
        !            65: 
        !            66: /*
        !            67:  * This is an entry in the in-core cache of known clearinghouses.
        !            68:  * chl_name    Each entry has a name, which may be null for entries 
        !            69:  *   obtained by expanding ring broadcast or initial table lookup.  A 
        !            70:  *   particular address may appear in the list multiple times with 
        !            71:  *   different or null names, but mostly the entries are unique.
        !            72:  * chl_addr    The address is one of the addresses given for this 
        !            73:  *   host.  For multihomed CHs, no attempt is made to make sure that 
        !            74:  *   this address is optimal.
        !            75:  * chl_status  The status of the entry, one of:
        !            76:  *     chunknown       address invalid.
        !            77:  *     chdown          did not answer when probed.
        !            78:  *     chup            address valid, and responds to RetrieveAddresses.
        !            79:  *     chused          has been returned to caller of GetCH routines
        !            80:  *                     as a valid CH.  Hence GetOtherCH will not return it 
        !            81:  *                     again.  Note that GetFirstCH resets chused->chup.
        !            82:  * chl_next    Link to next clearinghouse in database.
        !            83:  * chl_domains [NOT YET USED] List of domains served, for efficiency
        !            84:  */
        !            85: struct chlist {
        !            86:        Clearinghouse2_ObjectName *chl_name;
        !            87:        struct ns_addr chl_addr;
        !            88:        enum {chunknown, chup, chdown, chused} chl_status;
        !            89:        struct Clearinghouse2_TwoPartName *chl_domains;
        !            90:        struct chlist *chl_next;
        !            91: };
        !            92: struct chlist *namelist = NULL;
        !            93: 
        !            94: /*
        !            95:  * add a clearinghouse name to the ch list if it isn't already there.
        !            96:  * Initial state is chunknown, since we don't know its address and can't
        !            97:  * probe it.
        !            98:  */
        !            99: static struct chlist *
        !           100: addtochlist(ch_name)
        !           101:        Clearinghouse2_ObjectName *ch_name;
        !           102: {
        !           103:        struct chlist *chptr;
        !           104:        extern char *malloc();
        !           105: 
        !           106:        if (ch_name != NULL) /* don't eliminate duplicate anonymous entries */
        !           107:            for (chptr = namelist; chptr != NULL; chptr = chptr->chl_next) {
        !           108:                if ( chptr->chl_name &&
        !           109:                    (strcmp(chptr->chl_name->object,ch_name->object)==0) &&
        !           110:                    (strcmp(chptr->chl_name->domain,ch_name->domain)==0) &&
        !           111:                    (strcmp(chptr->chl_name->organization,
        !           112:                            ch_name->organization)==0)) {
        !           113:                        clear_Clearinghouse2_ObjectName(ch_name); /* dealloc */
        !           114:                        return NULL;    /* already in list */
        !           115:                }
        !           116:            }
        !           117:        chptr = (struct chlist *) malloc(sizeof(struct chlist));
        !           118:        chptr->chl_name = ch_name;
        !           119:        chptr->chl_status = chunknown;
        !           120:        chptr->chl_next = namelist;
        !           121:        namelist = chptr;
        !           122:        return chptr;
        !           123: }
        !           124: 
        !           125: static
        !           126: GetData(conn)
        !           127:        CourierConnection *conn;
        !           128: {
        !           129:        int count, i;
        !           130:        int bufused, bufsize;
        !           131:        Unspecified *buffer, *bp;
        !           132:        Clearinghouse2_StreamOfObjectName obnames;
        !           133:        
        !           134:        bufsize = MAXWORDS*4;    /* end of available space */
        !           135:        buffer = Allocate(bufsize);
        !           136:        bufused = 0;            /* number of words used */
        !           137:        while (count = BDTread(conn, (char*)(buffer+bufused), 
        !           138:                                MAXWORDS*sizeof(Unspecified))
        !           139:                ) {
        !           140:                bufused += count/sizeof(Unspecified);
        !           141:                /* leave room for one last packet */
        !           142:                if (bufused+MAXWORDS > bufsize) {
        !           143:                        bufsize += bufsize;     /* double our space */
        !           144:                        buffer = (Unspecified *) realloc((char *) buffer,
        !           145:                                                bufsize*sizeof(Unspecified));
        !           146:                }
        !           147:        }
        !           148:        bp = buffer;
        !           149:        while (bp-buffer < bufused) {
        !           150:                bp += internalize_Clearinghouse2_StreamOfObjectName(&obnames,bp);
        !           151:                if (0 == (int) obnames.designator) {
        !           152:                   for (i = 0; i < obnames.nextSegment_case.segment.length; i++)
        !           153:                        addtochlist(
        !           154:                                &obnames.nextSegment_case.segment.sequence[i]);
        !           155:                } else {
        !           156:                   for (i = 0; i < obnames.lastSegment_case.length; i++)
        !           157:                        addtochlist(
        !           158:                                &obnames.lastSegment_case.sequence[i]);
        !           159:                   Deallocate(buffer);
        !           160:                   return;
        !           161:                }
        !           162:        }
        !           163:        Deallocate(buffer);
        !           164:        return;
        !           165: }
        !           166: 
        !           167: static struct ns_addr*
        !           168: itemtonsaddr(itemptr)
        !           169:        Clearinghouse2_Item *itemptr;   /* i.e. a sequence of Unspecified */
        !           170: {
        !           171:        static union {
        !           172:                struct ns_addr addr;
        !           173:                u_short shrt[6];
        !           174:        } result;
        !           175:        register int i;
        !           176:        register Unspecified *seq;
        !           177: 
        !           178:        if (itemptr->length < 7)
        !           179:                return(0);
        !           180: 
        !           181:        seq = itemptr->sequence +1;
        !           182:        /* itemptr->sequence[0] == number of addresses */
        !           183:        for (i = 0; i < 6; i++, seq++)
        !           184:                result.shrt[i] = ntohs(*seq);
        !           185:        return(&result.addr);
        !           186: }
        !           187: 
        !           188: /*
        !           189:  * Open an SPP connection to the address given as chaddr, then
        !           190:  * check whether the CHS pointed to by conn is up.  If not, close
        !           191:  * conn and return 0.  If so, return the connection.
        !           192:  */
        !           193: static CourierConnection*
        !           194: ClearinghouseOpen(chaddr)
        !           195:        struct ns_addr chaddr;
        !           196: {
        !           197:        CourierConnection *conn;
        !           198:        Clearinghouse2_RetrieveAddressesResults raresult;
        !           199: 
        !           200:        if ((conn = CourierOpen(&chaddr)) == NULL)
        !           201:                return(conn);
        !           202:        DURING
        !           203:            raresult = Clearinghouse2_RetrieveAddresses(conn,NULL);
        !           204:        HANDLER {
        !           205:            CourierClose(conn);
        !           206:            conn = NULL;
        !           207:        } END_HANDLER;
        !           208:        clear_Clearinghouse2_RetrieveAddressesResults(&raresult);
        !           209:        return(conn);
        !           210: }
        !           211: 
        !           212: /*
        !           213:  * path to look for the addresses file on
        !           214:  * (I wish I'd picked a shorter name, so we could rendezvous in /etc.
        !           215:  *  But long file names in /etc are very unpopular!).
        !           216:  * This path is defined n CHdefault.c, and used by CH_NameDefault()
        !           217:  */
        !           218: extern char *chaddrpath[];
        !           219: 
        !           220: CourierConnection*
        !           221: CH_GetFirstCH()
        !           222: {
        !           223:        struct ns_addr chaddr;
        !           224:        extern struct ns_addr *getXNSaddr();
        !           225:        extern struct ns_addr ns_addr();
        !           226:        char buf[BUFSIZ];
        !           227:        CourierConnection *result;
        !           228:        FILE *chfile;
        !           229:        struct chlist *chptr;
        !           230:        int i;
        !           231: 
        !           232:        result = (CourierConnection *) NULL;
        !           233:        /* first, look in the process cache */
        !           234:        for (chptr = namelist; chptr != NULL; chptr = chptr->chl_next) {
        !           235:                switch (chptr->chl_status) {
        !           236:                case chunknown:
        !           237:                case chdown:
        !           238:                        break;
        !           239:                case chused:
        !           240:                        chptr->chl_status = chup;
        !           241:                case chup:
        !           242:                        if (result == NULL)
        !           243:                                result = ClearinghouseOpen(chptr->chl_addr);
        !           244:                }
        !           245:        }
        !           246:        if (result) return(result);
        !           247: 
        !           248:        /* Now, use hard-coded CH */
        !           249:        /* eventually we'll do an expanding-ring or something */
        !           250:        for (i = 0; chaddrpath[i] != NULL; i++) {
        !           251:                if ((chfile = fopen(chaddrpath[i],"r")) == NULL)
        !           252:                        continue;
        !           253:                flock(fileno(chfile),LOCK_SH);
        !           254:                while (fgets(buf, BUFSIZ, chfile) != NULL)
        !           255:                        if ((buf[0] != '#') &&
        !           256:                            (chaddr = ns_addr(buf),
        !           257:                             result = ClearinghouseOpen((chaddr)))) {
        !           258:                                if ((chptr = addtochlist(NULL))) {
        !           259:                                        chptr->chl_addr = chaddr;
        !           260:                                        chptr->chl_status = chused;
        !           261:                                }
        !           262:                                flock(fileno(chfile),LOCK_UN);
        !           263:                                fclose(chfile);
        !           264:                                return(result);
        !           265:                        }
        !           266:                flock(fileno(chfile),LOCK_UN);
        !           267:                fclose(chfile);
        !           268:                break;  /* don't look for other files */
        !           269:        }
        !           270:        /* try expanding-ring here -- this could be more efficient! */
        !           271:        if ((chfile = popen(BFS,"r")) != NULL) {
        !           272:                while (fgets(buf, BUFSIZ, chfile) != NULL)
        !           273:                        if ((buf[0] != '#') &&
        !           274:                            (chaddr=ns_addr(buf),
        !           275:                             result = ClearinghouseOpen(chaddr))) {
        !           276:                                if ((chptr = addtochlist(NULL))) {
        !           277:                                        chptr->chl_addr = chaddr;
        !           278:                                        chptr->chl_status = chused;
        !           279:                                }
        !           280:                                pclose(chfile);
        !           281:                                return(result);
        !           282:                        }
        !           283:                pclose(chfile);
        !           284:        }
        !           285:        return(result);
        !           286: }
        !           287: 
        !           288: CourierConnection *
        !           289: CH_GetOtherCH(conn,hint)
        !           290:        CourierConnection *conn;
        !           291:        Clearinghouse2_ObjectName hint;
        !           292: {
        !           293:        struct ns_addr *ch2addr;
        !           294:        CourierConnection *ch2conn, *chresult;
        !           295:        Clearinghouse2_RetrieveItemResults riresult;
        !           296:        Clearinghouse2_RetrieveMembersResults rmresult;
        !           297:        struct chlist *chptr;
        !           298: 
        !           299:        Clearinghouse2_Property clearinghouseNames = 3;
        !           300:        Clearinghouse2_Property clearinghouseAddresses = 4;
        !           301: 
        !           302:        if (hint.object != NULL && *hint.object != '\0') {
        !           303:            DURING
        !           304:                    /* get list of possible other clearinghouses */
        !           305:                    rmresult = Clearinghouse2_RetrieveMembers(conn, GetData, hint, 
        !           306:                            clearinghouseNames, BulkData1_immediateSink,
        !           307:                            nullagent);
        !           308:            HANDLER {
        !           309:                    /* some race condition */
        !           310:                    return(NULL);
        !           311:            } END_HANDLER;
        !           312:            /* throw away the distinguished name, which we don't need */
        !           313:            clear_Clearinghouse2_RetrieveMembersResults(&rmresult);
        !           314:        }
        !           315:        /* for each member of potentials list, probe it */
        !           316:        ch2conn = chresult = NULL;
        !           317:        for (chptr = namelist; chptr != NULL; chptr = chptr->chl_next) {
        !           318:            switch (chptr->chl_status) {
        !           319:            case chunknown:     /* a new entry, presumably */
        !           320:                /* get its address */
        !           321:                DURING
        !           322:                        riresult = Clearinghouse2_RetrieveItem(conn, NULL, 
        !           323:                                *(chptr->chl_name),
        !           324:                                clearinghouseAddresses, nullagent);
        !           325:                HANDLER
        !           326:                        break;  /* try next in namelist */
        !           327:                END_HANDLER;
        !           328:                chptr->chl_addr = *itemtonsaddr(&riresult.value);
        !           329:                clear_Clearinghouse2_RetrieveItemResults(&riresult);
        !           330:                chptr->chl_status = chdown;
        !           331:                /* fall through to: */
        !           332:            case chdown:        /* check down CH to see if it has revived */
        !           333:                /* make sure the second CH is really there */
        !           334:                if ((ch2conn = ClearinghouseOpen(chptr->chl_addr))) {
        !           335:                        chptr->chl_status = chup; /* we got it! */
        !           336:                        if (chresult == NULL) {
        !           337:                                chresult = ch2conn;
        !           338:                                chptr->chl_status = chused;
        !           339:                        }
        !           340:                        else CourierClose(ch2conn);
        !           341:                        ch2conn = NULL;
        !           342:                }
        !           343:                break;
        !           344:            case chup:
        !           345:            case chused:
        !           346:                break;
        !           347:            } /* end of switch */
        !           348:        } /* inspect next in list */
        !           349:        /* 
        !           350:         * if no new one, return an old one
        !           351:         */
        !           352:        for (chptr= namelist; chptr && (chresult==NULL); chptr= chptr->chl_next) {
        !           353:                if (chptr->chl_status == chup) {
        !           354:                    chptr->chl_status =
        !           355:                        (chresult=ClearinghouseOpen(chptr->chl_addr))
        !           356:                                        ? chused : chdown;
        !           357:                }
        !           358:        }
        !           359:        return(chresult);
        !           360: }
        !           361: 
        !           362: /*
        !           363:  * Given a Clearinghouse three part name (possibly containing wild cards)
        !           364:  * and the property number on which a NetworkAddress is expected to occur,
        !           365:  * returns the ns_addr structure associated with that name.
        !           366:  * Note that the ns_addr structure is statically allocated!
        !           367:  * Resets pattern to be the distinguished name of the object found.
        !           368:  */
        !           369: struct ns_addr *
        !           370: CH_LookupAddr(pattern,property)
        !           371:        Clearinghouse2_ObjectNamePattern pattern;
        !           372:        Clearinghouse2_Property property;
        !           373: {
        !           374:        struct ns_addr* CH_LookupAddrDN();
        !           375:        return(CH_LookupAddrDN(pattern,property,0,0));
        !           376: }
        !           377: 
        !           378: /*
        !           379:  * Lookup a clearinghouse address, returning the address and the
        !           380:  * distinguished name of the object found.
        !           381:  */
        !           382: struct ns_addr *
        !           383: CH_LookupAddrDN(pattern,property,distnamep,distnamelen)
        !           384:        Clearinghouse2_ObjectNamePattern pattern;
        !           385:        Clearinghouse2_Property property;
        !           386:        char *distnamep;
        !           387:        int distnamelen;
        !           388: {
        !           389:        struct ns_addr *chaddr, *resultaddr;
        !           390:        CourierConnection *conn, *ch2conn;
        !           391:        Clearinghouse2_ObjectName hint;         /* from WrongServer errors */
        !           392:        Clearinghouse2_RetrieveItemResults riresult;
        !           393:        int i;
        !           394: 
        !           395: 
        !           396:        if ((long) property <= 0)       /* default to addressList i.e. 4 */
        !           397:                property = CHEntries0_addressList;
        !           398:        if (pattern.object == NULL ||
        !           399:            pattern.domain == NULL ||
        !           400:            pattern.organization == NULL)
        !           401:                return(NULL);                   /* can't handle defaults */
        !           402:        
        !           403:        if ((conn = CH_GetFirstCH()) == NULL) {
        !           404:                fprintf(stderr,"Can't open connection to local Clearinghouse\n");
        !           405:                exit(1);
        !           406:        }
        !           407:        /* ask our primary clearinghouse for the address of this thing */
        !           408:        for (i = 5; i > 0; i--) {
        !           409:            DURING {
        !           410:                riresult = Clearinghouse2_RetrieveItem(conn, NULL,
        !           411:                                pattern, property, nullagent);
        !           412:                i = -1;
        !           413:            } HANDLER {
        !           414:                if (Exception.Code == REJECT_ERROR) {
        !           415:                        fprintf(stderr,"Problem with CH.addrs.  CH rejected request\n");
        !           416:                        hint.object = hint.domain = hint.organization = NULL;
        !           417:                }
        !           418:                else if (Exception.Code != Clearinghouse2_WrongServer) {
        !           419:                        /* some random error */
        !           420:                        hint.object = hint.domain = hint.organization = NULL;
        !           421:                }
        !           422:                else hint = CourierErrArgs(Clearinghouse2_WrongServerArgs, hint);
        !           423:                ch2conn = CH_GetOtherCH(conn, hint);
        !           424:                CourierClose(conn);
        !           425:                if (ch2conn == NULL) return(0);
        !           426:                conn = ch2conn;
        !           427:            } END_HANDLER;
        !           428:        }
        !           429:        if (i >= 0) {
        !           430:            return(0);
        !           431:        }
        !           432:        resultaddr = itemtonsaddr(&riresult.value);
        !           433:        if (distnamep != NULL &&
        !           434:            distnamelen >= (2+strlen(riresult.distinguishedObject.object)+
        !           435:                            strlen(riresult.distinguishedObject.domain)+
        !           436:                            strlen(riresult.distinguishedObject.organization)))
        !           437:                strcpy(distnamep,CH_NameToString(riresult.distinguishedObject));
        !           438:        clear_Clearinghouse2_RetrieveItemResults(&riresult);
        !           439:        CourierClose(conn);
        !           440:        return(resultaddr);
        !           441: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.