Annotation of kernel/bsd/netiso/tp_pcb.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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