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