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