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