Annotation of 43BSDReno/contrib/isode-beta/ssap/ssapinitiate.c, revision 1.1.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.