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

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