Annotation of 43BSDReno/contrib/isode-beta/quipu/di_block.c, revision 1.1

1.1     ! root        1: /* di_block.c - routines to handle operation activity blocks */
        !             2: 
        !             3: #ifndef lint
        !             4: static char *rcsid = "$Header: /f/osi/quipu/RCS/di_block.c,v 7.2 90/07/09 14:45:34 mrose Exp $";
        !             5: #endif
        !             6: 
        !             7: /*
        !             8:  * $Header: /f/osi/quipu/RCS/di_block.c,v 7.2 90/07/09 14:45:34 mrose Exp $
        !             9:  *
        !            10:  *
        !            11:  * $Log:       di_block.c,v $
        !            12:  * Revision 7.2  90/07/09  14:45:34  mrose
        !            13:  * sync
        !            14:  * 
        !            15:  * Revision 7.1  89/12/19  16:20:09  mrose
        !            16:  * sync
        !            17:  * 
        !            18:  * Revision 7.0  89/11/23  22:17:00  mrose
        !            19:  * Release 6.0
        !            20:  * 
        !            21:  */
        !            22: 
        !            23: /*
        !            24:  *                                NOTICE
        !            25:  *
        !            26:  *    Acquisition, use, and distribution of this module and related
        !            27:  *    materials are subject to the restrictions of a license agreement.
        !            28:  *    Consult the Preface in the User's Manual for the full terms of
        !            29:  *    this agreement.
        !            30:  *
        !            31:  */
        !            32: 
        !            33: 
        !            34: #include "quipu/util.h"
        !            35: #include "quipu/connection.h"
        !            36: #include "tsap.h"
        !            37: #include "tailor.h"
        !            38: 
        !            39: extern LLog * log_dsap;
        !            40: 
        !            41: extern time_t timenow;
        !            42: 
        !            43: struct di_block *di_alloc()
        !            44: {
        !            45:     struct di_block    * di_ret;
        !            46: 
        !            47:     di_ret = (struct di_block *) calloc(1,sizeof(struct di_block));
        !            48: 
        !            49:     return(di_ret);
        !            50: }
        !            51: 
        !            52: di_free(di)
        !            53: struct di_block *di;
        !            54: {
        !            55:        DLOG(log_dsap, LLOG_TRACE, ("di_free()"));
        !            56: 
        !            57:        switch (di->di_state) {
        !            58:          case DI_GLOBAL:       break;
        !            59:          case DI_TASK:         break;
        !            60:          case DI_OPERATION:    break;
        !            61:          default:
        !            62:                DLOG(log_dsap, LLOG_TRACE, ("di_free() of unknown type %d",di->di_state));
        !            63:                return;
        !            64:        }
        !            65: 
        !            66:        dn_free(di->di_dn);
        !            67: 
        !            68:        dn_free(di->di_target);
        !            69: 
        !            70:        if(di->di_accesspoints != NULLACCESSPOINT)
        !            71:            aps_free(di->di_accesspoints);
        !            72: 
        !            73:        di->di_state = -1;
        !            74: 
        !            75:        free((char *)di);
        !            76: }
        !            77: 
        !            78: di_extract(old_di)
        !            79: struct di_block        * old_di;
        !            80: {
        !            81:     struct di_block    * di;
        !            82:     struct di_block    **next_di;
        !            83: 
        !            84:     LLOG(log_dsap, LLOG_TRACE, ("di_extract"));
        !            85: #ifdef DEBUG
        !            86:     di_log(old_di);
        !            87: #endif
        !            88: 
        !            89:     switch(old_di->di_type)
        !            90:     {
        !            91:     case DI_GLOBAL:
        !            92:         next_di = &(deferred_dis);
        !            93:        for(di=deferred_dis; di!=NULL_DI_BLOCK; di=di->di_next)
        !            94:        {
        !            95:            if(di == old_di)
        !            96:                break;
        !            97: 
        !            98:            next_di = &(di->di_next);
        !            99:        }
        !           100:        if(di == NULL_DI_BLOCK)
        !           101:        {
        !           102:            LLOG(log_dsap, LLOG_EXCEPTIONS, ("di_block has escaped from global list"));
        !           103:        }
        !           104:        else
        !           105:        {
        !           106:            (*next_di) = di->di_next;
        !           107:        }
        !           108:        break;
        !           109:     case DI_OPERATION:
        !           110:        break;
        !           111:     case DI_TASK:
        !           112:        break;
        !           113:     default:
        !           114:        break;
        !           115:     }
        !           116: 
        !           117:     di_free(old_di);
        !           118: }
        !           119: 
        !           120: di_desist(di)
        !           121: struct di_block        * di;
        !           122: {
        !           123:     struct di_block    * di_tmp1;
        !           124:     struct di_block    * di_tmp1_next;
        !           125:     struct di_block    * di_tmp2;
        !           126:     struct di_block    **di_p2;
        !           127: 
        !           128:        DLOG(log_dsap, LLOG_TRACE, ("di_desist()"));
        !           129: 
        !           130:     for(di_tmp1=di; di_tmp1 != NULL_DI_BLOCK; di_tmp1 = di_tmp1_next)
        !           131:     {
        !           132:        di_tmp1_next = di_tmp1->di_next;
        !           133: 
        !           134:        switch(di->di_state)
        !           135:        {
        !           136:        case DI_ACCESSPOINT:
        !           137:        case DI_COMPLETE:
        !           138:                break;
        !           139:        case DI_DEFERRED:
        !           140:            di_p2 = &(di_tmp1->di_perform->on_wake_list);
        !           141:            for(di_tmp2=di_tmp1->di_perform->on_wake_list; di_tmp2!=NULL_DI_BLOCK; di_tmp2=di_tmp2->di_wake_next)
        !           142:            {
        !           143:                if(di_tmp2 == di_tmp1)
        !           144:                    break;
        !           145: 
        !           146:                di_p2 = &(di_tmp2->di_wake_next);
        !           147:            }
        !           148:            if(di_tmp2 == NULL_DI_BLOCK)
        !           149:            {
        !           150:                LLOG(log_dsap, LLOG_EXCEPTIONS, ("di_desist - di_block lost from performing operations wake up list"));
        !           151:            }
        !           152:            else
        !           153:            {
        !           154:                (*di_p2) = di_tmp2->di_wake_next;
        !           155:            }
        !           156:            break;
        !           157:        }
        !           158:        di_free(di_tmp1);
        !           159:     }
        !           160: }
        !           161: 
        !           162: di_log(di)
        !           163: struct di_block        * di;
        !           164: {
        !           165:     DLOG (log_dsap,LLOG_DEBUG, ("di_block [%x] , state = %d, type = %d",
        !           166:        di, di->di_state, di->di_type));
        !           167: }
        !           168: 
        !           169: di_list_log(di)
        !           170: struct di_block *di;
        !           171: {
        !           172:     struct di_block    * di_tmp;
        !           173: 
        !           174:     DLOG(log_dsap, LLOG_DEBUG, ("di_list:"));
        !           175: #ifdef DEBUG
        !           176:     for(di_tmp = di; di_tmp!=NULL_DI_BLOCK; di_tmp=di_tmp->di_next)
        !           177:     {
        !           178:        di_log(di_tmp);
        !           179:     }
        !           180: #endif
        !           181:     DLOG(log_dsap, LLOG_DEBUG, ("di_list ends."));
        !           182: }
        !           183: 
        !           184: 
        !           185: 
        !           186: static struct dn_seq * prefer_dsa_list = NULLDNSEQ;
        !           187: 
        !           188: prefer_dsa (str)
        !           189: char * str;
        !           190: {
        !           191: struct dn_seq * dsa, *loop;
        !           192: 
        !           193:        if (( dsa=str2dnseq(str)) == NULLDNSEQ) {
        !           194:                LLOG (log_dsap,LLOG_EXCEPTIONS,("Invalid prefered DSA name %s",str));   
        !           195:                return;
        !           196:        }
        !           197:        
        !           198:        if (prefer_dsa_list == NULLDNSEQ) 
        !           199:                prefer_dsa_list = dsa;
        !           200:        else {
        !           201:                for (loop = prefer_dsa_list; loop->dns_next != NULLDNSEQ; loop=loop->dns_next)
        !           202:                        ;
        !           203:                loop->dns_next = dsa;
        !           204:        }
        !           205: }
        !           206: 
        !           207: static di_prefer_dsa (a,b)
        !           208: DN a,b;
        !           209: {
        !           210: int x,y;
        !           211: 
        !           212:        if (prefer_dsa_list == NULLDNSEQ) {
        !           213:                DLOG (log_dsap,LLOG_TRACE,("NO DSAs to chose from"));
        !           214:                return 0;       /* not fussy !!! */
        !           215:        }
        !           216: 
        !           217:        if ((b == NULLDN) || (a == NULLDN)) {
        !           218:                DLOG (log_dsap,LLOG_NOTICE,("di_pref DNs NULL"));
        !           219:                return 0;       /* safty catch - don't think it can happen */
        !           220:        }
        !           221: 
        !           222:        if ((x = dn_in_dnseq (a,prefer_dsa_list)) == 0)
        !           223:                if ((y = dn_in_dnseq (b,prefer_dsa_list)) == 0)
        !           224:                        return 0;
        !           225:                else {
        !           226:                        DLOG (log_dsap,LLOG_TRACE,("DSA selected on preference"));
        !           227:                        return -1;
        !           228:                }
        !           229: 
        !           230:        if ((y = dn_in_dnseq (b,prefer_dsa_list)) == 0) {
        !           231:                DLOG (log_dsap,LLOG_TRACE,("DSA selected on preference"));
        !           232:                return 1;
        !           233:        }
        !           234: 
        !           235:        if ( x != y ) {
        !           236:                DLOG (log_dsap,LLOG_TRACE,("DSA selected on preference"));
        !           237:                return ( x > y ? -1 : 1 );
        !           238:        }
        !           239: 
        !           240:        return 0;
        !           241:        
        !           242: }
        !           243: 
        !           244: static di_ap2comp (di)
        !           245: struct di_block        **di;
        !           246: {
        !           247: struct di_block *loop;
        !           248: Entry eptr;
        !           249: 
        !           250:        /* replace DI_ACCESSPOINT with DI_COMPLETE if possible... */
        !           251:        /*      (data may have been cached since creating DI_ACCESSPOINT) */
        !           252: 
        !           253:        for (loop= *di; loop!=NULL_DI_BLOCK; loop=loop->di_next) {
        !           254:                if (loop->di_state != DI_ACCESSPOINT)
        !           255:                        continue;
        !           256: 
        !           257:                if (loop->di_reftype == RT_NONSPECIFICSUBORDINATE) 
        !           258:                        continue;       /* can't split these - all must be followed... */
        !           259: 
        !           260:                if (loop->di_accesspoints->ap_next == NULLACCESSPOINT) {
        !           261:                        if ((eptr=local_find_entry (loop->di_accesspoints->ap_name,FALSE)) != NULLENTRY)
        !           262:                                if (eptr->e_dsainfo != NULLDSA) {
        !           263:                                        loop->di_entry = eptr;
        !           264:                                        loop->di_state = DI_COMPLETE;   
        !           265:                                        aps_free (loop->di_accesspoints);
        !           266:                                        loop->di_accesspoints = NULLACCESSPOINT;
        !           267:                                }
        !           268:                } else 
        !           269:                        LLOG (log_dsap,LLOG_EXCEPTIONS,("Many access points, but not a RT_NONSPECIFICSUBORDINATE"));
        !           270:        }
        !           271: 
        !           272: }
        !           273: 
        !           274: dsa_reliable (cn,good,when)
        !           275: struct connection * cn;
        !           276: char good;
        !           277: time_t when;
        !           278: {
        !           279: Entry ptr;
        !           280: 
        !           281:        if ( (ptr=local_find_entry(cn->cn_dn,FALSE)) == NULLENTRY)
        !           282:                return;
        !           283: 
        !           284:        if (ptr->e_dsainfo == NULLDSA)
        !           285:                return;
        !           286: 
        !           287:        ptr->e_dsainfo->dsa_last_attempt = when;
        !           288:        if (good) {
        !           289:                ptr->e_dsainfo->dsa_last_success = when;
        !           290:                ptr->e_dsainfo->dsa_failures = 0;
        !           291:        } else 
        !           292:                ptr->e_dsainfo->dsa_failures++;
        !           293: }
        !           294: 
        !           295: static di_cmp_reliability (a,b)
        !           296: struct di_block *a, *b;
        !           297: {
        !           298: extern time_t retry_timeout;
        !           299: struct dsa_info *da, *db;
        !           300: 
        !           301:        /* If we have used a DSA recently, with no failures - use it again */
        !           302: 
        !           303:        if ((da = a->di_entry->e_dsainfo) == NULLDSA)
        !           304:                return 0;
        !           305:        if ((db = b->di_entry->e_dsainfo) == NULLDSA)
        !           306:                return 0;
        !           307: 
        !           308:        if (da->dsa_last_attempt == (time_t)0) {
        !           309:                if (db->dsa_failures == 0) {
        !           310:                        if ((db->dsa_last_success != (time_t)0)
        !           311:                                && (timenow - db->dsa_last_attempt < retry_timeout))
        !           312:                                return -1;      /* b worked recently */
        !           313:                } else if (timenow - db->dsa_last_attempt < retry_timeout)
        !           314:                        return 1;               /* b failed recently */
        !           315:                return 0;       /* have not tried either recently  */
        !           316: 
        !           317:        } else if (db->dsa_last_attempt == (time_t)0) {
        !           318:                if (da->dsa_failures == 0) {
        !           319:                        if ((da->dsa_last_success != (time_t)0)
        !           320:                                && (timenow - da->dsa_last_attempt < retry_timeout))
        !           321:                                return 1;       /* a worked recentdlry */
        !           322:                } else if (timenow - da->dsa_last_attempt < retry_timeout)
        !           323:                        return -1;              /* a failed recently */
        !           324:                return 0;       /* have not tried either recently  */
        !           325:        }
        !           326: 
        !           327:        if (da->dsa_failures == 0) {
        !           328:                if (db->dsa_failures == 0)
        !           329:                        return 0;       /* both OK */
        !           330:                return 1;       /* a worked last time, b failed - use a */
        !           331:        }
        !           332: 
        !           333:        if (db->dsa_failures == 0)
        !           334:                return -1;      /* b worked last time, a failed - use b */
        !           335: 
        !           336:        /* both failed last time - see if either have suceeded recently */
        !           337: 
        !           338:        if ((timenow - da->dsa_last_success) > retry_timeout ) {
        !           339:                if ((timenow - db->dsa_last_success) > retry_timeout)
        !           340:                        return 0;       /* too long ago to tell */
        !           341:                return -1;      /* use b it worked not that long ago... */
        !           342:        }
        !           343:        if ((timenow - db->dsa_last_success) > retry_timeout)
        !           344:                return 1;       /* use a it worked not that long ago... */
        !           345: 
        !           346:        /* neither has worked recently chose some other way */
        !           347:        return 0;
        !           348: }
        !           349: 
        !           350: static di_cmp_address (a,b)
        !           351: struct di_block *a, *b;
        !           352: {
        !           353: struct NSAPaddr *na;
        !           354: struct NSAPaddr *nb;
        !           355: struct NSAPaddr nas;
        !           356: struct TSAPaddr *ta2norm();
        !           357: struct TSAPaddr *ta;
        !           358: struct TSAPaddr *tb;
        !           359: int *ip;
        !           360: extern DN mydsadn;
        !           361: DN dnptr, mydnptr, dna,dnb;
        !           362: int ma,mb;
        !           363: 
        !           364:        /* select DSA with best looking address !!! */
        !           365: 
        !           366:        if (a->di_state == DI_COMPLETE) {
        !           367:                ta = &(a->di_entry->e_dsainfo->dsa_addr->pa_addr.sa_addr);
        !           368:                tb = &(b->di_entry->e_dsainfo->dsa_addr->pa_addr.sa_addr);
        !           369:                dna = a->di_dn;
        !           370:                dnb = b->di_dn;
        !           371:        } else {
        !           372:                /* Use 1 access point only */
        !           373:                ta = &(a->di_accesspoints->ap_address->pa_addr.sa_addr);
        !           374:                tb = &(b->di_accesspoints->ap_address->pa_addr.sa_addr);
        !           375:        }
        !           376: 
        !           377:        /* ta2norm return a static buffer */
        !           378:        ta = ta2norm (ta);
        !           379:        nas = *(ta->ta_addrs);  /* struct copy */
        !           380:        na = &nas;
        !           381:        tb = ta2norm (tb);
        !           382:        nb = tb->ta_addrs;
        !           383: 
        !           384:        /* normalised, so look for first "na" match with ts_communities */
        !           385:        for (ip = ts_communities; *ip; ip++) {
        !           386:                if (*ip == na->na_community) {
        !           387:                        if (*ip == nb->na_community)
        !           388:                                break;          /* same primary community */
        !           389:                        return 1;               /* 'a' preferred */
        !           390:                }
        !           391:                if (*ip == nb->na_community)
        !           392:                        return -1;              /* 'b' preferred */
        !           393:        }
        !           394: 
        !           395:        /* Look at the DSA name to detect locality */
        !           396:        ma=0;
        !           397:        for (dnptr=dna, mydnptr=mydsadn ;
        !           398:                (dnptr!=NULLDN) && (mydnptr!=NULLDN) ;
        !           399:                dnptr=dnptr->dn_parent, mydnptr=mydnptr->dn_parent) {
        !           400:                if (rdn_cmp(dnptr->dn_rdn,mydnptr->dn_rdn) == 0)
        !           401:                        ma++;
        !           402:        }
        !           403: 
        !           404:        mb=0;
        !           405:        for (dnptr=dnb, mydnptr=mydsadn ;
        !           406:                (dnptr!=NULLDN) && (mydnptr!=NULLDN) ;
        !           407:                dnptr=dnptr->dn_parent, mydnptr=mydnptr->dn_parent) {
        !           408:                if (rdn_cmp(dnptr->dn_rdn,mydnptr->dn_rdn) == 0)
        !           409:                        mb++;
        !           410:        }
        !           411: 
        !           412:        if (ma != mb)
        !           413:                return (ma > mb ? 1 : -1);
        !           414: 
        !           415:        /* check the DMD - NYI */
        !           416:        return 0;       
        !           417: }
        !           418: 
        !           419: static di_cmp (a,b)
        !           420: struct di_block *a, *b;
        !           421:     /*
        !           422:     *  Select best di_block
        !           423:     *    rule 1: deferred dsa infos have lowest preference, 
        !           424:     *           complete have highest.
        !           425:     *
        !           426:     *  If two block have same state, select using
        !           427:     *    preference 1: quipu DSAs with quipu context
        !           428:     *    preference 2: quipu DSAs
        !           429:     *    preference 3: reliable DSAs
        !           430:     *    preference 4: local DSAs
        !           431:     */
        !           432: {
        !           433: int x,y;
        !           434: 
        !           435:        if (a->di_state != b->di_state)
        !           436:                return (a->di_state > b->di_state ? -1 : 1);    /* rule 1 */
        !           437: 
        !           438:        switch (a->di_state) {
        !           439:        case DI_DEFERRED:
        !           440:                break;  
        !           441:        case DI_ACCESSPOINT:
        !           442:                if ((x = di_cmp_address(a,b)) != 0) {
        !           443:                        DLOG (log_dsap,LLOG_TRACE,("AP selected on address"));
        !           444:                        return x;       /* preference 4 - no info to asses 1,2 or 3 */
        !           445:                }
        !           446:                break;
        !           447:        case DI_COMPLETE:
        !           448:                x = quipu_ctx_supported (a->di_entry);
        !           449:                y = quipu_ctx_supported (b->di_entry);
        !           450:                if ( x != y ) {
        !           451:                        DLOG (log_dsap,LLOG_TRACE,("DSA selected on context"));
        !           452:                        return ( x > y ? 1 : -1);       /* preference 1 or 2 */
        !           453:                }
        !           454: 
        !           455:                if ((x=di_cmp_reliability (a,b)) != 0) {
        !           456:                        DLOG (log_dsap,LLOG_TRACE,("DSA selected on relibility"));
        !           457:                        return x;                       /* preference 3 */
        !           458:                }
        !           459: 
        !           460:                if ((x=di_cmp_address(a,b)) != 0) {
        !           461:                        DLOG (log_dsap,LLOG_TRACE,("DSA selected on address"));
        !           462:                        return x;               /* preference 4 */
        !           463:                }
        !           464: 
        !           465:                break;
        !           466:        }
        !           467: 
        !           468:        return (di_prefer_dsa(a->di_dn, b->di_dn));
        !           469: }
        !           470: 
        !           471: 
        !           472: sort_dsa_list (dsas)
        !           473: struct di_block        **dsas;
        !           474: {
        !           475: struct di_block        *trail;
        !           476: struct di_block        *old_di, *new_di;
        !           477: struct di_block *result;
        !           478: char changed = FALSE;
        !           479: 
        !           480:        /* turn access point into complete references if possible */
        !           481:        di_ap2comp (dsas);
        !           482: 
        !           483:        result = *dsas;
        !           484:        if ((old_di = result->di_next) == NULL_DI_BLOCK)
        !           485:                return;         /* only 1 - must be sorted !!! */
        !           486: 
        !           487:        result->di_next = NULL_DI_BLOCK;
        !           488: 
        !           489:        for(; old_di != NULL_DI_BLOCK; ) {
        !           490:                trail = NULL_DI_BLOCK;
        !           491:                for(new_di = result; new_di != NULL_DI_BLOCK; new_di= new_di->di_next) {
        !           492:                        if ( di_cmp (old_di,new_di) > 0 ) {
        !           493:                                if (trail == NULL_DI_BLOCK) {
        !           494:                                        result = old_di;
        !           495:                                        old_di = old_di->di_next;
        !           496:                                        result->di_next = new_di;
        !           497:                                } else {
        !           498:                                        trail->di_next = old_di;
        !           499:                                        old_di = old_di->di_next;
        !           500:                                        trail->di_next->di_next = new_di;
        !           501:                                }
        !           502:                                changed = TRUE;
        !           503:                                break;
        !           504:                        }
        !           505:                        trail = new_di;
        !           506:                } 
        !           507:                if (new_di == NULL_DI_BLOCK) {
        !           508:                        trail->di_next = old_di;
        !           509:                        old_di = old_di->di_next;
        !           510:                        trail->di_next->di_next = NULL_DI_BLOCK;
        !           511:                } 
        !           512:        }
        !           513:        *dsas = result;
        !           514: 
        !           515:        if (changed) {
        !           516:                LLOG (log_dsap,LLOG_TRACE,("DSA order changed"));
        !           517: #ifdef DEBUG
        !           518:                di_list_log (result);
        !           519: #endif
        !           520:        } else
        !           521:                DLOG (log_dsap,LLOG_TRACE,("DSA order not changed"));
        !           522: 
        !           523: }
        !           524: 
        !           525: static int       common_address (a,tb)
        !           526: struct di_block *a;
        !           527: struct TSAPaddr *tb;
        !           528: {
        !           529: struct TSAPaddr *ta;
        !           530: struct NSAPaddr *na;
        !           531: struct NSAPaddr *nb;
        !           532: int x,y;
        !           533: 
        !           534:        /* select DSA with best looking address !!! */
        !           535: 
        !           536:        if (a->di_state == DI_DEFERRED)
        !           537:                return FALSE;
        !           538: 
        !           539:        if (a->di_state == DI_COMPLETE)
        !           540:                ta = &(a->di_entry->e_dsainfo->dsa_addr->pa_addr.sa_addr);
        !           541:        else
        !           542:                /* Use 1 access point only */
        !           543:                ta = &(a->di_accesspoints->ap_address->pa_addr.sa_addr);
        !           544: 
        !           545:        /* compare ta and tb to see if they have a network in common */
        !           546:        for (na=ta->ta_addrs , x = ta->ta_naddr - 1 ;
        !           547:                        x >= 0;
        !           548:                        na++, x-- ) {
        !           549:                for (nb=tb->ta_addrs , y = tb->ta_naddr - 1 ;
        !           550:                                y >= 0;
        !           551:                                nb++, y-- ) {
        !           552:                        if (na->na_community == nb->na_community)
        !           553:                                return TRUE;
        !           554:                                }
        !           555:                        }
        !           556:        return FALSE;
        !           557: }
        !           558: 
        !           559: 
        !           560: struct di_block * select_refer_dsa(di,tk)
        !           561: struct di_block *di;
        !           562: struct task_act *tk;
        !           563: {
        !           564: struct di_block *best;
        !           565: struct di_block *loop;
        !           566: Entry eptr;
        !           567: struct TSAPaddr *ta;
        !           568: DN rdsa;
        !           569: 
        !           570:        /* return the di block of the best DSA the other end should be
        !           571:           to contact...
        !           572:           If it can't contact any - return NULL
        !           573:         */
        !           574: 
        !           575:        if (di != NULL_DI_BLOCK)
        !           576:                best = di;
        !           577:        else
        !           578:                best = NULL_DI_BLOCK;
        !           579: 
        !           580:        /* First set - find out who the remote end is... */
        !           581:        if (tk->tk_conn->cn_ctx == DS_CTX_X500_DAP)
        !           582:                return best;    /* we will chain anyway - unless prevented by service control... */
        !           583: 
        !           584:        rdsa = tk->tk_conn->cn_dn;
        !           585:        if ((eptr=local_find_entry (rdsa,FALSE)) == NULLENTRY)
        !           586:                return best;    /* no way of knowing */
        !           587: 
        !           588:        if (eptr->e_dsainfo == NULLDSA) 
        !           589:                return best;    /* no way of knowing */
        !           590: 
        !           591:        ta = &(eptr->e_dsainfo->dsa_addr->pa_addr.sa_addr);
        !           592:        ta = ta2norm (ta);      /* calculate subnets... */
        !           593: 
        !           594:        for (loop=di; loop!=NULL_DI_BLOCK; loop=loop->di_next)
        !           595:                if (common_address (loop,ta))
        !           596:                        return loop;
        !           597: 
        !           598:        /* nothing on the same network - chain if possible !!! */
        !           599:        return NULL_DI_BLOCK;   
        !           600: }
        !           601: 

unix.superglobalmegacorp.com

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