Annotation of 43BSDReno/contrib/isode-beta/tsap/tp0ts.c, revision 1.1

1.1     ! root        1: /* tp0ts.c - TPM: TP0 engine */
        !             2: 
        !             3: #ifndef        lint
        !             4: static char *rcsid = "$Header: /f/osi/tsap/RCS/tp0ts.c,v 7.6 90/07/27 08:48:10 mrose Exp $";
        !             5: #endif
        !             6: 
        !             7: /* 
        !             8:  * $Header: /f/osi/tsap/RCS/tp0ts.c,v 7.6 90/07/27 08:48:10 mrose Exp $
        !             9:  *
        !            10:  *
        !            11:  * $Log:       tp0ts.c,v $
        !            12:  * Revision 7.6  90/07/27  08:48:10  mrose
        !            13:  * update
        !            14:  * 
        !            15:  * Revision 7.5  90/03/23  17:31:10  mrose
        !            16:  * 8
        !            17:  * 
        !            18:  * Revision 7.4  89/12/19  10:18:22  mrose
        !            19:  * DLOG
        !            20:  * 
        !            21:  * Revision 7.3  89/12/08  09:41:23  mrose
        !            22:  * touch-up
        !            23:  * 
        !            24:  * Revision 7.2  89/12/07  22:15:39  mrose
        !            25:  * touch-up
        !            26:  * 
        !            27:  * Revision 7.1  89/12/07  01:07:30  mrose
        !            28:  * queued writes
        !            29:  * 
        !            30:  * Revision 7.0  89/11/23  22:30:33  mrose
        !            31:  * Release 6.0
        !            32:  * 
        !            33:  */
        !            34: 
        !            35: /*
        !            36:  *                               NOTICE
        !            37:  *
        !            38:  *    Acquisition, use, and distribution of this module and related
        !            39:  *    materials are subject to the restrictions of a license agreement.
        !            40:  *    Consult the Preface in the User's Manual for the full terms of
        !            41:  *    this agreement.
        !            42:  *
        !            43:  */
        !            44: 
        !            45: 
        !            46: /* LINTLIBRARY */
        !            47: 
        !            48: #include <stdio.h>
        !            49: #include "tpkt.h"
        !            50: #include "mpkt.h"
        !            51: #include "tailor.h"
        !            52: 
        !            53: 
        !            54: #if    defined(TCP) || defined(X25)
        !            55: 
        !            56: /*  */
        !            57: 
        !            58: static int  TConnect (tb, expedited, data, cc, td)
        !            59: register struct tsapblk *tb;
        !            60: char    *data;
        !            61: int    expedited,
        !            62:        cc;
        !            63: struct TSAPdisconnect *td;
        !            64: {
        !            65:     register struct tsapkt *t;
        !            66: 
        !            67:     if (!(tb -> tb_flags & TB_TCP)) {
        !            68:        expedited = 0;
        !            69:        if (cc > 0)
        !            70:            return tsaplose (td, DR_PARAMETER, NULLCP,
        !            71:                    "initial user data not allowed with class 0");
        !            72:     }
        !            73: 
        !            74:     tb -> tb_srcref = htons ((u_short) (getpid () & 0xffff));
        !            75:     tb -> tb_dstref = htons ((u_short) 0);
        !            76: 
        !            77:     if ((t = newtpkt (TPDU_CR)) == NULL)
        !            78:        return tsaplose (td, DR_CONGEST, NULLCP, "out of memory");
        !            79: 
        !            80:     t -> t_cr.cr_dstref = tb -> tb_dstref;
        !            81:     t -> t_cr.cr_srcref = tb -> tb_srcref;
        !            82:     t -> t_cr.cr_class = CR_CLASS_TP0;
        !            83:     if (!(tb -> tb_flags & TB_TCP)) {
        !            84:        register int    i,
        !            85:                        j;
        !            86:        int     k;
        !            87: 
        !            88:        i = k = tb -> tb_tsdusize + tb -> tb_tpduslop;
        !            89:        for (j = 0; i > 0; j++)
        !            90:            i >>= 1;
        !            91:        if (k == (1 << (j - 1)))
        !            92:            j--;
        !            93:        if (j > SIZE_MAXTP0) {
        !            94:            j = SIZE_MAXTP0;
        !            95:            tb -> tb_tsdusize = (1 << j) - tb -> tb_tpduslop;
        !            96:        }
        !            97:        if (j != SIZE_DFLT)
        !            98:            t -> t_tpdusize = j;
        !            99:     }
        !           100:     bcopy (tb -> tb_initiating.ta_selector, t -> t_calling,
        !           101:                t -> t_callinglen = tb -> tb_initiating.ta_selectlen);
        !           102: 
        !           103:     bcopy (tb -> tb_responding.ta_selector, t -> t_called,
        !           104:                t -> t_calledlen = tb -> tb_responding.ta_selectlen);
        !           105:     if (expedited) {
        !           106:        tb -> tb_flags |= TB_EXPD;
        !           107:        t -> t_options |= OPT_TEXPEDITE;
        !           108:     }
        !           109: 
        !           110:     copyTPKTdata (t, data, cc);        /* XXX: user musn't touch! */
        !           111: 
        !           112:     tb -> tb_retry = t;
        !           113: 
        !           114:     return OK;
        !           115: }
        !           116: 
        !           117: /*  */
        !           118: 
        !           119: static int  TRetry (tb, async, tc, td)
        !           120: register struct tsapblk *tb;
        !           121: int    async;
        !           122: struct TSAPconnect *tc;
        !           123: struct TSAPdisconnect *td;
        !           124: {
        !           125:     int            len;
        !           126:     register struct tsapkt *t;
        !           127: 
        !           128:     if (t = tb -> tb_retry) {
        !           129:        tb -> tb_retry = NULL;
        !           130: 
        !           131:        if (async)
        !           132:            switch ((*tb -> tb_retryfnx) (tb, td)) {
        !           133:                case NOTOK:
        !           134:                    goto out;
        !           135: 
        !           136:                case OK:
        !           137:                    tb -> tb_retry = t;
        !           138:                    return CONNECTING_1;
        !           139: 
        !           140:                case DONE:
        !           141:                    break;                  
        !           142:            }
        !           143: 
        !           144:        if (tpkt2fd (tb, t, tb -> tb_writefnx) == NOTOK) {
        !           145:            (void) tsaplose (td, t -> t_errno, NULLCP, NULLCP);
        !           146:            goto out;
        !           147:        }
        !           148: 
        !           149:        freetpkt (t), t = NULL;
        !           150:     }
        !           151: 
        !           152:     if (async) {
        !           153:        fd_set  mask;
        !           154: 
        !           155:        FD_ZERO (&mask);
        !           156:        FD_SET (tb -> tb_fd, &mask);
        !           157: 
        !           158:        if (xselect (tb -> tb_fd + 1, &mask, NULLFD, NULLFD, 0) == OK)
        !           159:            return CONNECTING_2;
        !           160:     }
        !           161: 
        !           162:     if ((t = fd2tpkt (tb -> tb_fd, tb -> tb_initfnx, tb -> tb_readfnx)) == NULL
        !           163:            || t -> t_errno != OK) {
        !           164:        (void) tsaplose (td, t ? t -> t_errno : DR_CONGEST, NULLCP, NULLCP);
        !           165:        goto out;
        !           166:     }
        !           167: 
        !           168:     switch (TPDU_CODE (t)) {
        !           169:        case TPDU_CC: 
        !           170:            tc -> tc_sd = tb -> tb_fd;
        !           171:            if (CR_CLASS (t) != CR_CLASS_TP0) {
        !           172:                (void) tpktlose (tb, td, DR_PROTOCOL, NULLCP,
        !           173:                        "proposed class 0, got back 0x%x", CR_CLASS (t));
        !           174:                goto out;
        !           175:            }
        !           176:            if (tb -> tb_srcref != t -> t_cc.cc_dstref) {
        !           177:                (void) tpktlose (tb, td, DR_MISMATCH, NULLCP,
        !           178:                        "sent srcref of 0x%x, got 0x%x",
        !           179:                        ntohs (tb -> tb_srcref), ntohs (t -> t_cc.cc_dstref));
        !           180:                goto out;
        !           181:            }
        !           182:            tb -> tb_dstref = t -> t_cc.cc_srcref;
        !           183:            if (!(tb -> tb_flags & TB_TCP)) {
        !           184:                if (t -> t_tpdusize == 0)
        !           185:                    t -> t_tpdusize = SIZE_DFLT;
        !           186:                else
        !           187:                    if (t -> t_tpdusize > SIZE_MAXTP0)
        !           188:                        t -> t_tpdusize = SIZE_MAXTP0;
        !           189:                tb -> tb_tpdusize = 1 << t -> t_tpdusize;
        !           190:                tb -> tb_tsdusize = tb -> tb_tpdusize - tb -> tb_tpduslop;
        !           191:            }
        !           192:            if ((len = t -> t_calledlen) > 0) {
        !           193:                if (len > sizeof tb -> tb_responding.ta_selector)
        !           194:                    len = sizeof tb -> tb_responding.ta_selector;
        !           195:                bcopy (t -> t_called, tb -> tb_responding.ta_selector,
        !           196:                        tb -> tb_responding.ta_selectlen = len);
        !           197:            }
        !           198:            copyTSAPaddrX (&tb -> tb_responding, &tc -> tc_responding);
        !           199:            if (!(t -> t_options & OPT_TEXPEDITE)
        !           200:                    || !(tb -> tb_flags & TB_TCP))
        !           201:                tb -> tb_flags &= ~TB_EXPD;
        !           202:            tc -> tc_expedited = (tb -> tb_flags & TB_EXPD) ? 1 : 0;
        !           203:            tc -> tc_tsdusize = tb -> tb_tsdusize;
        !           204:            tc -> tc_qos = tb -> tb_qos;        /* struct copy */
        !           205:            if (t -> t_qbuf) {
        !           206:                copyTSAPdata (t -> t_qbuf -> qb_data, t -> t_qbuf -> qb_len,
        !           207:                        tc);
        !           208:            }
        !           209:            else
        !           210:                tc -> tc_cc = 0;
        !           211: 
        !           212:            freetpkt (t);
        !           213:            tb -> tb_flags |= TB_CONN;
        !           214: #ifdef  MGMT
        !           215:            if (tb -> tb_manfnx)
        !           216:                (*tb -> tb_manfnx) (OPREQOUT, tb);
        !           217: #endif
        !           218:            if (tb -> tb_calling)
        !           219:                free ((char *) tb -> tb_calling), tb -> tb_calling = NULL;
        !           220:            if (tb -> tb_called)
        !           221:                free ((char *) tb -> tb_called), tb -> tb_called = NULL;
        !           222: 
        !           223:            return DONE;
        !           224: 
        !           225:        case TPDU_DR: 
        !           226:            td -> td_reason = t -> t_dr.dr_reason;
        !           227:            if (t -> t_qbuf) {
        !           228:                copyTSAPdata (t -> t_qbuf -> qb_data, t -> t_qbuf -> qb_len,
        !           229:                        td);
        !           230:            }
        !           231:            else
        !           232:                td -> td_cc = 0;
        !           233:            goto out;
        !           234: 
        !           235:        case TPDU_ER:
        !           236:            switch (t -> t_er.er_reject) {
        !           237:                case ER_REJ_NOTSPECIFIED:
        !           238:                default:
        !           239:                    td -> td_reason = DR_CONNECT;
        !           240:                    break;
        !           241: 
        !           242:                case ER_REJ_CODE:
        !           243:                case ER_REJ_TPDU:
        !           244:                case ER_REJ_VALUE:
        !           245:                    td -> td_reason = DR_PROTOCOL;
        !           246:                    break;
        !           247:            }
        !           248:            td -> td_cc = 0;
        !           249:            goto out;
        !           250:            
        !           251:        default: 
        !           252:            (void) tpktlose (tb, td, DR_PROTOCOL, NULLCP,
        !           253:                    "transport protocol mangled: expecting 0x%x, got 0x%x",
        !           254:                    TPDU_CC, TPDU_CODE (t));
        !           255:            goto out;
        !           256:     }
        !           257: 
        !           258: out: ;
        !           259:     freetpkt (t);
        !           260: /*    freetblk (tb); */
        !           261: 
        !           262:     return NOTOK;
        !           263: }
        !           264: 
        !           265: /*  */
        !           266: 
        !           267: static int  TStart (tb, cp, ts, td)
        !           268: register struct tsapblk *tb;
        !           269: char   *cp;
        !           270: struct TSAPstart *ts;
        !           271: struct TSAPdisconnect *td;
        !           272: {
        !           273:     int            len,
        !           274:            result;
        !           275:     register struct tsapkt *t;
        !           276: 
        !           277:     if ((t = str2tpkt (cp)) == NULL || t -> t_errno != OK) {
        !           278:        result = tsaplose (td, DR_PARAMETER, NULLCP,
        !           279:                    "bad initialization vector");
        !           280:        goto out;
        !           281:     }
        !           282: 
        !           283:     if (CR_CLASS (t) != CR_CLASS_TP0) {
        !           284:        if (t -> t_cr.cr_alternate & (ALT_TP0 | ALT_TP1))
        !           285:            t -> t_cr.cr_class = CR_CLASS_TP0;
        !           286:        else {
        !           287:            result = tpktlose (tb, td, DR_CONNECT, NULLCP,
        !           288:                        "only class 0 supported, not 0x%x", CR_CLASS (t));
        !           289:            goto out;
        !           290:        }
        !           291:     }
        !           292: 
        !           293:     tb -> tb_srcref = htons ((u_short) (getpid () & 0xffff));
        !           294:     tb -> tb_dstref = t -> t_cr.cr_srcref;
        !           295:     if (!(tb -> tb_flags & TB_TCP)) {
        !           296:        if (t -> t_tpdusize == 0)
        !           297:            t -> t_tpdusize = SIZE_DFLT;
        !           298:        else
        !           299:            if (t -> t_tpdusize > SIZE_MAXTP0)
        !           300:                t -> t_tpdusize = SIZE_MAXTP0;
        !           301:        tb -> tb_tpdusize = 1 << t -> t_tpdusize;
        !           302:        tb -> tb_tsdusize = tb -> tb_tpdusize - tb -> tb_tpduslop;
        !           303:     }
        !           304:     if ((len = t -> t_callinglen) > 0) {
        !           305:        if (len > sizeof tb -> tb_initiating.ta_selector)
        !           306:            len = sizeof tb -> tb_initiating.ta_selector;
        !           307:        bcopy (t -> t_calling, tb -> tb_initiating.ta_selector,
        !           308:                        tb -> tb_initiating.ta_selectlen = len);
        !           309:     }
        !           310:     if ((len = t -> t_calledlen) > 0) {
        !           311:        if (len > sizeof tb -> tb_responding.ta_selector)
        !           312:            len = sizeof tb -> tb_responding.ta_selector;
        !           313:        bcopy (t -> t_called, tb -> tb_responding.ta_selector,
        !           314:                        tb -> tb_responding.ta_selectlen = len);
        !           315:     }
        !           316:     if ((t -> t_options & OPT_TEXPEDITE) && (tb -> tb_flags & TB_TCP))
        !           317:        tb -> tb_flags |= TB_EXPD;
        !           318: 
        !           319:     ts -> ts_sd = tb -> tb_fd;
        !           320:     copyTSAPaddrX (&tb -> tb_initiating, &ts -> ts_calling);
        !           321:     copyTSAPaddrX (&tb -> tb_responding, &ts -> ts_called);
        !           322:     ts -> ts_expedited = (tb -> tb_flags & TB_EXPD) ? 1 : 0;
        !           323:     ts -> ts_tsdusize = tb -> tb_tsdusize;
        !           324:     ts -> ts_qos = tb -> tb_qos;       /* struct copy */
        !           325: 
        !           326:     if (t -> t_qbuf) {
        !           327:        copyTSAPdata (t -> t_qbuf -> qb_data, t -> t_qbuf -> qb_len, ts);
        !           328:     }
        !           329:     else
        !           330:        ts -> ts_cc = 0;
        !           331: 
        !           332:     result = OK;
        !           333: 
        !           334: out: ;
        !           335:     freetpkt (t);
        !           336: 
        !           337:     return result;
        !           338: }
        !           339: 
        !           340: /*  */
        !           341: 
        !           342: /* ARGSUSED */
        !           343: 
        !           344: static int  TAccept (tb, responding, data, cc, qos, td)
        !           345: register struct tsapblk *tb;
        !           346: char   *data;
        !           347: int    responding,
        !           348:        cc;
        !           349: struct QOStype *qos;
        !           350: struct TSAPdisconnect *td;
        !           351: {
        !           352:     int            result;
        !           353:     register struct tsapkt *t;
        !           354: 
        !           355:     if (!(tb -> tb_flags & TB_TCP) && cc > 0)
        !           356:        return tsaplose (td, DR_PARAMETER, NULLCP,
        !           357:                    "initial user data not allowed with class 0");
        !           358: 
        !           359:     if ((t = newtpkt (TPDU_CC)) == NULL)
        !           360:        return tsaplose (td, DR_CONGEST, NULLCP, "out of memory");
        !           361: 
        !           362:     t -> t_cc.cc_dstref = tb -> tb_dstref;
        !           363:     t -> t_cc.cc_srcref = tb -> tb_srcref;
        !           364:     t -> t_cc.cc_class = CR_CLASS_TP0;
        !           365:     if (!(tb -> tb_flags & TB_TCP)) {
        !           366:        register int    i,
        !           367:                        j;
        !           368:        int     k;
        !           369: 
        !           370:        i = k = tb -> tb_tsdusize + tb -> tb_tpduslop;
        !           371:        for (j = 0; i > 0; j++)
        !           372:            i >>= 1;
        !           373:        if (k == (1 << (j - 1)))
        !           374:            j--;
        !           375:        if (j > SIZE_MAXTP0) {
        !           376:            j = SIZE_MAXTP0;
        !           377:            tb -> tb_tsdusize = (1 << j) - tb -> tb_tpduslop;
        !           378:        }
        !           379:        if (j != SIZE_DFLT)
        !           380:            t -> t_tpdusize = j;
        !           381:     }
        !           382:     if (responding)
        !           383:        bcopy (tb -> tb_responding.ta_selector, t -> t_called,
        !           384:                        t -> t_calledlen = tb -> tb_responding.ta_selectlen);
        !           385:     if (tb -> tb_flags & TB_EXPD)
        !           386:        t -> t_options |= OPT_TEXPEDITE;
        !           387:     copyTPKTdata (t, data, cc);
        !           388: 
        !           389:     if ((result = tpkt2fd (tb, t, tb -> tb_writefnx)) == NOTOK)
        !           390:        (void) tsaplose (td, t -> t_errno, NULLCP, NULLCP);
        !           391:     else {
        !           392:        tb -> tb_flags |= TB_CONN;
        !           393: #ifdef  MGMT
        !           394:        if (tb -> tb_manfnx)
        !           395:            (*tb -> tb_manfnx) (OPREQIN, tb);
        !           396: #endif
        !           397:     }
        !           398: 
        !           399:     freetpkt (t);
        !           400: 
        !           401:     return result;
        !           402: }
        !           403: 
        !           404: /*  */
        !           405: 
        !           406: static int  TWrite (tb, uv, expedited, td)
        !           407: register struct tsapblk *tb;
        !           408: register struct udvec *uv;
        !           409: int    expedited;
        !           410: struct TSAPdisconnect *td;
        !           411: {
        !           412:     int            cc,
        !           413:            j,
        !           414:            len,
        !           415:            result;
        !           416: #if    defined(X25) || defined(MGMT)
        !           417:     int            dlen;
        !           418: #endif
        !           419:     register char *bp,
        !           420:                  *ep;
        !           421:     register struct tsapkt *t;
        !           422:     register struct udvec *vv,
        !           423:                          *wv;
        !           424: 
        !           425: #if    defined(X25) || defined(MGMT)
        !           426:     dlen = 0;
        !           427: #endif
        !           428: 
        !           429:     ep = (bp = uv -> uv_base) + (cc = uv -> uv_len);
        !           430:     while (uv -> uv_base) {
        !           431:        if ((t = newtpkt (expedited ? TPDU_ED : TPDU_DT)) == NULL)
        !           432:            return tsaplose (td, DR_CONGEST, NULLCP, "out of memory");
        !           433: 
        !           434:        wv = (vv = t -> t_udvec) + NTPUV - 1;
        !           435:        len = tb -> tb_tpdusize ? (tb -> tb_tpdusize - tb -> tb_tpduslop)
        !           436:                                : tb -> tb_tsdusize;
        !           437:        for (; len > 0 && vv < wv; len -= j) {
        !           438:            j = min (cc, len);
        !           439: #if    defined(X25) || defined(MGMT)
        !           440:            dlen += j;
        !           441: #endif
        !           442:            vv -> uv_base = bp, vv -> uv_len = j, vv++;
        !           443:            bp += j, cc -= j;
        !           444: 
        !           445:            if (bp >= ep) {
        !           446:                if ((bp = (++uv) -> uv_base) == NULL)
        !           447:                    break;
        !           448:                ep = bp + (cc = uv -> uv_len);
        !           449:            }
        !           450:        }
        !           451: 
        !           452:        if (uv -> uv_base == NULL)
        !           453:            t -> t_dt.dt_nr |= DT_EOT;
        !           454: 
        !           455:        if ((result = tpkt2fd (tb, t, tb -> tb_writefnx)) == NOTOK) {
        !           456:            (void) tsaplose (td, t -> t_errno, NULLCP, NULLCP);
        !           457: #ifdef X25
        !           458:            if (tb -> tb_flags & TB_X25)
        !           459:                LLOG (x25_log, LLOG_NOTICE,
        !           460:                      ("connection %d broken, %d/%d octets sent/recv",
        !           461:                       tb -> tb_fd, tb -> tb_sent, tb -> tb_recv));
        !           462: #endif
        !           463:            freetblk (tb);
        !           464:        }
        !           465: 
        !           466:        freetpkt (t);
        !           467:        if (result == NOTOK)
        !           468:            return NOTOK;
        !           469:     }
        !           470: 
        !           471: #ifdef X25
        !           472:     tb -> tb_sent += dlen;
        !           473: #endif
        !           474: #ifdef  MGMT
        !           475:     if (tb -> tb_manfnx)
        !           476:        (*tb -> tb_manfnx) (USERDT, tb, dlen);
        !           477: #endif
        !           478: 
        !           479:     return OK;
        !           480: }
        !           481: 
        !           482: /*  */
        !           483: 
        !           484: /* ARGSUSED */
        !           485: 
        !           486: static int  TRead (tb, tx, td, async, oob)
        !           487: register struct tsapblk *tb;
        !           488: register struct TSAPdata *tx;
        !           489: struct TSAPdisconnect *td;
        !           490: int    async,
        !           491:        oob;
        !           492: {
        !           493:     int     eot;
        !           494:     register struct tsapkt *t;
        !           495: 
        !           496:     bzero ((char *) tx, sizeof *tx);
        !           497:     tx -> tx_qbuf.qb_forw = tx -> tx_qbuf.qb_back = &tx -> tx_qbuf;
        !           498: 
        !           499:     for (;;) {
        !           500:        if ((t = fd2tpkt (tb -> tb_fd, tb -> tb_initfnx, tb -> tb_readfnx))
        !           501:                        == NULL
        !           502:                || t -> t_errno != OK) {
        !           503:            (void) tsaplose (td, t ? t -> t_errno : DR_CONGEST, NULLCP,
        !           504:                    NULLCP);
        !           505: #ifdef X25
        !           506:            if (tb -> tb_flags & TB_X25)
        !           507:                LLOG (x25_log, LLOG_NOTICE,
        !           508:                      ("connection %d broken, %d/%d octets sent/recv",
        !           509:                       tb -> tb_fd, tb -> tb_sent, tb -> tb_recv));
        !           510: #endif
        !           511:            break;
        !           512:        }
        !           513: 
        !           514:        switch (TPDU_CODE (t)) {
        !           515:            case TPDU_DT: 
        !           516:                eot = t -> t_dt.dt_nr & DT_EOT;
        !           517:                if (t -> t_qbuf) {
        !           518:                    insque (t -> t_qbuf, tb -> tb_qbuf.qb_back);
        !           519:                    tb -> tb_len += t -> t_qbuf -> qb_len;
        !           520: #ifdef X25
        !           521:                    tb -> tb_recv += t -> t_qbuf -> qb_len;
        !           522: #endif
        !           523:                    t -> t_qbuf = NULL;
        !           524:                }
        !           525:                freetpkt (t);
        !           526: #ifdef  MGMT
        !           527:                if (tb -> tb_manfnx)
        !           528:                    (*tb -> tb_manfnx) (USERDR, tb, tb -> tb_len);
        !           529: #endif
        !           530:                if (!eot) {
        !           531:                    if (async)
        !           532:                        return DONE;
        !           533: 
        !           534:                    continue;
        !           535:                }
        !           536:                tx -> tx_expedited = 0;
        !           537:                if (tb -> tb_qbuf.qb_forw != &tb -> tb_qbuf) {
        !           538:                    tx -> tx_qbuf = tb -> tb_qbuf;/* struct copy */
        !           539:                    tx -> tx_qbuf.qb_forw -> qb_back =
        !           540:                            tx -> tx_qbuf.qb_back -> qb_forw = &tx -> tx_qbuf;
        !           541:                    tx -> tx_cc = tb -> tb_len;
        !           542:                    tb -> tb_qbuf.qb_forw =
        !           543:                            tb -> tb_qbuf.qb_back = &tb -> tb_qbuf;
        !           544:                    tb -> tb_len = 0;
        !           545:                }
        !           546:                return OK;
        !           547: 
        !           548:            case TPDU_ED:
        !           549:                if (t -> t_qbuf) {
        !           550:                    insque (t -> t_qbuf, tx -> tx_qbuf.qb_back);
        !           551:                    tx -> tx_cc = t -> t_qbuf -> qb_len;
        !           552:                    t -> t_qbuf = NULL;
        !           553:                }
        !           554:                freetpkt (t);
        !           555:                tx -> tx_expedited = 1;
        !           556:                return OK;
        !           557: 
        !           558:            case TPDU_DR: 
        !           559:                td -> td_reason = t -> t_dr.dr_reason;
        !           560:                if (t -> t_qbuf) {
        !           561:                    copyTSAPdata (t -> t_qbuf -> qb_data,
        !           562:                            t -> t_qbuf -> qb_len, td);
        !           563:                }
        !           564:                else
        !           565:                    td -> td_cc = 0;
        !           566:                break;
        !           567: 
        !           568:            case TPDU_ER:
        !           569:                switch (t -> t_er.er_reject) {
        !           570:                    case ER_REJ_NOTSPECIFIED:
        !           571:                    default:
        !           572:                        td -> td_reason = DR_UNKNOWN;
        !           573:                        break;
        !           574: 
        !           575:                    case ER_REJ_CODE:
        !           576:                    case ER_REJ_TPDU:
        !           577:                    case ER_REJ_VALUE:
        !           578:                        td -> td_reason = DR_PROTOCOL;
        !           579:                        break;
        !           580:                }
        !           581:                td -> td_cc = 0;
        !           582:                break;
        !           583: 
        !           584:            default: 
        !           585:                (void) tpktlose (tb, td, DR_PROTOCOL, NULLCP,
        !           586:                        "transport protocol mangled: not expecting 0x%x",
        !           587:                        TPDU_CODE (t));
        !           588:                break;
        !           589:        }
        !           590:        break;
        !           591:     }
        !           592: 
        !           593:     freetpkt (t);
        !           594:     freetblk (tb);
        !           595: 
        !           596:     return NOTOK;
        !           597: }
        !           598: 
        !           599: /*  */
        !           600: 
        !           601: static int  TDisconnect (tb, data, cc, td)
        !           602: register struct tsapblk *tb;
        !           603: char   *data;
        !           604: int    cc;
        !           605: struct TSAPdisconnect *td;
        !           606: {
        !           607:     int     result;
        !           608: #ifdef TCP
        !           609:     register struct tsapkt *t;
        !           610: #endif
        !           611: 
        !           612:     result = OK;
        !           613: #ifdef TCP
        !           614:     if (tb -> tb_flags & TB_TCP) {
        !           615:        if (t = newtpkt (TPDU_DR)) {
        !           616:            t -> t_dr.dr_srcref = tb -> tb_srcref;
        !           617:            t -> t_dr.dr_dstref = tb -> tb_dstref;
        !           618:            t -> t_dr.dr_reason = DR_NORMAL;
        !           619:            copyTPKTdata (t, data, cc);
        !           620: 
        !           621:            if ((result = tpkt2fd (tb, t, tb -> tb_writefnx)) == NOTOK)
        !           622:                (void) tsaplose (td, t -> t_errno, NULLCP, NULLCP);
        !           623: 
        !           624:            freetpkt (t);
        !           625:        }
        !           626:        else
        !           627:            result = tsaplose (td, DR_CONGEST, NULLCP, "out of memory");
        !           628:     }
        !           629: #endif
        !           630: #ifdef X25
        !           631:     if (tb -> tb_flags & TB_X25)
        !           632:        LLOG (x25_log, LLOG_NOTICE,
        !           633:             ("connection %d closed, %d/%d octets sent/recv",
        !           634:              tb -> tb_fd, tb -> tb_sent, tb -> tb_recv));
        !           635: #endif
        !           636:     freetblk (tb);
        !           637: 
        !           638:     return result;
        !           639: }
        !           640: 
        !           641: /*  */
        !           642: 
        !           643: static TLose (tb, reason, td)
        !           644: register struct tsapblk *tb;
        !           645: int    reason;
        !           646: struct TSAPdisconnect *td;
        !           647: {
        !           648:     struct tsapkt  *t;
        !           649: 
        !           650:     switch (reason) {
        !           651:        case DR_UNKNOWN: 
        !           652:        case DR_CONGEST: 
        !           653:        case DR_SESSION: 
        !           654:        case DR_ADDRESS: 
        !           655:            if ((t = newtpkt (TPDU_DR)) == NULLPKT)
        !           656:                break;
        !           657: 
        !           658:            t -> t_dr.dr_srcref = tb -> tb_srcref;
        !           659:            t -> t_dr.dr_dstref = tb -> tb_dstref;
        !           660:            t -> t_dr.dr_reason = reason;
        !           661:            copyTPKTdata (t, td -> td_data, td -> td_cc);
        !           662:            break;
        !           663: 
        !           664:        default: 
        !           665:            if ((t = newtpkt (TPDU_ER)) == NULLPKT)
        !           666:                break;
        !           667: 
        !           668:            t -> t_er.er_dstref = tb -> tb_dstref;
        !           669:            switch (reason) {
        !           670:                case DR_PROTOCOL: 
        !           671:                    t -> t_er.er_reject = ER_REJ_TPDU;
        !           672:                    break;
        !           673: 
        !           674:                default: 
        !           675:                    t -> t_er.er_reject = ER_REJ_NOTSPECIFIED;
        !           676:                    break;
        !           677:            }
        !           678:            break;
        !           679:     }
        !           680:     if (t) {
        !           681:        (void) tpkt2fd (tb, t, tb -> tb_writefnx);
        !           682:        freetpkt (t);
        !           683:     }
        !           684: }
        !           685: 
        !           686: /*  */
        !           687: 
        !           688: /* at present, used by TCP, X.25 and BRG back-ends... */
        !           689: 
        !           690: #ifndef        TCP
        !           691: #undef WRITEV
        !           692: #endif
        !           693: 
        !           694: #include <errno.h>
        !           695: #include <sys/ioctl.h>
        !           696: #ifdef WRITEV
        !           697: #include <sys/uio.h>
        !           698: #endif
        !           699: #ifdef TCP
        !           700: #include "internet.h"
        !           701: #else
        !           702: #define        write_tcp_socket        NULLIFP
        !           703: #endif
        !           704: #ifdef X25
        !           705: #include "x25.h"
        !           706: #else
        !           707: #define        write_x25_socket        NULLIFP
        !           708: #endif
        !           709: 
        !           710: 
        !           711: extern int     errno;
        !           712: 
        !           713: /*  */
        !           714: 
        !           715: int    tp0write (tb, t, cp, n)
        !           716: register struct tsapblk *tb;
        !           717: register struct tsapkt *t;
        !           718: char   *cp;
        !           719: int    n;
        !           720: {
        !           721:     register int    cc;
        !           722:     register char   *p,
        !           723:                    *q;
        !           724:     register struct qbuf *qb;
        !           725:     register struct udvec  *uv;
        !           726: #if    defined(WRITEV) || defined(SUN_X25) || defined(CAMTEC_CCL)
        !           727:     struct iovec iovs[NTPUV + 4];
        !           728:     register struct iovec *iov;
        !           729: #endif
        !           730: 
        !           731: #if    defined(WRITEV) || defined(SUN_X25) || defined(CAMTEC_CCL)
        !           732: #ifdef FIONBIO
        !           733:     if (tb -> tb_flags & TB_QWRITES)
        !           734:        goto single;
        !           735: #endif
        !           736:     iov = iovs;
        !           737:     cc = 0;
        !           738: 
        !           739:     if (tb -> tb_flags & TB_X25) {
        !           740:        iov -> iov_base = (char *) &t -> t_li;
        !           741:        cc += (iov -> iov_len = sizeof t -> t_li);
        !           742:        iov++;
        !           743: 
        !           744:        iov -> iov_base = (char *) &t -> t_code;
        !           745:        cc += (iov -> iov_len = sizeof t -> t_code);
        !           746:        iov++;
        !           747: 
        !           748:     }
        !           749:     else {
        !           750:        iov -> iov_base = (char *) &t -> t_pkthdr;
        !           751:        cc += (iov -> iov_len = TPKT_HDRLEN (t));
        !           752:        iov++;
        !           753:     }
        !           754: 
        !           755:     iov -> iov_base = cp;
        !           756:     cc += (iov -> iov_len = n);
        !           757:     iov++;
        !           758: 
        !           759:     if (t -> t_vdata) {
        !           760:        iov -> iov_base = t -> t_vdata;
        !           761:        cc += (iov -> iov_len = t -> t_vlen);
        !           762:        iov++;
        !           763:     }
        !           764: 
        !           765:     for (uv = t -> t_udvec; uv -> uv_base; uv++) {
        !           766:        iov -> iov_base = uv -> uv_base;
        !           767:        cc += (iov -> iov_len = uv -> uv_len);
        !           768:        iov++;
        !           769:     }
        !           770: 
        !           771:     if ((n = writev (tb -> tb_fd, iovs, iov - iovs)) != cc) {
        !           772:        cc = NOTOK;
        !           773: #ifdef SUN_X25
        !           774:        if (tb -> tb_flags & TB_X25
        !           775:                && compat_log -> ll_events & LLOG_EXCEPTIONS)
        !           776:            (void) log_cause_and_diag (tb -> tb_fd);
        !           777: #endif
        !           778:     }
        !           779:     else
        !           780:        if (tb -> tb_flags & TB_X25) {
        !           781:            DLOG (compat_log, LLOG_DEBUG, ("X.25 write %d bytes", cc));
        !           782:        }
        !           783:     goto out;
        !           784: 
        !           785: single: ;
        !           786: #endif
        !           787: 
        !           788:     cc = ((tb -> tb_flags & TB_X25) ? sizeof t -> t_li + sizeof t -> t_code
        !           789:                                    : TPKT_HDRLEN (t))
        !           790:                + n;
        !           791:     if (t -> t_vdata)
        !           792:        cc += t -> t_vlen;
        !           793:     for (uv = t -> t_udvec; uv -> uv_base; uv++)
        !           794:        cc += uv -> uv_len;
        !           795: 
        !           796:     if (p = malloc (sizeof *qb + (unsigned) cc)) {
        !           797:        int     nc,
        !           798:                onoff;
        !           799:        IFP     wfnx = (tb -> tb_flags & TB_X25) ? write_x25_socket
        !           800:                                                 : write_tcp_socket;
        !           801: 
        !           802: #ifdef FIONBIO
        !           803:        if (tb -> tb_flags & TB_QWRITES) {
        !           804:            qb = (struct qbuf *) p;
        !           805:            qb -> qb_forw = qb -> qb_back = qb;
        !           806:            qb -> qb_data = qb -> qb_base, qb -> qb_len = cc;
        !           807:            p = qb -> qb_data;
        !           808:        }
        !           809: #endif
        !           810: 
        !           811:        if (tb -> tb_flags & TB_X25) {
        !           812:            bcopy ((char *) &t -> t_li, q = p, sizeof t -> t_li);
        !           813:            q += sizeof t -> t_li;
        !           814: 
        !           815:            bcopy ((char *) &t -> t_code, q, sizeof t -> t_code);
        !           816:            q += sizeof t -> t_code;
        !           817:        }
        !           818:        else {
        !           819:            bcopy ((char *) &t -> t_pkthdr, q = p, TPKT_HDRLEN (t));
        !           820:            q += TPKT_HDRLEN (t);
        !           821:        }
        !           822: 
        !           823:        bcopy (cp, q, n);
        !           824:        q += n;
        !           825: 
        !           826:        if (t -> t_vdata) {
        !           827:            bcopy (t -> t_vdata, q, t -> t_vlen);
        !           828:            q += t -> t_vlen;
        !           829:        }
        !           830: 
        !           831:        for (uv = t -> t_udvec; uv -> uv_base; uv++) {
        !           832:            bcopy (uv -> uv_base, q, uv -> uv_len);
        !           833:            q += uv -> uv_len;
        !           834:        }
        !           835: 
        !           836: #ifdef FIONBIO
        !           837:        if (tb -> tb_qwrites.qb_forw != &tb -> tb_qwrites) {
        !           838:            nc = 0;
        !           839:            goto insert;
        !           840:        }
        !           841: 
        !           842:        if (tb -> tb_flags & TB_QWRITES)
        !           843:            (void) ioctl (tb -> tb_fd, FIONBIO, (onoff = 1, (char *) &onoff));
        !           844: #endif
        !           845: 
        !           846:        nc = (*wfnx) (tb -> tb_fd, p, cc);
        !           847: 
        !           848: #ifdef FIONBIO
        !           849:        if (tb -> tb_flags & TB_QWRITES)
        !           850:            (void) ioctl (tb -> tb_fd, FIONBIO, (onoff = 0, (char *) &onoff));
        !           851: #endif
        !           852: 
        !           853:        if (nc != cc) {
        !           854: #ifdef FIONBIO
        !           855:            if (tb -> tb_flags & TB_QWRITES) {
        !           856:                if (nc == NOTOK) {
        !           857:                    if (errno != EWOULDBLOCK)
        !           858:                        goto losing;
        !           859:                    nc = 0;
        !           860:                }
        !           861:                else
        !           862:                    if (nc > 0 && (tb -> tb_flags & TB_X25)) {
        !           863:                        SLOG (tsap_log, LLOG_EXCEPTIONS, NULLCP,
        !           864:                              ("partial write (%d of %d octets) to X.25",
        !           865:                               nc, cc));
        !           866:                        goto losing;
        !           867:                    }
        !           868: 
        !           869:                if ((*tb -> tb_queuePfnx) (tb, 1, (struct TSAPdisconnect *) 0)
        !           870:                        == NOTOK)
        !           871:                    goto losing;
        !           872: 
        !           873:                qb -> qb_data += nc, qb -> qb_len -= nc;
        !           874: insert: ;
        !           875:                insque (qb, tb -> tb_qwrites.qb_back);
        !           876:                DLOG (tsap_log, LLOG_TRACE,
        !           877:                      ("queueing blocked write of %d of %d octets", nc, cc));
        !           878:                qb = NULL;
        !           879:            }
        !           880:            else
        !           881: #endif
        !           882:            {
        !           883: losing: ;
        !           884:                cc = NOTOK;
        !           885:            }
        !           886:        }
        !           887: 
        !           888: #ifdef FIONBIO
        !           889:        if (tb -> tb_flags & TB_QWRITES) {
        !           890:            if (qb)
        !           891:                free ((char *) qb);
        !           892:        }
        !           893:        else
        !           894: #endif
        !           895:            free (p);
        !           896:        goto out;
        !           897:     }
        !           898:     if ((tb -> tb_flags & TB_X25) || tb -> tb_flags & TB_QWRITES) {
        !           899:        SLOG (tsap_log, LLOG_EXCEPTIONS, NULLCP,
        !           900:              ("unable to malloc %d octets for pseudo-writev, failing...",
        !           901:               cc));
        !           902: 
        !           903:        cc = NOTOK;
        !           904:        goto out;
        !           905:     }
        !           906: 
        !           907: #ifdef TCP
        !           908:     SLOG (tsap_log, LLOG_EXCEPTIONS, NULLCP,
        !           909:          ("unable to malloc %d octets for pseudo-writev, continuing...",
        !           910:           cc));
        !           911: 
        !           912:     cc = TPKT_HDRLEN (t);
        !           913:     if (write_tcp_socket (tb -> tb_fd, (char *) &t -> t_pkthdr, cc) != cc) {
        !           914: err:   ;
        !           915:        cc = NOTOK;
        !           916:        goto out;
        !           917:     }
        !           918: 
        !           919:     if (write_tcp_socket (tb -> tb_fd, cp, n) != n)
        !           920:        goto err;
        !           921:     cc += n;
        !           922: 
        !           923:     if (t -> t_vdata
        !           924:            && write_tcp_socket (tb -> tb_fd, t -> t_vdata, t -> t_vlen)
        !           925:                    != t -> t_vlen)
        !           926:        goto err;
        !           927:     cc += t -> t_vlen;
        !           928: 
        !           929:     for (uv = t -> t_udvec; uv -> uv_base; uv++) {
        !           930:        if (write_tcp_socket (tb -> tb_fd, uv -> uv_base, uv -> uv_len)
        !           931:                != uv -> uv_len)
        !           932:            goto err;
        !           933:        cc += uv -> uv_len;
        !           934:     }
        !           935: #endif
        !           936: 
        !           937: out: ;
        !           938: 
        !           939:     return cc;
        !           940: }
        !           941: 
        !           942: /*  */
        !           943: 
        !           944: #ifdef FIONBIO
        !           945: static int  TDrain (tb, td)
        !           946: register struct tsapblk *tb;
        !           947: struct TSAPdisconnect *td;
        !           948: {
        !           949:     int            nc,
        !           950:            onoff,
        !           951:            result;
        !           952:     register struct qbuf *qb;
        !           953:     IFP            wfnx = (tb -> tb_flags & TB_X25) ? write_x25_socket
        !           954:                                             : write_tcp_socket;
        !           955: 
        !           956:     (void) ioctl (tb -> tb_fd, FIONBIO, (onoff = 1, (char *) &onoff));
        !           957: 
        !           958:     while ((qb = tb -> tb_qwrites.qb_forw) != &tb -> tb_qwrites) {
        !           959:        if ((nc = (*wfnx) (tb -> tb_fd, qb -> qb_data, qb -> qb_len))
        !           960:                != qb -> qb_len) {
        !           961:            if (nc == NOTOK) {
        !           962:                if (errno != EWOULDBLOCK) {
        !           963:                    result = tsaplose (td, DR_NETWORK, "failed",
        !           964:                                      "write to network");
        !           965:                    goto out;
        !           966:                }
        !           967: 
        !           968:                nc = 0;
        !           969:            }
        !           970:            else
        !           971:                if (nc > 0 && (tb -> tb_flags & TB_X25)) {
        !           972:                    SLOG (tsap_log, LLOG_EXCEPTIONS, NULLCP,
        !           973:                          ("partial write (%d of %d octets) to X.25",
        !           974:                           nc, qb -> qb_len));
        !           975:                    result = tsaplose (td, DR_NETWORK, NULLCP,
        !           976:                                       "partial write (%d of %d octets) to X.25",
        !           977:                                       nc, qb -> qb_len);
        !           978:                    goto out;
        !           979:                }
        !           980: 
        !           981:            DLOG (tsap_log, LLOG_TRACE,
        !           982:                  ("wrote %d of %d octets from blocked write", nc,
        !           983:                   qb -> qb_len));
        !           984:            qb -> qb_data += nc, qb -> qb_len -= nc;
        !           985: 
        !           986:            result = OK;
        !           987:            goto out;
        !           988:        }
        !           989: 
        !           990:        DLOG (tsap_log, LLOG_TRACE,
        !           991:              ("finished blocked write of %d octets", qb -> qb_len));
        !           992:        remque (qb);
        !           993:        free ((char *) qb);
        !           994:     }
        !           995:     result = DONE;
        !           996: 
        !           997: out: ;
        !           998:     (void) ioctl (tb -> tb_fd, FIONBIO, (onoff = 0, (char *) &onoff));
        !           999: 
        !          1000:     return result;
        !          1001: }
        !          1002: #endif
        !          1003: 
        !          1004: /*  */
        !          1005: 
        !          1006: int    tp0init (tb)
        !          1007: register struct tsapblk *tb;
        !          1008: {
        !          1009:     tb -> tb_connPfnx = TConnect;
        !          1010:     tb -> tb_retryPfnx = TRetry;
        !          1011: 
        !          1012:     tb -> tb_startPfnx = TStart;
        !          1013:     tb -> tb_acceptPfnx = TAccept;
        !          1014: 
        !          1015:     tb -> tb_writePfnx = TWrite;
        !          1016:     tb -> tb_readPfnx = TRead;
        !          1017:     tb -> tb_discPfnx = TDisconnect;
        !          1018:     tb -> tb_losePfnx = TLose;
        !          1019: 
        !          1020: #ifdef FIONBIO
        !          1021:     tb -> tb_drainPfnx = TDrain;
        !          1022: #endif
        !          1023: 
        !          1024: #ifdef  MGMT
        !          1025:     tb -> tb_manfnx = TManGen;
        !          1026: #endif
        !          1027: }
        !          1028: #endif

unix.superglobalmegacorp.com

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