|
|
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: *
1.1.1.2 ! root 65: * $Header: /cvsroot/src/sys/netiso/tp_pcb.h,v 1.1 1993/04/09 12:01:44 cgd Exp $
! 66: * $Source: /cvsroot/src/sys/netiso/tp_pcb.h,v $
1.1 root 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.