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