Annotation of 43BSDReno/contrib/isode-beta/ssap/ssapinitiate.c, revision 1.1

1.1     ! root        1: /* ssapinitiate.c - SPM: initiator */
        !             2: 
        !             3: #ifndef        lint
        !             4: static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapinitiate.c,v 7.2 90/01/27 10:27:27 mrose Exp $";
        !             5: #endif
        !             6: 
        !             7: /* 
        !             8:  * $Header: /f/osi/ssap/RCS/ssapinitiate.c,v 7.2 90/01/27 10:27:27 mrose Exp $
        !             9:  *
        !            10:  *
        !            11:  * $Log:       ssapinitiate.c,v $
        !            12:  * Revision 7.2  90/01/27  10:27:27  mrose
        !            13:  * touch-up
        !            14:  * 
        !            15:  * Revision 7.1  89/11/27  10:30:40  mrose
        !            16:  * sync
        !            17:  * 
        !            18:  * Revision 7.0  89/11/23  22:25:27  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: /* LINTLIBRARY */
        !            35: 
        !            36: #include <stdio.h>
        !            37: #include <signal.h>
        !            38: #include "spkt.h"
        !            39: #include "tailor.h"
        !            40: 
        !            41: /*    S-(ASYN-)CONNECT.REQUEST */
        !            42: 
        !            43: #define        dotoken(requires,shift,bit,type) \
        !            44: { \
        !            45:     if (requirements & requires) \
        !            46:        switch (settings & (ST_MASK << shift)) { \
        !            47:            case ST_INIT_VALUE << shift: \
        !            48:            case ST_RESP_VALUE << shift: \
        !            49:            case ST_CALL_VALUE << shift: \
        !            50:                break; \
        !            51:  \
        !            52:            default: \
        !            53:                return ssaplose (si, SC_PARAMETER, NULLCP, \
        !            54:                        "improper choice of %s token setting", type); \
        !            55:        } \
        !            56: }
        !            57: 
        !            58: /*  */
        !            59: 
        !            60: int    SAsynConnRequest (ref, calling, called, requirements, settings, isn,
        !            61:        data, cc, qos, sc, si, async)
        !            62: struct SSAPref *ref;
        !            63: struct SSAPaddr *calling,
        !            64:                *called;
        !            65: int    requirements,
        !            66:        settings,
        !            67:        cc,
        !            68:        async;
        !            69: long   isn;
        !            70: char   *data;
        !            71: struct QOStype *qos;
        !            72: struct SSAPconnect *sc;
        !            73: struct SSAPindication *si;
        !            74: {
        !            75:     SBV     smask;
        !            76:     int     result;
        !            77: 
        !            78:     isodetailor (NULLCP, 0);
        !            79: 
        !            80:     missingP (ref);
        !            81:     refmuchP (ref);
        !            82:     if (ref -> sr_vlen)
        !            83:        return ssaplose (si, SC_PARAMETER, NULLCP, "bad format for reference");
        !            84: #ifdef notdef
        !            85:     missingP (calling);
        !            86: #endif
        !            87:     missingP (called);
        !            88: 
        !            89:     if (requirements & ~SR_MYREQUIRE)
        !            90:        return ssaplose (si, SC_PARAMETER, NULLCP,
        !            91:                "requirements settings not supported");
        !            92:     if ((requirements & SR_EXCEPTIONS)
        !            93:            && !(requirements & SR_HALFDUPLEX))
        !            94:        return ssaplose (si, SC_PARAMETER, NULLCP,
        !            95:                "exception service requires half-duplex service");
        !            96: 
        !            97:     dotokens ();
        !            98: 
        !            99:     if (requirements & (SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC)) {
        !           100:        if (!(requirements & SR_ACTIVITY) || isn != SERIAL_NONE)
        !           101:            if (SERIAL_MIN > isn || isn > SERIAL_MAX + 1)
        !           102:                return ssaplose (si, SC_PARAMETER, NULLCP,
        !           103:                        "bad choice for initial serial number");
        !           104:     }
        !           105:     else
        !           106:        if (isn != SERIAL_NONE)
        !           107:            return ssaplose (si, SC_PARAMETER, NULLCP,
        !           108:                    "initial serial number invalid given requirements");
        !           109: 
        !           110:     if (data == NULL)
        !           111:        cc = 0;
        !           112:     else
        !           113:        if (cc > CONNECT_MAX)
        !           114:            return ssaplose (si, SC_PARAMETER, NULLCP,
        !           115:                             "too much initial user data, %d octets", cc);
        !           116: 
        !           117: #ifdef notdef
        !           118:     missingP (qos);
        !           119: #endif
        !           120:     missingP (sc);
        !           121:     missingP (si);
        !           122: 
        !           123:     smask = sigioblock ();
        !           124: 
        !           125:     result = SConnRequestAux (ref, calling, called, requirements, settings,
        !           126:            isn, data, cc, qos, sc, si, async);
        !           127: 
        !           128:     (void) sigiomask (smask);
        !           129: 
        !           130:     return result;
        !           131: }
        !           132: 
        !           133: #undef dotoken
        !           134: 
        !           135: /*  */
        !           136: 
        !           137: static int  SConnRequestAux (ref, calling, called, requirements, settings, isn,
        !           138:            data, cc, qos, sc, si, async)
        !           139: struct SSAPref *ref;
        !           140: struct SSAPaddr *calling,
        !           141:                *called;
        !           142: int    requirements,
        !           143:        settings,
        !           144:        cc,
        !           145:        async;
        !           146: long   isn;
        !           147: char   *data;
        !           148: struct QOStype *qos;
        !           149: struct SSAPconnect *sc;
        !           150: struct SSAPindication *si;
        !           151: {
        !           152:     int     result;
        !           153:     register struct ssapkt *s;
        !           154:     register struct ssapblk *sb;
        !           155:     struct TSAPconnect  tcs;
        !           156:     register struct TSAPconnect *tc = &tcs;
        !           157:     struct TSAPdisconnect   tds;
        !           158:     register struct TSAPdisconnect *td = &tds;
        !           159: 
        !           160:     if ((sb = newsblk ()) == NULL)
        !           161:        return ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
        !           162:     if (!async || qos == NULLQOS || qos -> qos_maxtime <= 0)
        !           163:        sb -> sb_maxtime = NOTOK;
        !           164:     else
        !           165:        sb -> sb_maxtime = qos -> qos_maxtime;
        !           166: 
        !           167:     if ((s = newspkt (SPDU_CN)) == NULL) {
        !           168:        (void) ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
        !           169:        goto out1;
        !           170:     }
        !           171: 
        !           172: #ifdef notdef
        !           173:     if (called -> sa_selectlen > 0) {
        !           174:        if (calling == NULLSA) {
        !           175:            static struct SSAPaddr sas;
        !           176: 
        !           177:            calling = &sas;
        !           178:            bzero ((char *) calling, sizeof *calling);
        !           179:        }
        !           180: 
        !           181:        if (calling -> sa_selectlen == 0) {
        !           182:            calling -> sa_port =
        !           183:                            htons ((u_short) (0x8000 | (getpid () & 0x7fff)));
        !           184:            calling -> sa_selectlen = sizeof calling -> sa_port;
        !           185:        }
        !           186:     }
        !           187: #endif
        !           188: 
        !           189:     if (calling) {
        !           190:        if (calling -> sa_selectlen > 0) {
        !           191:            s -> s_mask |= SMASK_CN_CALLING;
        !           192:            bcopy (calling -> sa_selector, s -> s_calling,
        !           193:                s -> s_callinglen = calling -> sa_selectlen);
        !           194:        }
        !           195:        sb -> sb_initiating = *calling; /* struct copy */
        !           196:     }
        !           197: 
        !           198:     if (called -> sa_selectlen > 0) {
        !           199:        s -> s_mask |= SMASK_CN_CALLED;
        !           200:        bcopy (called -> sa_selector, s -> s_called,
        !           201:                s -> s_calledlen = called -> sa_selectlen);
        !           202:     }
        !           203:     sb -> sb_responding = *called;     /* struct copy */
        !           204: 
        !           205:     sb -> sb_requirements = requirements;
        !           206:     sb -> sb_settings = settings;
        !           207: 
        !           208:     if ((result = TAsynConnRequest (calling ? &calling -> sa_addr : NULLTA,
        !           209:                &called -> sa_addr,
        !           210:                (qos ? qos -> qos_extended : 0)
        !           211:                        || ((requirements & SR_EXPEDITED) ? 1 : 0),
        !           212:                NULLCP, 0, qos, tc, td, async)) == NOTOK) {
        !           213:        (void) ts2sslose (si, "TAsynConnRequest", td);
        !           214: 
        !           215:        bzero ((char *) sc, sizeof *sc);
        !           216:        sc -> sc_sd = NOTOK;
        !           217:        sc -> sc_result = si -> si_abort.sa_reason;
        !           218: 
        !           219:        result = DONE;
        !           220:        goto out2;
        !           221:     }
        !           222: 
        !           223:     sb -> sb_fd = tc -> tc_sd;
        !           224:     if (qos && qos -> qos_sversion < 0) {
        !           225:        sb -> sb_version = SB_VRSN1;
        !           226:        sb -> sb_vrsnmask = SB_ALLVRSNS;
        !           227:     }
        !           228:     else
        !           229:        sb -> sb_vrsnmask = 1 << (sb -> sb_version =
        !           230:                                    (cc > SS_SIZE
        !           231:                                           || (qos && qos -> qos_sversion > 1))
        !           232:                                       ? SB_VRSN2 : SB_VRSN1);
        !           233: 
        !           234:     s -> s_mask |= SMASK_CN_REF | SMASK_CN_OPT | SMASK_CN_VRSN;
        !           235:     s -> s_cn_reference = *ref;        /* struct copy */
        !           236:     s -> s_options = CR_OPT_NULL;
        !           237:     s -> s_cn_version = sb -> sb_vrsnmask;
        !           238: 
        !           239:     if (isn != SERIAL_NONE) {
        !           240:        s -> s_mask |= SMASK_CN_ISN;
        !           241:        s -> s_isn = isn;
        !           242:     }
        !           243: 
        !           244:     if (cc > 0) {              /* XXX: user musn't touch! */
        !           245:        s -> s_mask |= SMASK_UDATA_PGI;
        !           246:        s -> s_udata = data, s -> s_ulen = cc;
        !           247:     }
        !           248:     else
        !           249:        s -> s_udata = NULL, s -> s_ulen = 0;
        !           250: 
        !           251:     sb -> sb_retry = s;
        !           252:     if (async) {
        !           253:        switch (result) {
        !           254:        case CONNECTING_1:
        !           255:        case CONNECTING_2:
        !           256:            sc -> sc_sd = sb -> sb_fd;
        !           257:            return result;
        !           258:        }
        !           259:     }
        !           260:     if ((result = SAsynRetryAux (sb, tc, sc, si)) == DONE && !async)
        !           261:        result = OK;
        !           262:     return result;
        !           263: 
        !           264: out2: ;
        !           265:     freespkt (s);
        !           266: out1: ;
        !           267:     freesblk (sb);
        !           268: 
        !           269:     return result;
        !           270: }
        !           271: 
        !           272: /*    S-ASYN-RETRY.REQUEST (pseudo) */
        !           273: 
        !           274: int    SAsynRetryRequest (sd, sc, si)
        !           275: int    sd;
        !           276: struct SSAPconnect *sc;
        !           277: struct SSAPindication *si;
        !           278: {
        !           279:     SBV     smask;
        !           280:     int     result;
        !           281:     register struct ssapblk *sb;
        !           282:     struct TSAPconnect  tcs;
        !           283:     register struct TSAPconnect *tc = &tcs;
        !           284:     struct TSAPdisconnect   tds;
        !           285:     register struct TSAPdisconnect *td = &tds;
        !           286: 
        !           287:     missingP (sc);
        !           288:     missingP (si);
        !           289: 
        !           290:     smask = sigioblock ();
        !           291: 
        !           292:     if ((sb = findsblk (sd)) == NULL) {
        !           293:        (void) sigiomask (smask);
        !           294:        return ssaplose (si, SC_PARAMETER, NULLCP,
        !           295:                "invalid session descriptor");
        !           296:     }
        !           297:     if (sb -> sb_flags & SB_CONN) {
        !           298:        (void) sigiomask (smask);
        !           299:        return ssaplose (si, SC_OPERATION, NULLCP,
        !           300:                "session descriptor connected");
        !           301:     }
        !           302: 
        !           303:     switch (result = TAsynRetryRequest (sb -> sb_fd, tc, td)) {
        !           304:        case NOTOK: 
        !           305:            (void) ts2sslose (si, "TAsynRetryRequest", td);
        !           306:            sb -> sb_fd = NOTOK;
        !           307: 
        !           308:            bzero ((char *) sc, sizeof *sc);
        !           309:            sc -> sc_sd = NOTOK;
        !           310:            sc -> sc_result = si -> si_abort.sa_reason;
        !           311: 
        !           312:            result = DONE;
        !           313:            freesblk (sb);
        !           314:            break;
        !           315: 
        !           316:        case CONNECTING_1:
        !           317:        case CONNECTING_2:
        !           318:            break;
        !           319: 
        !           320:        case DONE: 
        !           321:            result = SAsynRetryAux (sb, tc, sc, si);
        !           322:            break;
        !           323:     }
        !           324: 
        !           325:     (void) sigiomask (smask);
        !           326: 
        !           327:     return result;
        !           328: }
        !           329: 
        !           330: /*    S-ASYN-NEXT.REQUEST (pseudo) */
        !           331: 
        !           332: int    SAsynNextRequest (sd, sc, si)
        !           333: int    sd;
        !           334: struct SSAPconnect *sc;
        !           335: struct SSAPindication *si;
        !           336: {
        !           337:     SBV     smask;
        !           338:     int     result;
        !           339:     register struct ssapblk *sb;
        !           340:     struct TSAPconnect  tcs;
        !           341:     register struct TSAPconnect *tc = &tcs;
        !           342:     struct TSAPdisconnect   tds;
        !           343:     register struct TSAPdisconnect *td = &tds;
        !           344: 
        !           345:     missingP (sc);
        !           346:     missingP (si);
        !           347: 
        !           348:     smask = sigioblock ();
        !           349: 
        !           350:     if ((sb = findsblk (sd)) == NULL) {
        !           351:        (void) sigiomask (smask);
        !           352:        return ssaplose (si, SC_PARAMETER, NULLCP,
        !           353:                "invalid session descriptor");
        !           354:     }
        !           355:     if (sb -> sb_flags & SB_CONN) {
        !           356:        (void) sigiomask (smask);
        !           357:        return ssaplose (si, SC_OPERATION, NULLCP,
        !           358:                "session descriptor connected");
        !           359:     }
        !           360: 
        !           361:     switch (result = TAsynNextRequest (sb -> sb_fd, tc, td)) {
        !           362:        case NOTOK: 
        !           363:            (void) ts2sslose (si, "TAsynRetryRequest", td);
        !           364:            sb -> sb_fd = NOTOK;
        !           365: 
        !           366:            bzero ((char *) sc, sizeof *sc);
        !           367:            sc -> sc_sd = NOTOK;
        !           368:            sc -> sc_result = si -> si_abort.sa_reason;
        !           369: 
        !           370:            result = DONE;
        !           371:            freesblk (sb);
        !           372:            break;
        !           373: 
        !           374:        case CONNECTING_1:
        !           375:        case CONNECTING_2:
        !           376:            break;
        !           377: 
        !           378:        case DONE: 
        !           379:            result = SAsynRetryAux (sb, tc, sc, si);
        !           380:            break;
        !           381:     }
        !           382: 
        !           383:     (void) sigiomask (smask);
        !           384: 
        !           385:     return result;
        !           386: }
        !           387: 
        !           388: /*  */
        !           389: 
        !           390: #define        dotoken(requires,shift,bit,type) \
        !           391: { \
        !           392:     if (sb -> sb_requirements & requires) { \
        !           393:        switch (sb -> sb_settings & (ST_MASK << shift)) { \
        !           394:            case ST_CALL_VALUE << shift: \
        !           395:                if (!(s -> s_mask & SMASK_CN_SET)) \
        !           396:                    s -> s_settings = ST_INIT_VALUE << shift; \
        !           397:                switch (s -> s_settings & (ST_MASK << shift)) { \
        !           398:                    case ST_INIT_VALUE << shift: \
        !           399:                    default: \
        !           400:                        sb -> sb_owned |= bit; \
        !           401:                        sc -> sc_settings |= ST_INIT_VALUE << shift; \
        !           402:                        break; \
        !           403:  \
        !           404:                    case ST_RESP_VALUE << shift: \
        !           405:                        sc -> sc_settings |= ST_RESP_VALUE << shift; \
        !           406:                        break; \
        !           407:                } \
        !           408:                break; \
        !           409:  \
        !           410:            case ST_INIT_VALUE << shift: \
        !           411:                sb -> sb_owned |= bit; \
        !           412:                sc -> sc_settings |= ST_INIT_VALUE << shift; \
        !           413:                break; \
        !           414:  \
        !           415:            case ST_RESP_VALUE << shift: \
        !           416:                sc -> sc_settings |= ST_RESP_VALUE << shift; \
        !           417:                break; \
        !           418:        } \
        !           419:  \
        !           420:        if ((s -> s_mask & SMASK_AC_TOKEN) && (s -> s_ac_token & bit)) \
        !           421:            sc -> sc_please |= bit; \
        !           422:     } \
        !           423: }
        !           424: 
        !           425: /*  */
        !           426: 
        !           427: static int  SAsynRetryAux (sb, tc, sc, si)
        !           428: register struct ssapblk *sb;
        !           429: struct TSAPconnect *tc;
        !           430: struct SSAPconnect *sc;
        !           431: struct SSAPindication *si;
        !           432: {
        !           433:     int            len,
        !           434:            result;
        !           435:     register struct ssapkt *s;
        !           436: 
        !           437:     s = sb -> sb_retry;
        !           438:     sb -> sb_retry = NULL;
        !           439: 
        !           440:     sb -> sb_responding.sa_addr = tc -> tc_responding; /* struct copy */
        !           441:     if (tc -> tc_expedited)
        !           442:        sb -> sb_flags |= SB_EXPD;
        !           443:     else
        !           444:        sb -> sb_requirements &= ~SR_EXPEDITED;
        !           445:     if (sb -> sb_version < SB_VRSN2)           /* XXX */
        !           446:        sb -> sb_tsdu_us = sb -> sb_tsdu_them =
        !           447:                                            GET_TSDU_SIZE (tc -> tc_tsdusize);
        !           448: 
        !           449:     if (sb -> sb_tsdu_us || sb -> sb_tsdu_them) {
        !           450:        s -> s_mask |= SMASK_CN_TSDU;
        !           451:        s -> s_tsdu_resp = GET_TSDU_SIZE (sb -> sb_tsdu_us);
        !           452:        s -> s_tsdu_init = GET_TSDU_SIZE (sb -> sb_tsdu_them);
        !           453:     }
        !           454: 
        !           455:     s -> s_mask |= SMASK_CN_REQ;
        !           456:     if ((s -> s_cn_require = sb -> sb_requirements) & SR_TOKENS) {
        !           457:        s -> s_mask |= SMASK_CN_SET;
        !           458:        s -> s_settings = sb -> sb_settings;
        !           459:     }
        !           460: 
        !           461:     result = spkt2sd (s, sb -> sb_fd, 0, si);
        !           462:     s -> s_mask &= ~SMASK_UDATA_PGI;
        !           463:     s -> s_udata = NULL, s -> s_ulen = 0;
        !           464: 
        !           465:     freespkt (s);
        !           466:     if (result == NOTOK)
        !           467:        goto out1;
        !           468: 
        !           469:     if ((s = sb2spkt (sb, si, sb -> sb_maxtime, NULLTX)) == NULL) {
        !           470:        if (si -> si_abort.sa_reason == SC_TIMER)
        !           471:            (void) ssaplose (si, SC_CONGEST, NULLCP, "remote SPM timed-out");
        !           472:        result = NOTOK;
        !           473:        goto out2;
        !           474:     }
        !           475: 
        !           476:     bzero ((char *) sc, sizeof *sc);
        !           477:     switch (s -> s_code) {
        !           478:        case SPDU_AC: 
        !           479:            sc -> sc_sd = sb -> sb_fd;
        !           480:            sc -> sc_result = SC_ACCEPT;
        !           481:            if (s -> s_mask & SMASK_CN_REF)
        !           482:                sc -> sc_connect = s -> s_cn_reference; /* struct copy */
        !           483:            if (s -> s_mask & SMASK_CN_OPT)
        !           484:                sb -> sb_options = s -> s_options;
        !           485:            if (!(s -> s_mask & SMASK_CN_TSDU))
        !           486:                s -> s_tsdu_init = s -> s_tsdu_resp = 0;
        !           487:            if (s -> s_tsdu_init < sb -> sb_tsdu_us)
        !           488:                sb -> sb_tsdu_us = s -> s_tsdu_init;
        !           489:            if (s -> s_tsdu_resp < sb -> sb_tsdu_them)
        !           490:                sb -> sb_tsdu_them = s -> s_tsdu_resp;
        !           491:            if (BAD_TSDU_SIZE (sb -> sb_tsdu_us)) {
        !           492:                result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
        !           493:                        "perposterous TSDU size (%d) for initiator",
        !           494:                        sb -> sb_tsdu_us);
        !           495:                goto out2;
        !           496:            }
        !           497:            if (BAD_TSDU_SIZE (sb -> sb_tsdu_them)) {
        !           498:                result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
        !           499:                        "perposterous TSDU size (%d) for responder",
        !           500:                        sb -> sb_tsdu_them);
        !           501:                goto out2;
        !           502:            }
        !           503:            if (s -> s_mask & SMASK_CN_VRSN) {
        !           504:                if (!(s -> s_cn_version & sb -> sb_vrsnmask)) {
        !           505:                                                        /* not SC_VERSION */
        !           506:                    result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
        !           507:                     "version mismatch: expecting something in 0x%x, got 0x%x",
        !           508:                                       sb -> sb_vrsnmask, s -> s_cn_version);
        !           509:                    goto out2;
        !           510:                }
        !           511:                sb -> sb_vrsnmask &= s -> s_cn_version;
        !           512:            }
        !           513:            sb -> sb_version = (sb -> sb_vrsnmask & (1 << SB_VRSN2))
        !           514:                                        ? SB_VRSN2 : SB_VRSN1;
        !           515:            if (s -> s_mask & SMASK_CN_ISN)
        !           516:                sc -> sc_isn = sb -> sb_V_A = sb -> sb_V_M = s -> s_isn;
        !           517:            else
        !           518:                sc -> sc_isn = SERIAL_NONE;
        !           519:            if (!(s -> s_mask & SMASK_CN_REQ)) {
        !           520:                s -> s_mask |= SMASK_CN_REQ;
        !           521:                s -> s_cn_require = SR_DEFAULT;
        !           522:            }
        !           523:            switch (sb -> sb_requirements & (SR_HALFDUPLEX | SR_DUPLEX)) {
        !           524:                case SR_HALFDUPLEX: 
        !           525:                    if (s -> s_cn_require & SR_HALFDUPLEX)
        !           526:                        break;
        !           527:                    result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
        !           528:                            "half-duplex negotiation failed");
        !           529:                    goto out2;
        !           530: 
        !           531:                case SR_DUPLEX: 
        !           532:                    if (s -> s_cn_require & SR_DUPLEX)
        !           533:                        break;
        !           534:                    result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
        !           535:                            "full-duplex negotiation failed");
        !           536:                    goto out2;
        !           537: 
        !           538:                default: 
        !           539:                    break;
        !           540:            }
        !           541: #ifdef notdef          /* screwy session protocol... */
        !           542:            if (s -> s_cn_require & ~sb -> sb_requirements) {
        !           543:                result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
        !           544:                            "requirements negotiation failed");
        !           545:                goto out2;
        !           546:            }
        !           547: #endif
        !           548:            sb -> sb_requirements &= s -> s_cn_require;
        !           549:            switch (sb -> sb_requirements & (SR_HALFDUPLEX | SR_DUPLEX)) {
        !           550:                case SR_HALFDUPLEX: 
        !           551:                case SR_DUPLEX: 
        !           552:                    break;
        !           553: 
        !           554:                default: 
        !           555:                    result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
        !           556:                            "half/full-duplex negotiation failed");
        !           557:                    goto out2;
        !           558:            }
        !           559:            if ((sb -> sb_requirements & SR_EXCEPTIONS)
        !           560:                    && !(sb -> sb_requirements & SR_HALFDUPLEX)) {
        !           561:                result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
        !           562:                        "exception service requires half-duplex service");
        !           563:                goto out2;
        !           564:            }
        !           565:            sc -> sc_requirements = sb -> sb_requirements;
        !           566:            sc -> sc_settings = sc -> sc_please = 0;
        !           567:            dotokens ();
        !           568:            if (s -> s_mask & SMASK_CN_CALLED) {
        !           569:                if ((len = s -> s_calledlen)
        !           570:                        > sizeof sb -> sb_responding.sa_selector)
        !           571:                    len = sizeof sb -> sb_responding.sa_selector;
        !           572:                bcopy (s -> s_called, sb -> sb_responding.sa_selector,
        !           573:                        sb -> sb_responding.sa_selectlen = len);
        !           574:            }
        !           575:            sc -> sc_responding = sb -> sb_responding;  /* struct copy */
        !           576:            if ((sc -> sc_ssdusize = sb -> sb_tsdu_us - SSDU_MAGIC) < 0)
        !           577:                sc -> sc_ssdusize = tc -> tc_tsdusize - SSDU_MAGIC;
        !           578:            sc -> sc_qos = tc -> tc_qos;        /* struct copy */
        !           579:            sc -> sc_qos.qos_sversion = sb -> sb_version + 1;
        !           580:            sc -> sc_qos.qos_extended = (sb -> sb_flags & SB_EXPD) ? 1 : 0;
        !           581:            copySPKTdata (s, sc);
        !           582: 
        !           583:            freespkt (s);
        !           584:            sb -> sb_flags |= SB_CONN | SB_INIT;
        !           585: 
        !           586:            return DONE;
        !           587: 
        !           588:        case SPDU_RF:           /* ignore s -> s_rf_disconnect */
        !           589:            sc -> sc_sd = NOTOK;
        !           590:            sc -> sc_result = s -> s_rlen > 0 ? *s -> s_rdata
        !           591:                : SC_NOTSPECIFIED;
        !           592:            if (s -> s_mask & SMASK_RF_REF)
        !           593:                sc -> sc_connect = s -> s_rf_reference; /* struct copy */
        !           594:            if ((sc -> sc_result == SC_REJECTED)
        !           595:                    && (s -> s_mask & SMASK_RF_REQ))
        !           596:                sc -> sc_requirements = s -> s_rf_require;
        !           597:            if ((s -> s_mask & SMASK_CN_CALLED)
        !           598:                    && (sc -> sc_result & SC_BASE)) {
        !           599:                if ((len = s -> s_calledlen)
        !           600:                        > sizeof sb -> sb_responding.sa_selector)
        !           601:                    len = sizeof sb -> sb_responding.sa_selector;
        !           602:                bcopy (s -> s_called, sb -> sb_responding.sa_selector,
        !           603:                        sb -> sb_responding.sa_selectlen = len);
        !           604:            }
        !           605:            sc -> sc_responding = sb -> sb_responding;  /* struct copy */
        !           606:            sc -> sc_data = s -> s_rdata + 1, sc -> sc_cc = s -> s_rlen - 1;
        !           607:            sc -> sc_realdata = s -> s_rdata, s -> s_rdata = NULL;
        !           608:            si -> si_type = SI_ABORT;
        !           609:            {
        !           610:                register struct SSAPabort  *sa = &si -> si_abort;
        !           611: 
        !           612:                sa -> sa_peer = 0;
        !           613:                sa -> sa_reason = sc -> sc_result;
        !           614:                sa -> sa_info = sc -> sc_data, sa -> sa_cc = sc -> sc_cc;
        !           615:                sa -> sa_realinfo = NULL;
        !           616:            }
        !           617:            result = DONE;
        !           618:            break;
        !           619: 
        !           620:        case SPDU_AB: 
        !           621:            sc -> sc_sd = NOTOK;
        !           622:            sc -> sc_result = SC_ABORT;
        !           623:            si -> si_type = SI_ABORT;
        !           624:            {
        !           625:                register struct SSAPabort  *sa = &si -> si_abort;
        !           626: 
        !           627:                if (!(sa -> sa_peer = (s -> s_ab_disconnect & AB_DISC_USER)
        !           628:                            ? 1 : 0))
        !           629:                    sa -> sa_reason = sc -> sc_result;
        !           630:                sa -> sa_info = s -> s_udata, sa -> sa_cc = s -> s_ulen;
        !           631:                sa -> sa_realinfo = s -> s_udata, s -> s_udata = NULL;
        !           632:            }
        !           633:            result = DONE;
        !           634:            break;
        !           635: 
        !           636:        default: 
        !           637:            result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
        !           638:                    "session protocol mangled: expecting 0x%x, got 0x%x",
        !           639:                    SPDU_AC, s -> s_code);
        !           640:            break;
        !           641:     }
        !           642: 
        !           643: out2: ;
        !           644:     freespkt (s);
        !           645: out1: ;
        !           646:     freesblk (sb);
        !           647: 
        !           648:     return result;
        !           649: }
        !           650: 
        !           651: #undef dotoken

unix.superglobalmegacorp.com

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