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.20 (Berkeley) 12/17/91 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 "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 171 /* receiver congestion state stuff ... */ 172 u_int tp_win_recv; 173 174 /* receive window as a scaled int (8 bit fraction part) */ 175 176 struct cong_sample { 177 ushort cs_size; /* current window size */ 178 ushort cs_received; /* PDUs received in this sample */ 179 ushort cs_ce_set; /* PDUs received in this sample with CE bit set */ 180 } tp_cong_sample; 181 182 183 /* parameters per-connection controllable by user */ 184 struct tp_conn_param _tp_param; 185 186 #define tp_Nretrans _tp_param.p_Nretrans 187 #define tp_dr_ticks _tp_param.p_dr_ticks 188 #define tp_cc_ticks _tp_param.p_cc_ticks 189 #define tp_dt_ticks _tp_param.p_dt_ticks 190 #define tp_xpd_ticks _tp_param.p_x_ticks 191 #define tp_cr_ticks _tp_param.p_cr_ticks 192 #define tp_keepalive_ticks _tp_param.p_keepalive_ticks 193 #define tp_sendack_ticks _tp_param.p_sendack_ticks 194 #define tp_refer_ticks _tp_param.p_ref_ticks 195 #define tp_inact_ticks _tp_param.p_inact_ticks 196 #define tp_xtd_format _tp_param.p_xtd_format 197 #define tp_xpd_service _tp_param.p_xpd_service 198 #define tp_ack_strat _tp_param.p_ack_strat 199 #define tp_rx_strat _tp_param.p_rx_strat 200 #define tp_use_checksum _tp_param.p_use_checksum 201 #define tp_use_efc _tp_param.p_use_efc 202 #define tp_use_nxpd _tp_param.p_use_nxpd 203 #define tp_use_rcc _tp_param.p_use_rcc 204 #define tp_tpdusize _tp_param.p_tpdusize 205 #define tp_class _tp_param.p_class 206 #define tp_winsize _tp_param.p_winsize 207 #define tp_no_disc_indications _tp_param.p_no_disc_indications 208 #define tp_dont_change_params _tp_param.p_dont_change_params 209 #define tp_netservice _tp_param.p_netservice 210 #define tp_version _tp_param.p_version 211 #define tp_ptpdusize _tp_param.p_ptpdusize 212 213 int tp_l_tpdusize; 214 /* whereas tp_tpdusize is log2(the negotiated max size) 215 * l_tpdusize is the size we'll use when sending, in # chars 216 */ 217 218 int tp_rtv; /* max round-trip time variance */ 219 int tp_rtt; /* smoothed round-trip time */ 220 SeqNum tp_rttseq; /* packet being timed */ 221 int tp_rttemit; /* when emitted, in ticks */ 222 int tp_idle; /* last activity, in ticks */ 223 short tp_rxtcur; /* current retransmit value */ 224 short tp_rxtshift; /* log(2) of rexmt exp. backoff */ 225 226 unsigned 227 tp_sendfcc:1, /* shall next ack include FCC parameter? */ 228 tp_trace:1, /* is this pcb being traced? (not used yet) */ 229 tp_perf_on:1, /* 0/1 -> performance measuring on */ 230 tp_reneged:1, /* have we reneged on cdt since last ack? */ 231 tp_decbit:3, /* dec bit was set, we're in reneg mode */ 232 tp_cebit_off:1, /* the real DEC bit algorithms not in use */ 233 tp_flags:8, /* values: */ 234 #define TPF_NLQOS_PDN TPFLAG_NLQOS_PDN 235 #define TPF_PEER_ON_SAMENET TPFLAG_PEER_ON_SAMENET 236 #define TPF_GENERAL_ADDR TPFLAG_GENERAL_ADDR 237 #define TPF_DELACK 0x8 238 #define TPF_ACKNOW 0x10 239 240 #define PEER_IS_LOCAL(t) (((t)->tp_flags & TPF_PEER_ON_SAME_NET) != 0) 241 #define USES_PDN(t) (((t)->tp_flags & TPF_NLQOS_PDN) != 0) 242 243 tp_oktonagle:1, /* Last unsent packet that may be append to */ 244 tp_notdetached:1, /* Call tp_detach before freeing XXXXXXX */ 245 tp_unused:14; 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