Annotation of Net2/netiso/tp_pcb.c, revision 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.