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

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

unix.superglobalmegacorp.com

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