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