|
|
1.1 ! root 1: /*- ! 2: * Copyright (c) 1991 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms, with or without ! 6: * modification, are permitted provided that the following conditions ! 7: * are met: ! 8: * 1. Redistributions of source code must retain the above copyright ! 9: * notice, this list of conditions and the following disclaimer. ! 10: * 2. Redistributions in binary form must reproduce the above copyright ! 11: * notice, this list of conditions and the following disclaimer in the ! 12: * documentation and/or other materials provided with the distribution. ! 13: * 3. All advertising materials mentioning features or use of this software ! 14: * must display the following acknowledgement: ! 15: * This product includes software developed by the University of ! 16: * California, Berkeley and its contributors. ! 17: * 4. Neither the name of the University nor the names of its contributors ! 18: * may be used to endorse or promote products derived from this software ! 19: * without specific prior written permission. ! 20: * ! 21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 31: * SUCH DAMAGE. ! 32: * ! 33: * @(#)tp_pcb.h 7.9 (Berkeley) 5/6/91 ! 34: */ ! 35: ! 36: /*********************************************************** ! 37: Copyright IBM Corporation 1987 ! 38: ! 39: All Rights Reserved ! 40: ! 41: Permission to use, copy, modify, and distribute this software and its ! 42: documentation for any purpose and without fee is hereby granted, ! 43: provided that the above copyright notice appear in all copies and that ! 44: both that copyright notice and this permission notice appear in ! 45: supporting documentation, and that the name of IBM not be ! 46: used in advertising or publicity pertaining to distribution of the ! 47: software without specific, written prior permission. ! 48: ! 49: IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ! 50: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ! 51: IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 52: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ! 53: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ! 54: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ! 55: SOFTWARE. ! 56: ! 57: ******************************************************************/ ! 58: ! 59: /* ! 60: * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison ! 61: */ ! 62: /* ! 63: * ARGO TP ! 64: * ! 65: * $Header: tp_pcb.h,v 5.2 88/11/18 17:09:32 nhall Exp $ ! 66: * $Source: /usr/argo/sys/netiso/RCS/tp_pcb.h,v $ ! 67: * ! 68: * ! 69: * This file defines the transport protocol control block (tpcb). ! 70: * and a bunch of #define values that are used in the tpcb. ! 71: */ ! 72: ! 73: #ifndef __TP_PCB__ ! 74: #define __TP_PCB__ ! 75: ! 76: #include "../netiso/tp_param.h" ! 77: #include "../netiso/tp_timer.h" ! 78: #include "../netiso/tp_user.h" ! 79: #ifndef sblock ! 80: #include "socketvar.h" ! 81: #endif sblock ! 82: ! 83: /* NOTE: the code depends on REF_CLOSED > REF_OPEN > the rest, and ! 84: * on REF_FREE being zero ! 85: * ! 86: * Possible improvement: ! 87: * think about merging the tp_ref w/ the tpcb and doing a search ! 88: * through the tpcb list, from tpb. This would slow down lookup ! 89: * during data transfer ! 90: * It would be a little nicer also to have something based on the ! 91: * clock (like top n bits of the reference is part of the clock, to ! 92: * minimize the likelihood of reuse after a crash) ! 93: * also, need to keep the timer servicing part to a minimum (although ! 94: * the cost of this is probably independent of whether the timers are ! 95: * in the pcb or in an array.. ! 96: * Last, would have to make the number of timers a function of the amount of ! 97: * mbufs available, plus some for the frozen references. ! 98: * ! 99: * Possible improvement: ! 100: * Might not need the ref_state stuff either... ! 101: * REF_FREE could correspond to tp_state == CLOSED or nonexistend tpcb, ! 102: * REF_OPEN to tp_state anywhere from AK_WAIT or CR_SENT to CLOSING ! 103: * REF_OPENING could correspond to LISTENING, because that's the ! 104: * way it's used, not because the correspondence is exact. ! 105: * REF_CLOSED could correspond to REFWAIT ! 106: */ ! 107: #define REF_FROZEN 3 /* has ref timer only */ ! 108: #define REF_OPEN 2 /* has timers, possibly active */ ! 109: #define REF_OPENING 1 /* in use (has a pcb) but no timers */ ! 110: #define REF_FREE 0 /* free to reallocate */ ! 111: ! 112: #define N_CTIMERS 4 ! 113: #define N_ETIMERS 2 ! 114: ! 115: struct tp_ref { ! 116: u_char tpr_state; /* values REF_FROZEN, etc. above */ ! 117: struct Ccallout tpr_callout[N_CTIMERS]; /* C timers */ ! 118: struct Ecallout tpr_calltodo; /* list of active E timers */ ! 119: struct tp_pcb *tpr_pcb; /* back ptr to PCB */ ! 120: }; ! 121: ! 122: struct tp_param { ! 123: /* PER system stuff (one static structure instead of a bunch of names) */ ! 124: unsigned tpp_configed:1; /* Has TP been initialized? */ ! 125: }; ! 126: ! 127: ! 128: /* ! 129: * retransmission control and performance measurement ! 130: */ ! 131: struct tp_rtc { ! 132: struct tp_rtc *tprt_next; /* ptr to next rtc structure in the list */ ! 133: SeqNum tprt_seq; /* seq # of this TPDU */ ! 134: int tprt_eot; /* Will this TPDU have the eot bit set? */ ! 135: int tprt_octets;/* # octets in this TPDU */ ! 136: struct mbuf *tprt_data; /* ptr to the octets of data */ ! 137: }; ! 138: ! 139: struct nl_protosw { ! 140: int nlp_afamily; /* address family */ ! 141: int (*nlp_putnetaddr)(); /* puts addresses in nl pcb */ ! 142: int (*nlp_getnetaddr)(); /* gets addresses from nl pcb */ ! 143: int (*nlp_cmpnetaddr)(); /* compares address in pcb with sockaddr */ ! 144: int (*nlp_putsufx)(); /* puts transport suffixes in nl pcb */ ! 145: int (*nlp_getsufx)(); /* gets transport suffixes from nl pcb */ ! 146: int (*nlp_recycle_suffix)();/* clears suffix from nl pcb */ ! 147: int (*nlp_mtu)(); /* figures out mtu based on nl used */ ! 148: int (*nlp_pcbbind)(); /* bind to pcb for net level */ ! 149: int (*nlp_pcbconn)(); /* connect for net level */ ! 150: int (*nlp_pcbdisc)(); /* disconnect net level */ ! 151: int (*nlp_pcbdetach)(); /* detach net level pcb */ ! 152: int (*nlp_pcballoc)(); /* allocate a net level pcb */ ! 153: int (*nlp_output)(); /* prepare a packet to give to nl */ ! 154: int (*nlp_dgoutput)(); /* prepare a packet to give to nl */ ! 155: int (*nlp_ctloutput)(); /* hook for network set/get options */ ! 156: caddr_t nlp_pcblist; /* list of xx_pcb's for connections */ ! 157: }; ! 158: ! 159: ! 160: struct tp_pcb { ! 161: struct tp_pcb *tp_next; ! 162: struct tp_pcb *tp_prev; ! 163: struct tp_pcb *tp_nextlisten; /* chain all listeners */ ! 164: u_short tp_state; /* state of fsm */ ! 165: short tp_retrans; /* # times can still retrans */ ! 166: struct tp_ref *tp_refp; /* rest of pcb */ ! 167: caddr_t tp_npcb; /* to lower layer pcb */ ! 168: struct nl_protosw *tp_nlproto; /* lower-layer dependent routines */ ! 169: struct socket *tp_sock; /* back ptr */ ! 170: ! 171: ! 172: RefNum tp_lref; /* local reference */ ! 173: RefNum tp_fref; /* foreign reference */ ! 174: ! 175: u_int tp_seqmask; /* mask for seq space */ ! 176: u_int tp_seqbit; /* bit for seq number wraparound */ ! 177: u_int tp_seqhalf; /* half the seq space */ ! 178: ! 179: /* credit & sequencing info for SENDING */ ! 180: u_short tp_fcredit; /* current remote credit in # packets */ ! 181: ! 182: u_short tp_cong_win; /* congestion window : set to 1 on ! 183: * source quench ! 184: * Minimizes the amount of retrans- ! 185: * missions (independently of the ! 186: * retrans strategy). Increased ! 187: * by one for each good ack received. ! 188: * Minimizes the amount sent in a ! 189: * regular tp_send() also. ! 190: */ ! 191: u_int tp_ackrcvd; /* ACKs received since the send window was updated */ ! 192: SeqNum tp_last_retrans; ! 193: SeqNum tp_retrans_hiwat; ! 194: SeqNum tp_snduna; /* seq # of lowest unacked DT */ ! 195: struct tp_rtc *tp_snduna_rtc; /* lowest unacked stuff sent so far */ ! 196: SeqNum tp_sndhiwat; /* highest seq # sent so far */ ! 197: ! 198: struct tp_rtc *tp_sndhiwat_rtc; /* last stuff sent so far */ ! 199: int tp_Nwindow; /* for perf. measurement */ ! 200: struct mbuf *tp_ucddata; /* user connect/disconnect data */ ! 201: ! 202: /* credit & sequencing info for RECEIVING */ ! 203: SeqNum tp_sent_lcdt; /* cdt according to last ack sent */ ! 204: SeqNum tp_sent_uwe; /* uwe according to last ack sent */ ! 205: SeqNum tp_sent_rcvnxt; /* rcvnxt according to last ack sent ! 206: * needed for perf measurements only ! 207: */ ! 208: u_short tp_lcredit; /* current local credit in # packets */ ! 209: SeqNum tp_rcvnxt; /* next DT seq # expect to recv */ ! 210: struct tp_rtc *tp_rcvnxt_rtc; /* unacked stuff recvd out of order */ ! 211: ! 212: /* receiver congestion state stuff ... */ ! 213: u_int tp_win_recv; ! 214: ! 215: /* receive window as a scaled int (8 bit fraction part) */ ! 216: ! 217: struct cong_sample { ! 218: ushort cs_size; /* current window size */ ! 219: ushort cs_received; /* PDUs received in this sample */ ! 220: ushort cs_ce_set; /* PDUs received in this sample with CE bit set */ ! 221: } tp_cong_sample; ! 222: ! 223: ! 224: /* parameters per-connection controllable by user */ ! 225: struct tp_conn_param _tp_param; ! 226: ! 227: #define tp_Nretrans _tp_param.p_Nretrans ! 228: #define tp_dr_ticks _tp_param.p_dr_ticks ! 229: #define tp_cc_ticks _tp_param.p_cc_ticks ! 230: #define tp_dt_ticks _tp_param.p_dt_ticks ! 231: #define tp_xpd_ticks _tp_param.p_x_ticks ! 232: #define tp_cr_ticks _tp_param.p_cr_ticks ! 233: #define tp_keepalive_ticks _tp_param.p_keepalive_ticks ! 234: #define tp_sendack_ticks _tp_param.p_sendack_ticks ! 235: #define tp_refer_ticks _tp_param.p_ref_ticks ! 236: #define tp_inact_ticks _tp_param.p_inact_ticks ! 237: #define tp_xtd_format _tp_param.p_xtd_format ! 238: #define tp_xpd_service _tp_param.p_xpd_service ! 239: #define tp_ack_strat _tp_param.p_ack_strat ! 240: #define tp_rx_strat _tp_param.p_rx_strat ! 241: #define tp_use_checksum _tp_param.p_use_checksum ! 242: #define tp_use_efc _tp_param.p_use_efc ! 243: #define tp_use_nxpd _tp_param.p_use_nxpd ! 244: #define tp_use_rcc _tp_param.p_use_rcc ! 245: #define tp_tpdusize _tp_param.p_tpdusize ! 246: #define tp_class _tp_param.p_class ! 247: #define tp_winsize _tp_param.p_winsize ! 248: #define tp_no_disc_indications _tp_param.p_no_disc_indications ! 249: #define tp_dont_change_params _tp_param.p_dont_change_params ! 250: #define tp_netservice _tp_param.p_netservice ! 251: #define tp_version _tp_param.p_version ! 252: ! 253: int tp_l_tpdusize; ! 254: /* whereas tp_tpdusize is log2(the negotiated max size) ! 255: * l_tpdusize is the size we'll use when sending, in # chars ! 256: */ ! 257: ! 258: struct timeval tp_rtv; /* max round-trip time variance */ ! 259: struct timeval tp_rtt; /* smoothed round-trip time */ ! 260: struct timeval tp_rttemit[ TP_RTT_NUM + 1 ]; ! 261: /* times that the last TP_RTT_NUM DT_TPDUs were emitted */ ! 262: unsigned ! 263: tp_sendfcc:1, /* shall next ack include FCC parameter? */ ! 264: tp_trace:1, /* is this pcb being traced? (not used yet) */ ! 265: tp_perf_on:1, /* 0/1 -> performance measuring on */ ! 266: tp_reneged:1, /* have we reneged on cdt since last ack? */ ! 267: tp_decbit:3, /* dec bit was set, we're in reneg mode */ ! 268: tp_cebit_off:1, /* the real DEC bit algorithms not in use */ ! 269: tp_flags:8, /* values: */ ! 270: #define TPF_CONN_DATA_OUT TPFLAG_CONN_DATA_OUT ! 271: #define TPF_CONN_DATA_IN TPFLAG_CONN_DATA_IN ! 272: #define TPF_DISC_DATA_IN TPFLAG_DISC_DATA_IN ! 273: #define TPF_DISC_DATA_OUT TPFLAG_DISC_DATA_OUT ! 274: #define TPF_XPD_PRESENT TPFLAG_XPD_PRESENT ! 275: #define TPF_NLQOS_PDN TPFLAG_NLQOS_PDN ! 276: #define TPF_PEER_ON_SAMENET TPFLAG_PEER_ON_SAMENET ! 277: ! 278: #define PEER_IS_LOCAL(t) \ ! 279: (((t)->tp_flags & TPF_PEER_ON_SAME_NET)==TPF_PEER_ON_SAME_NET) ! 280: #define USES_PDN(t) \ ! 281: (((t)->tp_flags & TPF_NLQOS_PDN)==TPF_NLQOS_PDN) ! 282: ! 283: tp_unused:16; ! 284: ! 285: ! 286: #ifdef TP_PERF_MEAS ! 287: /* performance stats - see tp_stat.h */ ! 288: struct tp_pmeas *tp_p_meas; ! 289: struct mbuf *tp_p_mbuf; ! 290: #endif TP_PERF_MEAS ! 291: /* addressing */ ! 292: u_short tp_domain; /* domain (INET, ISO) */ ! 293: /* for compatibility with the *old* way and with INET, be sure that ! 294: * that lsuffix and fsuffix are aligned to a short addr. ! 295: * having them follow the u_short *suffixlen should suffice (choke) ! 296: */ ! 297: u_short tp_fsuffixlen; /* foreign suffix */ ! 298: char tp_fsuffix[MAX_TSAP_SEL_LEN]; ! 299: u_short tp_lsuffixlen; /* local suffix */ ! 300: char tp_lsuffix[MAX_TSAP_SEL_LEN]; ! 301: #define SHORT_LSUFXP(tpcb) ((short *)((tpcb)->tp_lsuffix)) ! 302: #define SHORT_FSUFXP(tpcb) ((short *)((tpcb)->tp_fsuffix)) ! 303: ! 304: u_char tp_vers; /* protocol version */ ! 305: u_char tp_peer_acktime; /* used to compute DT retrans time */ ! 306: ! 307: struct sockbuf tp_Xsnd; /* for expedited data */ ! 308: /* struct sockbuf tp_Xrcv; /* for expedited data */ ! 309: #define tp_Xrcv tp_sock->so_rcv ! 310: SeqNum tp_Xsndnxt; /* next XPD seq # to send */ ! 311: SeqNum tp_Xuna; /* seq # of unacked XPD */ ! 312: SeqNum tp_Xrcvnxt; /* next XPD seq # expect to recv */ ! 313: ! 314: /* AK subsequencing */ ! 315: u_short tp_s_subseq; /* next subseq to send */ ! 316: u_short tp_r_subseq; /* highest recv subseq */ ! 317: ! 318: }; ! 319: ! 320: u_int tp_start_win; ! 321: ! 322: #define ROUND(scaled_int) (((scaled_int) >> 8) + (((scaled_int) & 0x80) ? 1:0)) ! 323: ! 324: /* to round off a scaled int with an 8 bit fraction part */ ! 325: ! 326: #define CONG_INIT_SAMPLE(pcb) \ ! 327: pcb->tp_cong_sample.cs_received = \ ! 328: pcb->tp_cong_sample.cs_ce_set = 0; \ ! 329: pcb->tp_cong_sample.cs_size = MAX(pcb->tp_lcredit, 1) << 1; ! 330: ! 331: #define CONG_UPDATE_SAMPLE(pcb, ce_bit) \ ! 332: pcb->tp_cong_sample.cs_received++; \ ! 333: if (ce_bit) { \ ! 334: pcb->tp_cong_sample.cs_ce_set++; \ ! 335: } \ ! 336: if (pcb->tp_cong_sample.cs_size <= pcb->tp_cong_sample.cs_received) { \ ! 337: if ((pcb->tp_cong_sample.cs_ce_set << 1) >= \ ! 338: pcb->tp_cong_sample.cs_size ) { \ ! 339: pcb->tp_win_recv -= pcb->tp_win_recv >> 3; /* multiply by .875 */ \ ! 340: pcb->tp_win_recv = MAX(1 << 8, pcb->tp_win_recv); \ ! 341: } \ ! 342: else { \ ! 343: pcb->tp_win_recv += (1 << 8); /* add one to the scaled int */ \ ! 344: } \ ! 345: pcb->tp_lcredit = ROUND(pcb->tp_win_recv); \ ! 346: CONG_INIT_SAMPLE(pcb); \ ! 347: } ! 348: ! 349: #define CONG_ACK(pcb, seq) \ ! 350: { int newacks = SEQ_SUB(pcb, seq, pcb->tp_snduna); \ ! 351: if (newacks > 0) { \ ! 352: pcb->tp_ackrcvd += newacks; \ ! 353: if (pcb->tp_ackrcvd >= MIN(pcb->tp_fcredit, pcb->tp_cong_win)) { \ ! 354: ++pcb->tp_cong_win; \ ! 355: pcb->tp_ackrcvd = 0; \ ! 356: } \ ! 357: } \ ! 358: } ! 359: ! 360: #ifdef KERNEL ! 361: extern struct timeval time; ! 362: extern struct tp_ref *tp_ref; ! 363: extern struct tp_param tp_param; ! 364: extern struct nl_protosw nl_protosw[]; ! 365: extern struct tp_pcb *tp_listeners; ! 366: extern struct tp_pcb *tp_intercepts; ! 367: #endif ! 368: ! 369: #define sototpcb(so) ((struct tp_pcb *)(so->so_tpcb)) ! 370: #define sototpref(so) ((struct tp_ref *)((so)->so_tpcb->tp_ref)) ! 371: #define tpcbtoso(tp) ((struct socket *)((tp)->tp_sock)) ! 372: #define tpcbtoref(tp) ((struct tp_ref *)((tp)->tp_ref)) ! 373: ! 374: #endif __TP_PCB__
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.