Annotation of 43BSDReno/sys/netiso/tp_pcb.c, revision 1.1.1.1

1.1       root        1: /***********************************************************
                      2:                                Copyright IBM Corporation 1987
                      3: 
                      4:                       All Rights Reserved
                      5: 
                      6: Permission to use, copy, modify, and distribute this software and its 
                      7: documentation for any purpose and without fee is hereby granted, 
                      8: provided that the above copyright notice appear in all copies and that
                      9: both that copyright notice and this permission notice appear in 
                     10: supporting documentation, and that the name of IBM not be
                     11: used in advertising or publicity pertaining to distribution of the
                     12: software without specific, written prior permission.  
                     13: 
                     14: IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     15: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     16: IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     17: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     18: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     19: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     20: SOFTWARE.
                     21: 
                     22: ******************************************************************/
                     23: 
                     24: /*
                     25:  * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
                     26:  */
                     27: /* 
                     28:  * ARGO TP
                     29:  *
                     30:  * $Header: tp_pcb.c,v 5.4 88/11/18 17:28:24 nhall Exp $
                     31:  * $Source: /usr/argo/sys/netiso/RCS/tp_pcb.c,v $
                     32:  *     @(#)tp_pcb.c    7.6 (Berkeley) 6/28/90 *
                     33:  *
                     34:  *
                     35:  * This is the initialization and cleanup stuff - 
                     36:  * for the tp machine in general as well as  for the individual pcbs.
                     37:  * tp_init() is called at system startup.  tp_attach() and tp_getref() are
                     38:  * called when a socket is created.  tp_detach() and tp_freeref()
                     39:  * are called during the closing stage and/or when the reference timer 
                     40:  * goes off. 
                     41:  * tp_soisdisconnecting() and tp_soisdisconnected() are tp-specific 
                     42:  * versions of soisconnect*
                     43:  * and are called (obviously) during the closing phase.
                     44:  *
                     45:  */
                     46: 
                     47: #ifndef lint
                     48: static char *rcsid = "$Header: tp_pcb.c,v 5.4 88/11/18 17:28:24 nhall Exp $";
                     49: #endif lint
                     50: 
                     51: #include "argoxtwentyfive.h"
                     52: #include "types.h"
                     53: #include "param.h"
                     54: #include "mbuf.h"
                     55: #include "socket.h"
                     56: #include "socketvar.h"
                     57: #include "protosw.h"
                     58: #include "errno.h"
                     59: #include "time.h"
                     60: #include "argo_debug.h"
                     61: #include "tp_param.h"
                     62: #include "tp_timer.h"
                     63: #include "tp_ip.h"
                     64: #include "tp_stat.h"
                     65: #include "tp_pcb.h"
                     66: #include "tp_tpdu.h"
                     67: #include "tp_trace.h"
                     68: #include "tp_meas.h"
                     69: #include "tp_seq.h"
                     70: #include "tp_clnp.h"
                     71: 
                     72: /* list of reference structures */
                     73: struct tp_ref tp_ref[N_TPREF];
                     74: 
                     75: struct tp_param tp_param = {
                     76:        1,                              /*  configured          */
                     77: };
                     78: 
                     79: /* ticks are in units of: 
                     80:  * 500 nano-fortnights ;-) or
                     81:  * 500 ms or 
                     82:  * 1/2 second 
                     83:  */
                     84: 
                     85: struct tp_conn_param tp_conn_param[] = {
                     86:        /* ISO_CLNS: TP4 CONNECTION LESS */
                     87:        {
                     88:                TP_NRETRANS,    /* short p_Nretrans;  */
                     89:                20,             /* 10 sec */    /* short p_dr_ticks;  */
                     90: 
                     91:                20,             /* 10 sec */    /* short p_cc_ticks; */
                     92:                20,             /* 10 sec */    /* short p_dt_ticks; */
                     93: 
                     94:                40,             /* 20 sec */    /* short p_x_ticks;      */
                     95:                80,             /* 40 sec */    /* short p_cr_ticks;*/
                     96: 
                     97:                240,    /* 2 min */     /* short p_keepalive_ticks;*/
                     98:                10,             /* 5 sec */     /* short p_sendack_ticks;  */
                     99: 
                    100:                600,    /* 5 min */     /* short p_ref_ticks;   */
                    101:                360,    /* 3 min */     /* short p_inact_ticks; */
                    102: 
                    103:                (short) 100,                    /* short p_lcdtfract */
                    104:                (short) TP_SOCKBUFSIZE, /* short p_winsize */
                    105:                TP_TPDUSIZE,                    /* u_char p_tpdusize */
                    106: 
                    107:                TPACK_WINDOW,                   /* 4 bits p_ack_strat */
                    108:                TPRX_USE_CW | TPRX_FASTSTART, 
                    109:                                                                /* 4 bits p_rx_strat*/
                    110:                TP_CLASS_4 | TP_CLASS_0,/* 5 bits p_class */
                    111:                1,                                              /* 1 bit xtd format */
                    112:                1,                                              /* 1 bit xpd service */
                    113:                1,                                              /* 1 bit use_checksum */
                    114:                0,                                              /* 1 bit use net xpd */
                    115:                0,                                              /* 1 bit use rcc */
                    116:                0,                                              /* 1 bit use efc */
                    117:                1,                                              /* no disc indications */
                    118:                0,                                              /* don't change params */
                    119:                ISO_CLNS,                               /* p_netservice */
                    120:        },
                    121:        /* IN_CLNS: TP4 CONNECTION LESS */
                    122:        {
                    123:                TP_NRETRANS,    /* short p_Nretrans;  */
                    124:                20,             /* 10 sec */    /* short p_dr_ticks;  */
                    125: 
                    126:                20,             /* 10 sec */    /* short p_cc_ticks; */
                    127:                20,             /* 10 sec */    /* short p_dt_ticks; */
                    128: 
                    129:                40,             /* 20 sec */    /* short p_x_ticks;      */
                    130:                80,             /* 40 sec */    /* short p_cr_ticks;*/
                    131: 
                    132:                240,    /* 2 min */     /* short p_keepalive_ticks;*/
                    133:                10,             /* 5 sec */     /* short p_sendack_ticks;  */
                    134: 
                    135:                600,    /* 5 min */     /* short p_ref_ticks;   */
                    136:                360,    /* 3 min */     /* short p_inact_ticks; */
                    137: 
                    138:                (short) 100,                    /* short p_lcdtfract */
                    139:                (short) TP_SOCKBUFSIZE, /* short p_winsize */
                    140:                TP_TPDUSIZE,                    /* u_char p_tpdusize */
                    141: 
                    142:                TPACK_WINDOW,                   /* 4 bits p_ack_strat */
                    143:                TPRX_USE_CW | TPRX_FASTSTART, 
                    144:                                                                /* 4 bits p_rx_strat*/
                    145:                TP_CLASS_4,                             /* 5 bits p_class */
                    146:                1,                                              /* 1 bit xtd format */
                    147:                1,                                              /* 1 bit xpd service */
                    148:                1,                                              /* 1 bit use_checksum */
                    149:                0,                                              /* 1 bit use net xpd */
                    150:                0,                                              /* 1 bit use rcc */
                    151:                0,                                              /* 1 bit use efc */
                    152:                1,                                              /* no disc indications */
                    153:                0,                                              /* don't change params */
                    154:                IN_CLNS,                                /* p_netservice */
                    155:        },
                    156:        /* ISO_CONS: TP0 CONNECTION MODE */
                    157:        {
                    158:                TP_NRETRANS,                    /* short p_Nretrans;  */
                    159:                0,              /* n/a */               /* short p_dr_ticks; */
                    160: 
                    161:                40,             /* 20 sec */    /* short p_cc_ticks; */
                    162:                0,              /* n/a */               /* short p_dt_ticks; */
                    163: 
                    164:                0,              /* n/a */               /* short p_x_ticks;     */
                    165:                360,    /* 3  min */    /* short p_cr_ticks;*/
                    166: 
                    167:                0,              /* n/a */               /* short p_keepalive_ticks;*/
                    168:                0,              /* n/a */               /* short p_sendack_ticks; */
                    169: 
                    170:                600,    /* for cr/cc to clear *//* short p_ref_ticks;   */
                    171:                0,              /* n/a */               /* short p_inact_ticks; */
                    172: 
                    173:                /* Use tp4 defaults just in case the user changes ONLY
                    174:                 * the class 
                    175:                 */
                    176:                (short) 100,                    /* short p_lcdtfract */
                    177:                (short) TP0_SOCKBUFSIZE,        /* short p_winsize */
                    178:                TP0_TPDUSIZE,                   /* 8 bits p_tpdusize */
                    179: 
                    180:                0,                                              /* 4 bits p_ack_strat */
                    181:                0,                                              /* 4 bits p_rx_strat*/
                    182:                TP_CLASS_0,                             /* 5 bits p_class */
                    183:                0,                                              /* 1 bit xtd format */
                    184:                0,                                              /* 1 bit xpd service */
                    185:                0,                                              /* 1 bit use_checksum */
                    186:                0,                                              /* 1 bit use net xpd */
                    187:                0,                                              /* 1 bit use rcc */
                    188:                0,                                              /* 1 bit use efc */
                    189:                0,                                              /* no disc indications */
                    190:                0,                                              /* don't change params */
                    191:                ISO_CONS,                               /* p_netservice */
                    192:        },
                    193:        /* ISO_COSNS: TP4 CONNECTION LESS SERVICE over CONSNS */
                    194:        {
                    195:                TP_NRETRANS,    /* short p_Nretrans;  */
                    196:                40,             /* 20 sec */    /* short p_dr_ticks;  */
                    197: 
                    198:                40,             /* 20 sec */    /* short p_cc_ticks; */
                    199:                80,             /* 40 sec */    /* short p_dt_ticks; */
                    200: 
                    201:                120,            /* 1 min */     /* short p_x_ticks;      */
                    202:                360,            /* 3 min */     /* short p_cr_ticks;*/
                    203: 
                    204:                360,    /* 3 min */     /* short p_keepalive_ticks;*/
                    205:                20,             /* 10 sec */    /* short p_sendack_ticks;  */
                    206: 
                    207:                600,    /* 5 min */     /* short p_ref_ticks;   */
                    208:                480,    /* 4 min */     /* short p_inact_ticks; */
                    209: 
                    210:                (short) 100,                    /* short p_lcdtfract */
                    211:                (short) TP0_SOCKBUFSIZE,        /* short p_winsize */
                    212:                TP0_TPDUSIZE,                   /* u_char p_tpdusize */
                    213: 
                    214:                TPACK_WINDOW,                   /* 4 bits p_ack_strat */
                    215:                TPRX_USE_CW ,                   /* No fast start */ 
                    216:                                                                /* 4 bits p_rx_strat*/
                    217:                TP_CLASS_4 | TP_CLASS_0,/* 5 bits p_class */
                    218:                0,                                              /* 1 bit xtd format */
                    219:                1,                                              /* 1 bit xpd service */
                    220:                1,                                              /* 1 bit use_checksum */
                    221:                0,                                              /* 1 bit use net xpd */
                    222:                0,                                              /* 1 bit use rcc */
                    223:                0,                                              /* 1 bit use efc */
                    224:                0,                                              /* no disc indications */
                    225:                0,                                              /* don't change params */
                    226:                ISO_COSNS,                              /* p_netservice */
                    227:        },
                    228: };
                    229: 
                    230: #ifdef INET
                    231: int            in_putnetaddr();
                    232: int            in_getnetaddr();
                    233: int            in_cmpnetaddr();
                    234: int    in_putsufx(); 
                    235: int    in_getsufx(); 
                    236: int    in_recycle_tsuffix(); 
                    237: int    tpip_mtu(); 
                    238: int    in_pcbbind(); 
                    239: int    in_pcbconnect(); 
                    240: int    in_pcbdisconnect(); 
                    241: int    in_pcbdetach(); 
                    242: int    in_pcballoc(); 
                    243: int    tpip_output(); 
                    244: int    tpip_output_dg(); 
                    245: struct inpcb   tp_inpcb;
                    246: #endif INET
                    247: #ifdef ISO
                    248: int            iso_putnetaddr();
                    249: int            iso_getnetaddr();
                    250: int            iso_cmpnetaddr();
                    251: int    iso_putsufx(); 
                    252: int    iso_getsufx(); 
                    253: int    iso_recycle_tsuffix(); 
                    254: int            tpclnp_mtu(); 
                    255: int            iso_pcbbind(); 
                    256: int            iso_pcbconnect(); 
                    257: int            iso_pcbdisconnect(); 
                    258: int    iso_pcbdetach(); 
                    259: int    iso_pcballoc(); 
                    260: int    tpclnp_output(); 
                    261: int    tpclnp_output_dg(); 
                    262: int            iso_nlctloutput();
                    263: struct isopcb  tp_isopcb;
                    264: #endif ISO
                    265: #if NARGOXTWENTYFIVE > 0
                    266: int            iso_putnetaddr();
                    267: int            iso_getnetaddr();
                    268: int            iso_cmpnetaddr();
                    269: int    iso_putsufx(); 
                    270: int    iso_getsufx(); 
                    271: int    iso_recycle_tsuffix(); 
                    272: int            tpcons_mtu(); 
                    273: int            iso_pcbbind(); 
                    274: int            iso_pcbconnect(); 
                    275: int            iso_pcbdisconnect(); 
                    276: int    iso_pcbdetach(); 
                    277: int    iso_pcballoc(); 
                    278: int    tpcons_output(); 
                    279: int    tpcons_output_dg(); 
                    280: struct isopcb  tp_isopcb;
                    281: #endif NARGOXTWENTYFIVE
                    282: 
                    283: 
                    284: struct nl_protosw nl_protosw[] = {
                    285:        /* ISO_CLNS */
                    286: #ifdef ISO
                    287:        { AF_ISO, iso_putnetaddr, iso_getnetaddr, iso_cmpnetaddr,
                    288:                iso_putsufx, iso_getsufx,
                    289:                iso_recycle_tsuffix,
                    290:                tpclnp_mtu, iso_pcbbind, iso_pcbconnect,
                    291:                iso_pcbdisconnect,      iso_pcbdetach,
                    292:                iso_pcballoc,
                    293:                tpclnp_output, tpclnp_output_dg, iso_nlctloutput,
                    294:                (caddr_t) &tp_isopcb,
                    295:                },
                    296: #else
                    297:        { 0 },
                    298: #endif ISO
                    299:        /* IN_CLNS */
                    300: #ifdef INET
                    301:        { AF_INET, in_putnetaddr, in_getnetaddr, in_cmpnetaddr,
                    302:                in_putsufx, in_getsufx,
                    303:                in_recycle_tsuffix,
                    304:                tpip_mtu, in_pcbbind, in_pcbconnect,
                    305:                in_pcbdisconnect,       in_pcbdetach,
                    306:                in_pcballoc,
                    307:                tpip_output, tpip_output_dg, /* nl_ctloutput */ NULL,
                    308:                (caddr_t) &tp_inpcb,
                    309:                },
                    310: #else
                    311:        { 0 },
                    312: #endif INET
                    313:        /* ISO_CONS */
                    314: #if defined(ISO) && (NARGOXTWENTYFIVE > 0)
                    315:        { AF_ISO, iso_putnetaddr, iso_getnetaddr, iso_cmpnetaddr,
                    316:                iso_putsufx, iso_getsufx,
                    317:                iso_recycle_tsuffix,
                    318:                tpcons_mtu, iso_pcbbind, iso_pcbconnect,
                    319:                iso_pcbdisconnect,      iso_pcbdetach,
                    320:                iso_pcballoc,
                    321:                tpcons_output, tpcons_output_dg, iso_nlctloutput,
                    322:                (caddr_t) &tp_isopcb,
                    323:                },
                    324: #else
                    325:        { 0 },
                    326: #endif ISO_CONS
                    327:        /* End of protosw marker */
                    328:        { 0 }
                    329: };
                    330: 
                    331: /*
                    332:  * NAME:  tp_init()
                    333:  *
                    334:  * CALLED FROM:
                    335:  *  autoconf through the protosw structure
                    336:  *
                    337:  * FUNCTION:
                    338:  *  initialize tp machine
                    339:  *
                    340:  * RETURNS:  Nada
                    341:  *
                    342:  * SIDE EFFECTS:
                    343:  * 
                    344:  * NOTES:
                    345:  */
                    346: int
                    347: tp_init()
                    348: {
                    349:        static int      init_done=0;
                    350:        void            tp_timerinit();
                    351: 
                    352:        if (init_done++)
                    353:                return 0;
                    354: 
                    355: 
                    356:        /* FOR INET */
                    357:        tp_inpcb.inp_next = tp_inpcb.inp_prev = &tp_inpcb;
                    358:        /* FOR ISO */
                    359:        tp_isopcb.isop_next = tp_isopcb.isop_prev = &tp_isopcb;
                    360: 
                    361:     tp_start_win = 2;
                    362: 
                    363:        tp_timerinit();
                    364:        bzero((caddr_t)&tp_stat, sizeof(struct tp_stat));
                    365:        return 0;
                    366: }
                    367: 
                    368: /*
                    369:  * NAME:       tp_soisdisconnecting()
                    370:  *
                    371:  * CALLED FROM:
                    372:  *  tp.trans
                    373:  *
                    374:  * FUNCTION and ARGUMENTS:
                    375:  *  Set state of the socket (so) to reflect that fact that we're disconnectING
                    376:  *
                    377:  * RETURNS:    Nada
                    378:  *
                    379:  * SIDE EFFECTS:
                    380:  *
                    381:  * NOTES:
                    382:  *  This differs from the regular soisdisconnecting() in that the latter
                    383:  *  also sets the SS_CANTRECVMORE and SS_CANTSENDMORE flags.
                    384:  *  We don't want to set those flags because those flags will cause
                    385:  *  a SIGPIPE to be delivered in sosend() and we don't like that.
                    386:  *  If anyone else is sleeping on this socket, wake 'em up.
                    387:  */
                    388: void
                    389: tp_soisdisconnecting(so)
                    390:        register struct socket *so;
                    391: {
                    392:        soisdisconnecting(so);
                    393:        so->so_state &= ~SS_CANTSENDMORE;
                    394:        IFPERF(sototpcb(so))
                    395:                register struct tp_pcb *tpcb = sototpcb(so);
                    396:                u_int   fsufx, lsufx;
                    397: 
                    398:                bcopy ((caddr_t)tpcb->tp_fsuffix, (caddr_t)&fsufx, sizeof(u_int) );
                    399:                bcopy ((caddr_t)tpcb->tp_lsuffix, (caddr_t)&lsufx, sizeof(u_int) );
                    400: 
                    401:                tpmeas(tpcb->tp_lref, TPtime_close, &time, fsufx, lsufx, tpcb->tp_fref);
                    402:                tpcb->tp_perf_on = 0; /* turn perf off */
                    403:        ENDPERF
                    404: }
                    405: 
                    406: 
                    407: /*
                    408:  * NAME: tp_soisdisconnected()
                    409:  *
                    410:  * CALLED FROM:
                    411:  *     tp.trans        
                    412:  *
                    413:  * FUNCTION and ARGUMENTS:
                    414:  *  Set state of the socket (so) to reflect that fact that we're disconnectED
                    415:  *  Set the state of the reference structure to closed, and
                    416:  *  recycle the suffix.
                    417:  *  Start a reference timer.
                    418:  *
                    419:  * RETURNS:    Nada
                    420:  *
                    421:  * SIDE EFFECTS:
                    422:  *
                    423:  * NOTES:
                    424:  *  This differs from the regular soisdisconnected() in that the latter
                    425:  *  also sets the SS_CANTRECVMORE and SS_CANTSENDMORE flags.
                    426:  *  We don't want to set those flags because those flags will cause
                    427:  *  a SIGPIPE to be delivered in sosend() and we don't like that.
                    428:  *  If anyone else is sleeping on this socket, wake 'em up.
                    429:  */
                    430: void
                    431: tp_soisdisconnected(tpcb)
                    432:        register struct tp_pcb  *tpcb;
                    433: {
                    434:        register struct socket  *so = tpcb->tp_sock;
                    435: 
                    436:        soisdisconnecting(so);
                    437:        so->so_state &= ~SS_CANTSENDMORE;
                    438:        IFPERF(sototpcb(so))
                    439:                register struct tp_pcb *ttpcb = sototpcb(so);
                    440:                u_int   fsufx, lsufx;
                    441: 
                    442:                /* CHOKE */
                    443:                bcopy ((caddr_t)ttpcb->tp_fsuffix, (caddr_t)&fsufx, sizeof(u_int) );
                    444:                bcopy ((caddr_t)ttpcb->tp_lsuffix, (caddr_t)&lsufx, sizeof(u_int) );
                    445: 
                    446:                tpmeas(ttpcb->tp_lref, TPtime_close, 
                    447:                   &time, &lsufx, &fsufx, ttpcb->tp_fref);
                    448:                tpcb->tp_perf_on = 0; /* turn perf off */
                    449:        ENDPERF
                    450: 
                    451:        tpcb->tp_refp->tpr_state = REF_FROZEN;
                    452:        tp_recycle_tsuffix( tpcb );
                    453:        tp_etimeout(tpcb->tp_refp, TM_reference, 0,0,0, (int)tpcb->tp_refer_ticks);
                    454: }
                    455: 
                    456: int tp_maxrefopen;  /* highest reference # of the set of open tp connections */
                    457: 
                    458: /*
                    459:  * NAME:       tp_freeref()
                    460:  *
                    461:  * CALLED FROM:
                    462:  *  tp.trans when the reference timer goes off, and
                    463:  *  from tp_attach() and tp_detach() when a tpcb is partially set up but not
                    464:  *  set up enough to have a ref timer set for it, and it's discarded
                    465:  *  due to some sort of error or an early close()
                    466:  *
                    467:  * FUNCTION and ARGUMENTS:
                    468:  *  Frees the reference represented by (r) for re-use.
                    469:  *
                    470:  * RETURNS: Nothing
                    471:  * 
                    472:  * SIDE EFFECTS:
                    473:  *
                    474:  * NOTES:      better be called at clock priority !!!!!
                    475:  */
                    476: void
                    477: tp_freeref(r)
                    478:        register struct tp_ref *r;
                    479: {
                    480:        IFDEBUG(D_TIMER)
                    481:                printf("tp_freeref called for ref %d maxrefopen %d\n", 
                    482:                r - tp_ref, tp_maxrefopen);
                    483:        ENDDEBUG
                    484:        IFTRACE(D_TIMER)
                    485:                tptrace(TPPTmisc, "tp_freeref ref tp_maxrefopen",
                    486:                r - tp_ref, tp_maxrefopen, 0, 0);
                    487:        ENDTRACE
                    488:        r->tpr_state = REF_FREE;
                    489:        IFDEBUG(D_CONN)
                    490:                printf("tp_freeref: CLEARING tpr_pcb 0x%x\n", r->tpr_pcb);
                    491:        ENDDEBUG
                    492:        r->tpr_pcb = (struct tp_pcb *)0;
                    493: 
                    494:        r = &tp_ref[tp_maxrefopen];
                    495: 
                    496:        while( tp_maxrefopen > 0 ) {
                    497:                if(r->tpr_state )
                    498:                        break;
                    499:                tp_maxrefopen--;
                    500:                r--;
                    501:        }
                    502:        IFDEBUG(D_TIMER)
                    503:                printf("tp_freeref ends w/ maxrefopen %d\n", tp_maxrefopen);
                    504:        ENDDEBUG
                    505: }
                    506: 
                    507: /*
                    508:  * NAME:  tp_getref()
                    509:  *
                    510:  * CALLED FROM:
                    511:  *  tp_attach()
                    512:  *
                    513:  * FUNCTION and ARGUMENTS:
                    514:  *  obtains the next free reference and allocates the appropriate
                    515:  *  ref structure, links that structure to (tpcb) 
                    516:  *
                    517:  * RETURN VALUE:
                    518:  *     a reference number
                    519:  *  or TP_ENOREF
                    520:  *
                    521:  * SIDE EFFECTS:
                    522:  *
                    523:  * NOTES:
                    524:  */
                    525: static RefNum
                    526: tp_getref(tpcb) 
                    527:        register struct tp_pcb *tpcb;
                    528: {
                    529:        register struct tp_ref  *r = tp_ref; 
                    530:        register int                    i=1;
                    531: 
                    532:        r++; /* tp_ref[0] is never used */
                    533: 
                    534:        /* REF_FREE is zero */
                    535:        while( r->tpr_state ) {
                    536:                r++; 
                    537:                if ( i == N_TPREF ) {
                    538:                        return TP_ENOREF;
                    539:                }
                    540:                i++;
                    541:        }
                    542:        r->tpr_state = REF_OPENING;
                    543:        if (tp_maxrefopen < i) 
                    544:                tp_maxrefopen = i;
                    545:        r->tpr_pcb = tpcb;
                    546:        tpcb->tp_refp = r;
                    547: 
                    548:        return i;
                    549: }
                    550: 
                    551: /*
                    552:  * NAME: tp_attach()
                    553:  *
                    554:  * CALLED FROM:
                    555:  *     tp_usrreq, PRU_ATTACH
                    556:  *
                    557:  * FUNCTION and ARGUMENTS:
                    558:  *  given a socket (so) and a protocol family (dom), allocate a tpcb
                    559:  *  and ref structure, initialize everything in the structures that
                    560:  *  needs to be initialized.
                    561:  *
                    562:  * RETURN VALUE:
                    563:  *  0 ok
                    564:  *  EINVAL if DEBUG(X) in is on and a disaster has occurred
                    565:  *  ENOPROTOOPT if TP hasn't been configured or if the
                    566:  *   socket wasn't created with tp as its protocol
                    567:  *  EISCONN if this socket is already part of a connection
                    568:  *  ETOOMANYREFS if ran out of tp reference numbers.
                    569:  *  E* whatever error is returned from soreserve()
                    570:  *    for from the network-layer pcb allocation routine
                    571:  *
                    572:  * SIDE EFFECTS:
                    573:  *
                    574:  * NOTES:
                    575:  */
                    576: tp_attach(so, dom)
                    577:        struct socket   *so;
                    578:        int                     dom;
                    579: {
                    580:        register struct tp_pcb  *tpcb;
                    581:        int                                     error;
                    582:        int                                     protocol = so->so_proto->pr_protocol;
                    583:        extern struct tp_conn_param tp_conn_param[];
                    584: 
                    585:        IFDEBUG(D_CONN)
                    586:                printf("tp_attach:dom 0x%x so 0x%x ", dom, so);
                    587:        ENDDEBUG
                    588:        IFTRACE(D_CONN)
                    589:                tptrace(TPPTmisc, "tp_attach:dom so", dom, so, 0, 0);
                    590:        ENDTRACE
                    591:        if ( ! tp_param.tpp_configed ) {
                    592:                error = ENOPROTOOPT; /* protocol not available */
                    593:                goto bad2;
                    594:        }
                    595: 
                    596:        if (so->so_pcb != NULL) { 
                    597:                return EISCONN; /* socket already part of a connection*/
                    598:        }
                    599: 
                    600:        error = soreserve(so, TP_SOCKBUFSIZE, TP_SOCKBUFSIZE);
                    601:                /* later an ioctl will allow reallocation IF still in closed state */
                    602: 
                    603:        if (error)
                    604:                goto bad2;
                    605: 
                    606:        MALLOC(tpcb, struct tp_pcb *, sizeof(*tpcb), M_PCB, M_NOWAIT);
                    607:        if (tpcb == NULL) {
                    608:                error = ENOBUFS;
                    609:                goto bad2;
                    610:        }
                    611:        bzero( (caddr_t)tpcb, sizeof (struct tp_pcb) );
                    612: 
                    613:        if ( ((tpcb->tp_lref = tp_getref(tpcb)) &  TP_ENOREF) != 0 ) { 
                    614:                error = ETOOMANYREFS; 
                    615:                goto bad3;
                    616:        }
                    617:        tpcb->tp_sock =  so;
                    618:        tpcb->tp_domain = dom;
                    619:        if (protocol<ISOPROTO_TP4) {
                    620:                tpcb->tp_netservice = ISO_CONS;
                    621:                tpcb->tp_snduna = (SeqNum) -1;/* kludge so the pseudo-ack from the CR/CC
                    622:                                                                 * will generate correct fake-ack values
                    623:                                                                 */
                    624:        } else {
                    625:                tpcb->tp_netservice = (dom== AF_INET)?IN_CLNS:ISO_CLNS;
                    626:                /* the default */
                    627:        }
                    628:        tpcb->_tp_param = tp_conn_param[tpcb->tp_netservice];
                    629: 
                    630:        tpcb->tp_cong_win = 1;  
                    631:        tpcb->tp_state = TP_CLOSED;
                    632:        tpcb->tp_vers  = TP_VERSION;
                    633: 
                    634:                   /* Spec says default is 128 octets,
                    635:                        * that is, if the tpdusize argument never appears, use 128.
                    636:                        * As the initiator, we will always "propose" the 2048
                    637:                        * size, that is, we will put this argument in the CR 
                    638:                        * always, but accept what the other side sends on the CC.
                    639:                        * If the initiator sends us something larger on a CR,
                    640:                        * we'll respond w/ this.
                    641:                        * Our maximum is 4096.  See tp_chksum.c comments.
                    642:                        */
                    643:        tpcb->tp_l_tpdusize = 1 << tpcb->tp_tpdusize;
                    644: 
                    645:        tpcb->tp_seqmask  = TP_NML_FMT_MASK;
                    646:        tpcb->tp_seqbit  =  TP_NML_FMT_BIT;
                    647:        tpcb->tp_seqhalf  =  tpcb->tp_seqbit >> 1;
                    648:        tpcb->tp_sndhiwat = (SeqNum) - 1; /* a kludge but it works */
                    649:        tpcb->tp_s_subseq = 0;
                    650: 
                    651:        /* attach to a network-layer protoswitch */
                    652:        /* new way */
                    653:        tpcb->tp_nlproto = & nl_protosw[tpcb->tp_netservice];
                    654:        ASSERT( tpcb->tp_nlproto->nlp_afamily == tpcb->tp_domain);
                    655: #ifdef notdef
                    656:        /* OLD WAY */
                    657:        /* TODO: properly, this search would be on the basis of 
                    658:        * domain,netservice or just netservice only (if you have
                    659:        * IN_CLNS, ISO_CLNS, and ISO_CONS)
                    660:        */
                    661:        tpcb->tp_nlproto = nl_protosw;
                    662:        while(tpcb->tp_nlproto->nlp_afamily != tpcb->tp_domain )  {
                    663:                if( tpcb->tp_nlproto->nlp_afamily == 0 ) {
                    664:                        error = EAFNOSUPPORT;
                    665:                        goto bad4;
                    666:                }
                    667:                tpcb->tp_nlproto ++;
                    668:        }
                    669: #endif notdef
                    670: 
                    671:        /* xx_pcballoc sets so_pcb */
                    672:        if ( error =  (tpcb->tp_nlproto->nlp_pcballoc) ( 
                    673:                                                        so, tpcb->tp_nlproto->nlp_pcblist ) ) {
                    674:                goto bad4;
                    675:        }
                    676: 
                    677:        if( dom == AF_INET )
                    678:                sotoinpcb(so)->inp_ppcb = (caddr_t) tpcb;
                    679:                /* nothing to do for iso case */
                    680: 
                    681:        tpcb->tp_npcb = (caddr_t) so->so_pcb;
                    682:        so->so_tpcb = (caddr_t) tpcb;
                    683: 
                    684:        return 0;
                    685: 
                    686: bad4:
                    687:        IFDEBUG(D_CONN)
                    688:                printf("BAD4 in tp_attach, so 0x%x\n", so);
                    689:        ENDDEBUG
                    690:        tp_freeref(tpcb->tp_refp);
                    691: 
                    692: bad3:
                    693:        IFDEBUG(D_CONN)
                    694:                printf("BAD3 in tp_attach, so 0x%x\n", so);
                    695:        ENDDEBUG
                    696: 
                    697:        free((caddr_t)tpcb, M_PCB); /* never a cluster  */
                    698: 
                    699: bad2:
                    700:        IFDEBUG(D_CONN)
                    701:                printf("BAD2 in tp_attach, so 0x%x\n", so);
                    702:        ENDDEBUG
                    703:        so->so_pcb = 0;
                    704:        so->so_tpcb = 0;
                    705:        sofree(so);
                    706: 
                    707: /*bad:*/
                    708:        IFDEBUG(D_CONN)
                    709:                printf("BAD in tp_attach, so 0x%x\n", so);
                    710:        ENDDEBUG
                    711:        return error;
                    712: }
                    713: 
                    714: /*
                    715:  * NAME:  tp_detach()
                    716:  *
                    717:  * CALLED FROM:
                    718:  *     tp.trans, on behalf of a user close request
                    719:  *  and when the reference timer goes off
                    720:  * (if the disconnect  was initiated by the protocol entity 
                    721:  * rather than by the user)
                    722:  *
                    723:  * FUNCTION and ARGUMENTS:
                    724:  *  remove the tpcb structure from the list of active or
                    725:  *  partially active connections, recycle all the mbufs
                    726:  *  associated with the pcb, ref structure, sockbufs, etc.
                    727:  *  Only free the ref structure if you know that a ref timer
                    728:  *  wasn't set for this tpcb.
                    729:  *
                    730:  * RETURNS:  Nada
                    731:  *
                    732:  * SIDE EFFECTS:
                    733:  *
                    734:  * NOTES:
                    735:  *  tp_soisdisconnected() was already when this is called
                    736:  */
                    737: void
                    738: tp_detach(tpcb)
                    739:        register struct tp_pcb  *tpcb;
                    740: {
                    741:        void                                    tp_freeref();
                    742:        register struct socket   *so = tpcb->tp_sock;
                    743: 
                    744:        IFDEBUG(D_CONN)
                    745:                printf("tp_detach(tpcb 0x%x, so 0x%x)\n",
                    746:                        tpcb,so);
                    747:        ENDDEBUG
                    748:        IFTRACE(D_CONN)
                    749:                tptraceTPCB(TPPTmisc, "tp_detach tpcb so lsufx", 
                    750:                        tpcb, so, *(u_short *)(tpcb->tp_lsuffix), 0);
                    751:        ENDTRACE
                    752: 
                    753:        if (so->so_head) {
                    754:                if (!soqremque(so, 0) && !soqremque(so, 1))
                    755:                        panic("sofree dq");
                    756:                so->so_head = 0;
                    757:        }
                    758: 
                    759:        IFDEBUG(D_CONN)
                    760:                printf("tp_detach(freeing RTC list snduna 0x%x rcvnxt 0x%x)\n",
                    761:                tpcb->tp_snduna_rtc,
                    762:                tpcb->tp_rcvnxt_rtc);
                    763:        ENDDEBUG
                    764: 
                    765: #define FREE_RTC_LIST(XXX)\
                    766:        { register struct tp_rtc *xxr = XXX, *xxs; while (xxr) {\
                    767:                xxs = xxr->tprt_next;\
                    768:                m_freem( xxr->tprt_data );\
                    769:                m_free( dtom(xxr) ); xxr = xxs; }\
                    770:                XXX = (struct tp_rtc *)0;\
                    771:        }
                    772: 
                    773:        FREE_RTC_LIST( tpcb->tp_snduna_rtc );
                    774:        tpcb->tp_sndhiwat_rtc = (struct tp_rtc *)0;
                    775: 
                    776:        FREE_RTC_LIST( tpcb->tp_rcvnxt_rtc );
                    777: 
                    778: #undef FREE_RTC_LIST
                    779: 
                    780:        IFDEBUG(D_CONN)
                    781:                printf("calling (...nlproto->...)(0x%x, so 0x%x)\n", 
                    782:                        so->so_pcb, so);
                    783:                printf("so 0x%x so_head 0x%x,  qlen %d q0len %d qlimit %d\n", 
                    784:                so,  so->so_head,
                    785:                so->so_q0len, so->so_qlen, so->so_qlimit);
                    786:        ENDDEBUG
                    787: 
                    788:        if ( tpcb->tp_flags & (TPF_DISC_DATA_OUT | TPF_CONN_DATA_OUT ) )  {
                    789:                ASSERT( so->so_snd.sb_cc != 0 );
                    790:                IFDEBUG(D_CONN)
                    791:                        printf(
                    792:                        "detach, flags 0x%x doing sbdrop on so_snd, mb 0x%x cc 0x%x\n", 
                    793:                                tpcb->tp_flags, so->so_snd.sb_mb, so->so_snd.sb_cc);
                    794:                        dump_mbuf( so->so_snd.sb_mb, "detach so snd: \n");
                    795:                ENDDEBUG
                    796:                if ( so->so_snd.sb_cc != 0 )
                    797:                        sbflush(&so->so_snd);
                    798:                tpcb->tp_flags &= ~(TPF_CONN_DATA_OUT | TPF_DISC_DATA_OUT); 
                    799:        }
                    800:        if ( tpcb->tp_flags & (TPF_DISC_DATA_IN | TPF_CONN_DATA_IN ) ) {
                    801:                ASSERT( tpcb->tp_Xrcv.sb_cc != 0 );
                    802:                IFDEBUG(D_CONN)
                    803:                        printf(
                    804:                        "detach, flags 0x%x doing sbdrop on tp_Xrcv, mb 0x%x cc 0x%x\n", 
                    805:                                tpcb->tp_flags, tpcb->tp_Xrcv.sb_mb, tpcb->tp_Xrcv.sb_cc);
                    806:                        dump_mbuf( tpcb->tp_Xrcv.sb_mb, "detach Xrcv: \n");
                    807:                ENDDEBUG
                    808:                if( tpcb->tp_Xrcv.sb_cc != 0 )
                    809:                        sbdrop(&tpcb->tp_Xrcv, (int)tpcb->tp_Xrcv.sb_cc);
                    810:                tpcb->tp_flags &= ~(TPF_CONN_DATA_IN | TPF_DISC_DATA_IN); 
                    811:        }
                    812: 
                    813:        IFDEBUG(D_CONN)
                    814:                printf("so_snd at 0x%x so_rcv at 0x%x\n", &so->so_snd, &so->so_rcv);
                    815:                dump_mbuf(so->so_snd.sb_mb, "so_snd at detach ");
                    816:                printf("about to call LL detach, nlproto 0x%x, nl_detach 0x%x\n",
                    817:                                tpcb->tp_nlproto, tpcb->tp_nlproto->nlp_pcbdetach);
                    818:        ENDDEBUG
                    819: 
                    820:                
                    821:                
                    822:        (tpcb->tp_nlproto->nlp_pcbdetach)((struct inpcb *)so->so_pcb);
                    823:                                /* does an sofree(so) */
                    824: 
                    825:        IFDEBUG(D_CONN)
                    826:                printf("after xxx_pcbdetach\n");
                    827:        ENDDEBUG
                    828: 
                    829:        if( tpcb->tp_refp->tpr_state == REF_OPENING ) {
                    830:                /* no connection existed here so no reference timer will be called */
                    831:                IFDEBUG(D_CONN)
                    832:                        printf("SETTING ref %d, 0x%x to REF_FREE\n", tpcb->tp_lref,
                    833:                        tpcb->tp_refp - &tp_ref[0]);
                    834:                ENDDEBUG
                    835: 
                    836:                tp_freeref(tpcb->tp_refp);
                    837:        }
                    838: 
                    839:        if (tpcb->tp_Xsnd.sb_mb) {
                    840:                printf("Unsent Xdata on detach; would panic");
                    841:                sbflush(&tpcb->tp_Xsnd);
                    842:        }
                    843:        so->so_tpcb = (caddr_t)0;
                    844: 
                    845:        /* 
                    846:         * Get rid of the cluster mbuf allocated for performance measurements, if
                    847:         * there is one.  Note that tpcb->tp_perf_on says nothing about whether or 
                    848:         * not a cluster mbuf was allocated, so you have to check for a pointer 
                    849:         * to one (that is, we need the TP_PERF_MEASs around the following section 
                    850:         * of code, not the IFPERFs)
                    851:         */
                    852: #ifdef TP_PERF_MEAS
                    853:        if(tpcb->tp_p_mbuf) {
                    854:                register struct mbuf *m = tpcb->tp_p_mbuf;
                    855:                struct mbuf *n;
                    856:                IFDEBUG(D_PERF_MEAS)
                    857:                        printf("freeing tp_p_meas 0x%x  ", tpcb->tp_p_meas);
                    858:                ENDDEBUG
                    859:                do {
                    860:                    MFREE(m, n);
                    861:                    m = n;
                    862:                } while (n);
                    863:                tpcb->tp_p_meas = 0;
                    864:                tpcb->tp_p_mbuf = 0;
                    865:        }
                    866: #endif TP_PERF_MEAS
                    867: 
                    868:        IFDEBUG(D_CONN)
                    869:                printf( "end of detach, NOT single, tpcb 0x%x\n", tpcb);
                    870:        ENDDEBUG
                    871:        /* free((caddr_t)tpcb, M_PCB); WHere to put this ? */
                    872: }

unix.superglobalmegacorp.com

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