Annotation of Net2/netiso/tp_pcb.c, revision 1.1.1.3

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

unix.superglobalmegacorp.com

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