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