1 /*- 2 * Copyright (c) 1991 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)tp_pcb.h 7.24 (Berkeley) 10/17/92 8 */ 9 10 /*********************************************************** 11 Copyright IBM Corporation 1987 12 13 All Rights Reserved 14 15 Permission to use, copy, modify, and distribute this software and its 16 documentation for any purpose and without fee is hereby granted, 17 provided that the above copyright notice appear in all copies and that 18 both that copyright notice and this permission notice appear in 19 supporting documentation, and that the name of IBM not be 20 used in advertising or publicity pertaining to distribution of the 21 software without specific, written prior permission. 22 23 IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 24 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 25 IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 26 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 27 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 28 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 29 SOFTWARE. 30 31 ******************************************************************/ 32 33 /* 34 * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison 35 */ 36 /* 37 * ARGO TP 38 * 39 * $Header: tp_pcb.h,v 5.2 88/11/18 17:09:32 nhall Exp $ 40 * $Source: /usr/argo/sys/netiso/RCS/tp_pcb.h,v $ 41 * 42 * 43 * This file defines the transport protocol control block (tpcb). 44 * and a bunch of #define values that are used in the tpcb. 45 */ 46 47 #ifndef __TP_PCB__ 48 #define __TP_PCB__ 49 50 #include <netiso/tp_param.h> 51 #include <netiso/tp_timer.h> 52 #include <netiso/tp_user.h> 53 #ifndef sblock 54 #include <sys/socketvar.h> 55 #endif sblock 56 57 /* NOTE: the code depends on REF_CLOSED > REF_OPEN > the rest, and 58 * on REF_FREE being zero 59 * 60 * Possible improvement: 61 * think about merging the tp_ref w/ the tpcb and doing a search 62 * through the tpcb list, from tpb. This would slow down lookup 63 * during data transfer 64 * It would be a little nicer also to have something based on the 65 * clock (like top n bits of the reference is part of the clock, to 66 * minimize the likelihood of reuse after a crash) 67 * also, need to keep the timer servicing part to a minimum (although 68 * the cost of this is probably independent of whether the timers are 69 * in the pcb or in an array.. 70 * Last, would have to make the number of timers a function of the amount of 71 * mbufs available, plus some for the frozen references. 72 * 73 * Possible improvement: 74 * Might not need the ref_state stuff either... 75 * REF_FREE could correspond to tp_state == CLOSED or nonexistend tpcb, 76 * REF_OPEN to tp_state anywhere from AK_WAIT or CR_SENT to CLOSING 77 * REF_OPENING could correspond to LISTENING, because that's the 78 * way it's used, not because the correspondence is exact. 79 * REF_CLOSED could correspond to REFWAIT 80 */ 81 #define REF_FROZEN 3 /* has ref timer only */ 82 #define REF_OPEN 2 /* has timers, possibly active */ 83 #define REF_OPENING 1 /* in use (has a pcb) but no timers */ 84 #define REF_FREE 0 /* free to reallocate */ 85 86 #define TM_NTIMERS 6 87 88 struct tp_ref { 89 struct tp_pcb *tpr_pcb; /* back ptr to PCB */ 90 }; 91 92 /* PER system stuff (one static structure instead of a bunch of names) */ 93 struct tp_refinfo { 94 struct tp_ref *tpr_base; 95 int tpr_size; 96 int tpr_maxopen; 97 int tpr_numopen; 98 }; 99 100 struct nl_protosw { 101 int nlp_afamily; /* address family */ 102 int (*nlp_putnetaddr)(); /* puts addresses in nl pcb */ 103 int (*nlp_getnetaddr)(); /* gets addresses from nl pcb */ 104 int (*nlp_cmpnetaddr)(); /* compares address in pcb with sockaddr */ 105 int (*nlp_putsufx)(); /* puts transport suffixes in nl pcb */ 106 int (*nlp_getsufx)(); /* gets transport suffixes from nl pcb */ 107 int (*nlp_recycle_suffix)();/* clears suffix from nl pcb */ 108 int (*nlp_mtu)(); /* figures out mtu based on nl used */ 109 int (*nlp_pcbbind)(); /* bind to pcb for net level */ 110 int (*nlp_pcbconn)(); /* connect for net level */ 111 int (*nlp_pcbdisc)(); /* disconnect net level */ 112 int (*nlp_pcbdetach)(); /* detach net level pcb */ 113 int (*nlp_pcballoc)(); /* allocate a net level pcb */ 114 int (*nlp_output)(); /* prepare a packet to give to nl */ 115 int (*nlp_dgoutput)(); /* prepare a packet to give to nl */ 116 int (*nlp_ctloutput)(); /* hook for network set/get options */ 117 caddr_t nlp_pcblist; /* list of xx_pcb's for connections */ 118 }; 119 120 121 struct tp_pcb { 122 struct tp_pcb *tp_next; 123 struct tp_pcb *tp_prev; 124 struct tp_pcb *tp_nextlisten; /* chain all listeners */ 125 struct socket *tp_sock; /* back ptr */ 126 u_short tp_state; /* state of fsm */ 127 short tp_retrans; /* # times can still retrans */ 128 caddr_t tp_npcb; /* to lower layer pcb */ 129 struct nl_protosw *tp_nlproto; /* lower-layer dependent routines */ 130 struct rtentry **tp_routep; /* obtain mtu; inside npcb */ 131 132 133 RefNum tp_lref; /* local reference */ 134 RefNum tp_fref; /* foreign reference */ 135 136 u_int tp_seqmask; /* mask for seq space */ 137 u_int tp_seqbit; /* bit for seq number wraparound */ 138 u_int tp_seqhalf; /* half the seq space */ 139 140 struct mbuf *tp_ucddata; /* user connect/disconnect data */ 141 142 /* credit & sequencing info for SENDING */ 143 u_short tp_fcredit; /* current remote credit in # packets */ 144 u_short tp_maxfcredit; /* max remote credit in # packets */ 145 u_short tp_dupacks; /* intuit packet loss before rxt timo */ 146 u_long tp_cong_win; /* congestion window in bytes. 147 * see profuse comments in TCP code 148 */ 149 u_long tp_ssthresh; /* cong_win threshold for slow start 150 * exponential to linear switch 151 */ 152 SeqNum tp_snduna; /* seq # of lowest unacked DT */ 153 SeqNum tp_sndnew; /* seq # of lowest unsent DT */ 154 SeqNum tp_sndnum; /* next seq # to be assigned */ 155 SeqNum tp_sndnxt; /* what to do next; poss. rxt */ 156 struct mbuf *tp_sndnxt_m; /* packet corres. to sndnxt*/ 157 int tp_Nwindow; /* for perf. measurement */ 158 159 /* credit & sequencing info for RECEIVING */ 160 SeqNum tp_rcvnxt; /* next DT seq # expect to recv */ 161 SeqNum tp_sent_lcdt; /* cdt according to last ack sent */ 162 SeqNum tp_sent_uwe; /* uwe according to last ack sent */ 163 SeqNum tp_sent_rcvnxt; /* rcvnxt according to last ack sent 164 * needed for perf measurements only 165 */ 166 u_short tp_lcredit; /* current local credit in # packets */ 167 u_short tp_maxlcredit; /* needed for reassembly queue */ 168 struct mbuf **tp_rsyq; /* unacked stuff recvd out of order */ 169 int tp_rsycnt; /* number of packets "" "" "" "" */ 170 u_long tp_rhiwat; /* remember original RCVBUF size */ 171 172 /* receiver congestion state stuff ... */ 173 u_int tp_win_recv; 174 175 /* receive window as a scaled int (8 bit fraction part) */ 176 177 struct cong_sample { 178 ushort cs_size; /* current window size */ 179 ushort cs_received; /* PDUs received in this sample */ 180 ushort cs_ce_set; /* PDUs received in this sample with CE bit set */ 181 } tp_cong_sample; 182 183 184 /* parameters per-connection controllable by user */ 185 struct tp_conn_param _tp_param; 186 187 #define tp_Nretrans _tp_param.p_Nretrans 188 #define tp_dr_ticks _tp_param.p_dr_ticks 189 #define tp_cc_ticks _tp_param.p_cc_ticks 190 #define tp_dt_ticks _tp_param.p_dt_ticks 191 #define tp_xpd_ticks _tp_param.p_x_ticks 192 #define tp_cr_ticks _tp_param.p_cr_ticks 193 #define tp_keepalive_ticks _tp_param.p_keepalive_ticks 194 #define tp_sendack_ticks _tp_param.p_sendack_ticks 195 #define tp_refer_ticks _tp_param.p_ref_ticks 196 #define tp_inact_ticks _tp_param.p_inact_ticks 197 #define tp_xtd_format _tp_param.p_xtd_format 198 #define tp_xpd_service _tp_param.p_xpd_service 199 #define tp_ack_strat _tp_param.p_ack_strat 200 #define tp_rx_strat _tp_param.p_rx_strat 201 #define tp_use_checksum _tp_param.p_use_checksum 202 #define tp_use_efc _tp_param.p_use_efc 203 #define tp_use_nxpd _tp_param.p_use_nxpd 204 #define tp_use_rcc _tp_param.p_use_rcc 205 #define tp_tpdusize _tp_param.p_tpdusize 206 #define tp_class _tp_param.p_class 207 #define tp_winsize _tp_param.p_winsize 208 #define tp_no_disc_indications _tp_param.p_no_disc_indications 209 #define tp_dont_change_params _tp_param.p_dont_change_params 210 #define tp_netservice _tp_param.p_netservice 211 #define tp_version _tp_param.p_version 212 #define tp_ptpdusize _tp_param.p_ptpdusize 213 214 int tp_l_tpdusize; 215 /* whereas tp_tpdusize is log2(the negotiated max size) 216 * l_tpdusize is the size we'll use when sending, in # chars 217 */ 218 219 int tp_rtv; /* max round-trip time variance */ 220 int tp_rtt; /* smoothed round-trip time */ 221 SeqNum tp_rttseq; /* packet being timed */ 222 int tp_rttemit; /* when emitted, in ticks */ 223 int tp_idle; /* last activity, in ticks */ 224 short tp_rxtcur; /* current retransmit value */ 225 short tp_rxtshift; /* log(2) of rexmt exp. backoff */ 226 u_char tp_cebit_off; /* real DEC bit algorithms not in use */ 227 u_char tp_oktonagle; /* Last unsent pckt may be append to */ 228 u_char tp_flags; /* values: */ 229 #define TPF_NLQOS_PDN TPFLAG_NLQOS_PDN 230 #define TPF_PEER_ON_SAMENET TPFLAG_PEER_ON_SAMENET 231 #define TPF_GENERAL_ADDR TPFLAG_GENERAL_ADDR 232 #define TPF_DELACK 0x8 233 #define TPF_ACKNOW 0x10 234 235 #define PEER_IS_LOCAL(t) (((t)->tp_flags & TPF_PEER_ON_SAME_NET) != 0) 236 #define USES_PDN(t) (((t)->tp_flags & TPF_NLQOS_PDN) != 0) 237 238 239 unsigned 240 tp_sendfcc:1, /* shall next ack include FCC parameter? */ 241 tp_trace:1, /* is this pcb being traced? (not used yet) */ 242 tp_perf_on:1, /* 0/1 -> performance measuring on */ 243 tp_reneged:1, /* have we reneged on cdt since last ack? */ 244 tp_decbit:3, /* dec bit was set, we're in reneg mode */ 245 tp_notdetached:1; /* Call tp_detach before freeing XXXXXXX */ 246 247 #ifdef TP_PERF_MEAS 248 /* performance stats - see tp_stat.h */ 249 struct tp_pmeas *tp_p_meas; 250 struct mbuf *tp_p_mbuf; 251 #endif TP_PERF_MEAS 252 253 /* addressing */ 254 u_short tp_domain; /* domain (INET, ISO) */ 255 /* for compatibility with the *old* way and with INET, be sure that 256 * that lsuffix and fsuffix are aligned to a short addr. 257 * having them follow the u_short *suffixlen should suffice (choke) 258 */ 259 u_short tp_fsuffixlen; /* foreign suffix */ 260 char tp_fsuffix[MAX_TSAP_SEL_LEN]; 261 u_short tp_lsuffixlen; /* local suffix */ 262 char tp_lsuffix[MAX_TSAP_SEL_LEN]; 263 #define SHORT_LSUFXP(tpcb) ((short *)((tpcb)->tp_lsuffix)) 264 #define SHORT_FSUFXP(tpcb) ((short *)((tpcb)->tp_fsuffix)) 265 266 /* Timer stuff */ 267 u_char tp_vers; /* protocol version */ 268 u_char tp_peer_acktime; /* used for DT retrans time */ 269 u_char tp_refstate; /* values REF_FROZEN, etc. above */ 270 struct tp_pcb *tp_fasttimeo; /* limit pcbs to examine */ 271 u_int tp_timer[TM_NTIMERS]; /* C timers */ 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 #ifdef KERNEL 316 extern struct tp_refinfo tp_refinfo; 317 extern struct timeval time; 318 extern struct tp_ref *tp_ref; 319 extern struct tp_param tp_param; 320 extern struct nl_protosw nl_protosw[]; 321 extern struct tp_pcb *tp_listeners; 322 extern struct tp_pcb *tp_ftimeolist; 323 #endif 324 325 #define sototpcb(so) ((struct tp_pcb *)(so->so_pcb)) 326 #define sototpref(so) ((sototpcb(so)->tp_ref)) 327 #define tpcbtoso(tp) ((struct socket *)((tp)->tp_sock)) 328 #define tpcbtoref(tp) ((struct tp_ref *)((tp)->tp_ref)) 329 330 #endif __TP_PCB__ 331