Deleted Added
full compact
spx_reass.c (25345) spx_reass.c (25652)
1/*
2 * Copyright (c) 1995, Mike Mitchell
3 * Copyright (c) 1984, 1985, 1986, 1987, 1993
4 * The Regents of the University of California. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 19 unchanged lines hidden (view full) ---

28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * @(#)spx_usrreq.h
35 *
1/*
2 * Copyright (c) 1995, Mike Mitchell
3 * Copyright (c) 1984, 1985, 1986, 1987, 1993
4 * The Regents of the University of California. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 19 unchanged lines hidden (view full) ---

28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * @(#)spx_usrreq.h
35 *
36 * $Id: spx_usrreq.c,v 1.11 1997/04/05 20:05:11 jhay Exp $
36 * $Id: spx_usrreq.c,v 1.12 1997/05/01 06:21:31 jhay Exp $
37 */
38
39#include <sys/param.h>
40#include <sys/systm.h>
41#include <sys/malloc.h>
42#include <sys/mbuf.h>
43#include <sys/proc.h>
44#include <sys/protosw.h>

--- 13 unchanged lines hidden (view full) ---

58#include <netipx/spx.h>
59#include <netipx/spx_timer.h>
60#include <netipx/spx_var.h>
61#include <netipx/spx_debug.h>
62
63/*
64 * SPX protocol implementation.
65 */
37 */
38
39#include <sys/param.h>
40#include <sys/systm.h>
41#include <sys/malloc.h>
42#include <sys/mbuf.h>
43#include <sys/proc.h>
44#include <sys/protosw.h>

--- 13 unchanged lines hidden (view full) ---

58#include <netipx/spx.h>
59#include <netipx/spx_timer.h>
60#include <netipx/spx_var.h>
61#include <netipx/spx_debug.h>
62
63/*
64 * SPX protocol implementation.
65 */
66u_short spx_iss;
67u_short spx_newchecks[50];
68int spx_hardnosed;
69int spx_use_delack = 0;
70int traceallspxs = 0;
71struct spx spx_savesi;
72struct spx_istat spx_istat;
66
73
67struct spx spx_savesi;
68int traceallspxs = 0;
69int spx_hardnosed;
70int spx_use_delack = 0;
71u_short spx_newchecks[50];
74/* Following was struct spxstat spxstat; */
75#ifndef spxstat
76#define spxstat spx_istat.newstats
77#endif
72
78
73struct spx_istat spx_istat;
74u_short spx_iss;
79int spx_backoff[SPX_MAXRXTSHIFT+1] =
80 { 1, 2, 4, 8, 16, 32, 64, 64, 64, 64, 64, 64, 64 };
75
81
82static void spx_abort(struct ipxpcb *ipxp);
83static struct spxpcb *spx_close(struct spxpcb *cb);
84static struct spxpcb *spx_disconnect(struct spxpcb *cb);
85static struct spxpcb *spx_drop(struct spxpcb *cb, int errno);
86static int spx_output(struct spxpcb *cb, struct mbuf *m0);
87static void spx_quench(struct ipxpcb *ipxp);
88static int spx_reass(struct spxpcb *cb, struct spx *si);
89static void spx_setpersist(struct spxpcb *cb);
90static void spx_template(struct spxpcb *cb);
91static struct spxpcb *spx_timers(struct spxpcb *cb, int timer);
92static struct spxpcb *spx_usrclosed(struct spxpcb *cb);
93
76static int spx_usr_abort(struct socket *so);
77static int spx_accept(struct socket *so, struct mbuf *nam);
78static int spx_attach(struct socket *so, int proto, struct proc *p);
79static int spx_bind(struct socket *so, struct mbuf *nam, struct proc *p);
80static int spx_connect(struct socket *so, struct mbuf *nam, struct proc *p);
81static int spx_detach(struct socket *so);
82static int spx_usr_disconnect(struct socket *so);
83static int spx_listen(struct socket *so, struct proc *p);

--- 4 unchanged lines hidden (view full) ---

88static int spx_shutdown(struct socket *so);
89static int spx_sp_attach(struct socket *so, int proto, struct proc *p);
90
91struct pr_usrreqs spx_usrreqs = {
92 spx_usr_abort, spx_accept, spx_attach, spx_bind,
93 spx_connect, pru_connect2_notsupp, ipx_control, spx_detach,
94 spx_usr_disconnect, spx_listen, ipx_peeraddr, spx_rcvd,
95 spx_rcvoob, spx_send, pru_sense_null, spx_shutdown,
94static int spx_usr_abort(struct socket *so);
95static int spx_accept(struct socket *so, struct mbuf *nam);
96static int spx_attach(struct socket *so, int proto, struct proc *p);
97static int spx_bind(struct socket *so, struct mbuf *nam, struct proc *p);
98static int spx_connect(struct socket *so, struct mbuf *nam, struct proc *p);
99static int spx_detach(struct socket *so);
100static int spx_usr_disconnect(struct socket *so);
101static int spx_listen(struct socket *so, struct proc *p);

--- 4 unchanged lines hidden (view full) ---

106static int spx_shutdown(struct socket *so);
107static int spx_sp_attach(struct socket *so, int proto, struct proc *p);
108
109struct pr_usrreqs spx_usrreqs = {
110 spx_usr_abort, spx_accept, spx_attach, spx_bind,
111 spx_connect, pru_connect2_notsupp, ipx_control, spx_detach,
112 spx_usr_disconnect, spx_listen, ipx_peeraddr, spx_rcvd,
113 spx_rcvoob, spx_send, pru_sense_null, spx_shutdown,
96 ipx_sockaddr
114 ipx_sockaddr, sosend, soreceive, soselect
97};
98
99struct pr_usrreqs spx_usrreq_sps = {
100 spx_usr_abort, spx_accept, spx_sp_attach, spx_bind,
101 spx_connect, pru_connect2_notsupp, ipx_control, spx_detach,
102 spx_usr_disconnect, spx_listen, ipx_peeraddr, spx_rcvd,
103 spx_rcvoob, spx_send, pru_sense_null, spx_shutdown,
115};
116
117struct pr_usrreqs spx_usrreq_sps = {
118 spx_usr_abort, spx_accept, spx_sp_attach, spx_bind,
119 spx_connect, pru_connect2_notsupp, ipx_control, spx_detach,
120 spx_usr_disconnect, spx_listen, ipx_peeraddr, spx_rcvd,
121 spx_rcvoob, spx_send, pru_sense_null, spx_shutdown,
104 ipx_sockaddr
122 ipx_sockaddr, sosend, soreceive, soselect
105};
106
107void
108spx_init()
109{
110
111 spx_iss = 1; /* WRONG !! should fish it out of TODR */
112}
113
123};
124
125void
126spx_init()
127{
128
129 spx_iss = 1; /* WRONG !! should fish it out of TODR */
130}
131
114/*ARGSUSED*/
115void
116spx_input(m, ipxp)
117 register struct mbuf *m;
118 register struct ipxpcb *ipxp;
119{
120 register struct spxpcb *cb;
121 register struct spx *si = mtod(m, struct spx *);
122 register struct socket *so;
123 int dropsocket = 0;
124 short ostate = 0;
125
126 spxstat.spxs_rcvtotal++;
132void
133spx_input(m, ipxp)
134 register struct mbuf *m;
135 register struct ipxpcb *ipxp;
136{
137 register struct spxpcb *cb;
138 register struct spx *si = mtod(m, struct spx *);
139 register struct socket *so;
140 int dropsocket = 0;
141 short ostate = 0;
142
143 spxstat.spxs_rcvtotal++;
127 if (ipxp == 0) {
144 if (ipxp == NULL) {
128 panic("No ipxpcb in spx_input\n");
129 return;
130 }
131
132 cb = ipxtospxpcb(ipxp);
145 panic("No ipxpcb in spx_input\n");
146 return;
147 }
148
149 cb = ipxtospxpcb(ipxp);
133 if (cb == 0) goto bad;
150 if (cb == NULL)
151 goto bad;
134
135 if (m->m_len < sizeof(*si)) {
152
153 if (m->m_len < sizeof(*si)) {
136 if ((m = m_pullup(m, sizeof(*si))) == 0) {
154 if ((m = m_pullup(m, sizeof(*si))) == NULL) {
137 spxstat.spxs_rcvshort++;
138 return;
139 }
140 si = mtod(m, struct spx *);
141 }
142 si->si_seq = ntohs(si->si_seq);
143 si->si_ack = ntohs(si->si_ack);
144 si->si_alo = ntohs(si->si_alo);
145
146 so = ipxp->ipxp_socket;
147
148 if (so->so_options & SO_DEBUG || traceallspxs) {
149 ostate = cb->s_state;
150 spx_savesi = *si;
151 }
152 if (so->so_options & SO_ACCEPTCONN) {
153 struct spxpcb *ocb = cb;
154
155 so = sonewconn(so, 0);
155 spxstat.spxs_rcvshort++;
156 return;
157 }
158 si = mtod(m, struct spx *);
159 }
160 si->si_seq = ntohs(si->si_seq);
161 si->si_ack = ntohs(si->si_ack);
162 si->si_alo = ntohs(si->si_alo);
163
164 so = ipxp->ipxp_socket;
165
166 if (so->so_options & SO_DEBUG || traceallspxs) {
167 ostate = cb->s_state;
168 spx_savesi = *si;
169 }
170 if (so->so_options & SO_ACCEPTCONN) {
171 struct spxpcb *ocb = cb;
172
173 so = sonewconn(so, 0);
156 if (so == 0) {
174 if (so == NULL) {
157 goto drop;
158 }
159 /*
160 * This is ugly, but ....
161 *
162 * Mark socket as temporary until we're
163 * committed to keeping it. The code at
164 * ``drop'' and ``dropwithreset'' check the

--- 33 unchanged lines hidden (view full) ---

198 */
199 if (spx_hardnosed && (si->si_did != 0 || si->si_seq != 0)) {
200 spx_istat.gonawy++;
201 goto dropwithreset;
202 }
203 am = m_get(M_DONTWAIT, MT_SONAME);
204 if (am == NULL)
205 goto drop;
175 goto drop;
176 }
177 /*
178 * This is ugly, but ....
179 *
180 * Mark socket as temporary until we're
181 * committed to keeping it. The code at
182 * ``drop'' and ``dropwithreset'' check the

--- 33 unchanged lines hidden (view full) ---

216 */
217 if (spx_hardnosed && (si->si_did != 0 || si->si_seq != 0)) {
218 spx_istat.gonawy++;
219 goto dropwithreset;
220 }
221 am = m_get(M_DONTWAIT, MT_SONAME);
222 if (am == NULL)
223 goto drop;
206 am->m_len = sizeof (struct sockaddr_ipx);
224 am->m_len = sizeof(struct sockaddr_ipx);
207 sipx = mtod(am, struct sockaddr_ipx *);
208 sipx->sipx_len = sizeof(*sipx);
209 sipx->sipx_family = AF_IPX;
210 sipx->sipx_addr = si->si_sna;
211 laddr = ipxp->ipxp_laddr;
212 if (ipx_nullhost(laddr))
213 ipxp->ipxp_laddr = si->si_dna;
214 if (ipx_pcbconnect(ipxp, am, &proc0)) {
215 ipxp->ipxp_laddr = laddr;
225 sipx = mtod(am, struct sockaddr_ipx *);
226 sipx->sipx_len = sizeof(*sipx);
227 sipx->sipx_family = AF_IPX;
228 sipx->sipx_addr = si->si_sna;
229 laddr = ipxp->ipxp_laddr;
230 if (ipx_nullhost(laddr))
231 ipxp->ipxp_laddr = si->si_dna;
232 if (ipx_pcbconnect(ipxp, am, &proc0)) {
233 ipxp->ipxp_laddr = laddr;
216 (void) m_free(am);
234 m_free(am);
217 spx_istat.noconn++;
218 goto drop;
219 }
235 spx_istat.noconn++;
236 goto drop;
237 }
220 (void) m_free(am);
238 m_free(am);
221 spx_template(cb);
222 dropsocket = 0; /* committed to socket */
223 cb->s_did = si->si_sid;
224 cb->s_rack = si->si_ack;
225 cb->s_ralo = si->si_alo;
226#define THREEWAYSHAKE
227#ifdef THREEWAYSHAKE
228 cb->s_state = TCPS_SYN_RECEIVED;

--- 4 unchanged lines hidden (view full) ---

233 break;
234 /*
235 * This state means that we have heard a response
236 * to our acceptance of their connection
237 * It is probably logically unnecessary in this
238 * implementation.
239 */
240 case TCPS_SYN_RECEIVED: {
239 spx_template(cb);
240 dropsocket = 0; /* committed to socket */
241 cb->s_did = si->si_sid;
242 cb->s_rack = si->si_ack;
243 cb->s_ralo = si->si_alo;
244#define THREEWAYSHAKE
245#ifdef THREEWAYSHAKE
246 cb->s_state = TCPS_SYN_RECEIVED;

--- 4 unchanged lines hidden (view full) ---

251 break;
252 /*
253 * This state means that we have heard a response
254 * to our acceptance of their connection
255 * It is probably logically unnecessary in this
256 * implementation.
257 */
258 case TCPS_SYN_RECEIVED: {
241 if (si->si_did!=cb->s_sid) {
259 if (si->si_did != cb->s_sid) {
242 spx_istat.wrncon++;
243 goto drop;
244 }
245#endif
246 ipxp->ipxp_fport = si->si_sport;
247 cb->s_timer[SPXT_REXMT] = 0;
248 cb->s_timer[SPXT_KEEP] = SPXTV_KEEP;
249 soisconnected(so);

--- 7 unchanged lines hidden (view full) ---

257 * to our attempt to establish a connection.
258 * We fill in the data from the other side,
259 * telling us which port to respond to, instead of the well-
260 * known one we might have sent to in the first place.
261 * We also require that this is a response to our
262 * connection id.
263 */
264 case TCPS_SYN_SENT:
260 spx_istat.wrncon++;
261 goto drop;
262 }
263#endif
264 ipxp->ipxp_fport = si->si_sport;
265 cb->s_timer[SPXT_REXMT] = 0;
266 cb->s_timer[SPXT_KEEP] = SPXTV_KEEP;
267 soisconnected(so);

--- 7 unchanged lines hidden (view full) ---

275 * to our attempt to establish a connection.
276 * We fill in the data from the other side,
277 * telling us which port to respond to, instead of the well-
278 * known one we might have sent to in the first place.
279 * We also require that this is a response to our
280 * connection id.
281 */
282 case TCPS_SYN_SENT:
265 if (si->si_did!=cb->s_sid) {
283 if (si->si_did != cb->s_sid) {
266 spx_istat.notme++;
267 goto drop;
268 }
269 spxstat.spxs_connects++;
270 cb->s_did = si->si_sid;
271 cb->s_rack = si->si_ack;
272 cb->s_ralo = si->si_alo;
273 cb->s_dport = ipxp->ipxp_fport = si->si_sport;

--- 9 unchanged lines hidden (view full) ---

283 ((cb->s_srtt >> 2) + cb->s_rttvar) >> 1,
284 SPXTV_MIN, SPXTV_REXMTMAX);
285 cb->s_rtt = 0;
286 }
287 }
288 if (so->so_options & SO_DEBUG || traceallspxs)
289 spx_trace(SA_INPUT, (u_char)ostate, cb, &spx_savesi, 0);
290
284 spx_istat.notme++;
285 goto drop;
286 }
287 spxstat.spxs_connects++;
288 cb->s_did = si->si_sid;
289 cb->s_rack = si->si_ack;
290 cb->s_ralo = si->si_alo;
291 cb->s_dport = ipxp->ipxp_fport = si->si_sport;

--- 9 unchanged lines hidden (view full) ---

301 ((cb->s_srtt >> 2) + cb->s_rttvar) >> 1,
302 SPXTV_MIN, SPXTV_REXMTMAX);
303 cb->s_rtt = 0;
304 }
305 }
306 if (so->so_options & SO_DEBUG || traceallspxs)
307 spx_trace(SA_INPUT, (u_char)ostate, cb, &spx_savesi, 0);
308
291 m->m_len -= sizeof (struct ipx);
292 m->m_pkthdr.len -= sizeof (struct ipx);
293 m->m_data += sizeof (struct ipx);
309 m->m_len -= sizeof(struct ipx);
310 m->m_pkthdr.len -= sizeof(struct ipx);
311 m->m_data += sizeof(struct ipx);
294
295 if (spx_reass(cb, si)) {
312
313 if (spx_reass(cb, si)) {
296 (void) m_freem(m);
314 m_freem(m);
297 }
298 if (cb->s_force || (cb->s_flags & (SF_ACKNOW|SF_WIN|SF_RXT)))
315 }
316 if (cb->s_force || (cb->s_flags & (SF_ACKNOW|SF_WIN|SF_RXT)))
299 (void) spx_output(cb, (struct mbuf *)0);
317 spx_output(cb, (struct mbuf *)NULL);
300 cb->s_flags &= ~(SF_WIN|SF_RXT);
301 return;
302
303dropwithreset:
304 if (dropsocket)
318 cb->s_flags &= ~(SF_WIN|SF_RXT);
319 return;
320
321dropwithreset:
322 if (dropsocket)
305 (void) soabort(so);
323 soabort(so);
306 si->si_seq = ntohs(si->si_seq);
307 si->si_ack = ntohs(si->si_ack);
308 si->si_alo = ntohs(si->si_alo);
324 si->si_seq = ntohs(si->si_seq);
325 si->si_ack = ntohs(si->si_ack);
326 si->si_alo = ntohs(si->si_alo);
327#ifdef IPXERRORMSGS
309 ipx_error(dtom(si), IPX_ERR_NOSOCK, 0);
328 ipx_error(dtom(si), IPX_ERR_NOSOCK, 0);
329#else
330 m_freem(dtom(si));
331#endif
310 if (cb->s_ipxpcb->ipxp_socket->so_options & SO_DEBUG || traceallspxs)
311 spx_trace(SA_DROP, (u_char)ostate, cb, &spx_savesi, 0);
312 return;
313
314drop:
315bad:
316 if (cb == 0 || cb->s_ipxpcb->ipxp_socket->so_options & SO_DEBUG ||
317 traceallspxs)
318 spx_trace(SA_DROP, (u_char)ostate, cb, &spx_savesi, 0);
319 m_freem(m);
320}
321
322int spxrexmtthresh = 3;
323
324/*
325 * This is structurally similar to the tcp reassembly routine
326 * but its function is somewhat different: It merely queues
327 * packets up, and suppresses duplicates.
328 */
332 if (cb->s_ipxpcb->ipxp_socket->so_options & SO_DEBUG || traceallspxs)
333 spx_trace(SA_DROP, (u_char)ostate, cb, &spx_savesi, 0);
334 return;
335
336drop:
337bad:
338 if (cb == 0 || cb->s_ipxpcb->ipxp_socket->so_options & SO_DEBUG ||
339 traceallspxs)
340 spx_trace(SA_DROP, (u_char)ostate, cb, &spx_savesi, 0);
341 m_freem(m);
342}
343
344int spxrexmtthresh = 3;
345
346/*
347 * This is structurally similar to the tcp reassembly routine
348 * but its function is somewhat different: It merely queues
349 * packets up, and suppresses duplicates.
350 */
329int
351static int
330spx_reass(cb, si)
331register struct spxpcb *cb;
332register struct spx *si;
333{
334 register struct spx_q *q;
335 register struct mbuf *m;
336 register struct socket *so = cb->s_ipxpcb->ipxp_socket;
337 char packetp = cb->s_flags & SF_HI;

--- 23 unchanged lines hidden (view full) ---

361 cb->s_dupacks = 0;
362 else if (++cb->s_dupacks == spxrexmtthresh) {
363 u_short onxt = cb->s_snxt;
364 int cwnd = cb->s_cwnd;
365
366 cb->s_snxt = si->si_ack;
367 cb->s_cwnd = CUNIT;
368 cb->s_force = 1 + SPXT_REXMT;
352spx_reass(cb, si)
353register struct spxpcb *cb;
354register struct spx *si;
355{
356 register struct spx_q *q;
357 register struct mbuf *m;
358 register struct socket *so = cb->s_ipxpcb->ipxp_socket;
359 char packetp = cb->s_flags & SF_HI;

--- 23 unchanged lines hidden (view full) ---

383 cb->s_dupacks = 0;
384 else if (++cb->s_dupacks == spxrexmtthresh) {
385 u_short onxt = cb->s_snxt;
386 int cwnd = cb->s_cwnd;
387
388 cb->s_snxt = si->si_ack;
389 cb->s_cwnd = CUNIT;
390 cb->s_force = 1 + SPXT_REXMT;
369 (void) spx_output(cb, (struct mbuf *)0);
391 spx_output(cb, (struct mbuf *)NULL);
370 cb->s_timer[SPXT_REXMT] = cb->s_rxtcur;
371 cb->s_rtt = 0;
372 if (cwnd >= 4 * CUNIT)
373 cb->s_cwnd = cwnd / 2;
374 if (SSEQ_GT(onxt, cb->s_snxt))
375 cb->s_snxt = onxt;
376 return (1);
377 }

--- 101 unchanged lines hidden (view full) ---

479 if (SSEQ_GT(si->si_seq, cb->s_alo)) {
480 if (si->si_cc & SPX_SP) {
481 spxstat.spxs_rcvwinprobe++;
482 return (1);
483 } else
484 spxstat.spxs_rcvpackafterwin++;
485 if (si->si_cc & SPX_OB) {
486 if (SSEQ_GT(si->si_seq, cb->s_alo + 60)) {
392 cb->s_timer[SPXT_REXMT] = cb->s_rxtcur;
393 cb->s_rtt = 0;
394 if (cwnd >= 4 * CUNIT)
395 cb->s_cwnd = cwnd / 2;
396 if (SSEQ_GT(onxt, cb->s_snxt))
397 cb->s_snxt = onxt;
398 return (1);
399 }

--- 101 unchanged lines hidden (view full) ---

501 if (SSEQ_GT(si->si_seq, cb->s_alo)) {
502 if (si->si_cc & SPX_SP) {
503 spxstat.spxs_rcvwinprobe++;
504 return (1);
505 } else
506 spxstat.spxs_rcvpackafterwin++;
507 if (si->si_cc & SPX_OB) {
508 if (SSEQ_GT(si->si_seq, cb->s_alo + 60)) {
509#ifdef IPXERRORMSGS
487 ipx_error(dtom(si), IPX_ERR_FULLUP, 0);
510 ipx_error(dtom(si), IPX_ERR_FULLUP, 0);
511#else
512 m_freem(dtom(si));
513#endif
488 return (0);
489 } /* else queue this packet; */
490 } else {
491 /*register struct socket *so = cb->s_ipxpcb->ipxp_socket;
492 if (so->so_state && SS_NOFDREF) {
493 ipx_error(dtom(si), IPX_ERR_NOSOCK, 0);
514 return (0);
515 } /* else queue this packet; */
516 } else {
517 /*register struct socket *so = cb->s_ipxpcb->ipxp_socket;
518 if (so->so_state && SS_NOFDREF) {
519 ipx_error(dtom(si), IPX_ERR_NOSOCK, 0);
494 (void)spx_close(cb);
520 spx_close(cb);
495 } else
496 would crash system*/
497 spx_istat.notyet++;
521 } else
522 would crash system*/
523 spx_istat.notyet++;
524#ifdef IPXERRORMSGS
498 ipx_error(dtom(si), IPX_ERR_FULLUP, 0);
525 ipx_error(dtom(si), IPX_ERR_FULLUP, 0);
526#else
527 m_freem(dtom(si));
528#endif
499 return (0);
500 }
501 }
502 /*
503 * If this is a system packet, we don't need to
504 * queue it up, and won't update acknowledge #
505 */
506 if (si->si_cc & SPX_SP) {

--- 8 unchanged lines hidden (view full) ---

515 if (si->si_seq == cb->s_ack - 1)
516 spx_istat.lstdup++;
517 return (1);
518 }
519 /*
520 * Loop through all packets queued up to insert in
521 * appropriate sequence.
522 */
529 return (0);
530 }
531 }
532 /*
533 * If this is a system packet, we don't need to
534 * queue it up, and won't update acknowledge #
535 */
536 if (si->si_cc & SPX_SP) {

--- 8 unchanged lines hidden (view full) ---

545 if (si->si_seq == cb->s_ack - 1)
546 spx_istat.lstdup++;
547 return (1);
548 }
549 /*
550 * Loop through all packets queued up to insert in
551 * appropriate sequence.
552 */
523 for (q = cb->s_q.si_next; q!=&cb->s_q; q = q->si_next) {
553 for (q = cb->s_q.si_next; q != &cb->s_q; q = q->si_next) {
524 if (si->si_seq == SI(q)->si_seq) {
525 spxstat.spxs_rcvduppack++;
526 return (1);
527 }
528 if (SSEQ_LT(si->si_seq, SI(q)->si_seq)) {
529 spxstat.spxs_rcvoopack++;
530 break;
531 }

--- 9 unchanged lines hidden (view full) ---

541 }
542present:
543#define SPINC sizeof(struct spxhdr)
544 /*
545 * Loop through all packets queued up to update acknowledge
546 * number, and present all acknowledged data to user;
547 * If in packet interface mode, show packet headers.
548 */
554 if (si->si_seq == SI(q)->si_seq) {
555 spxstat.spxs_rcvduppack++;
556 return (1);
557 }
558 if (SSEQ_LT(si->si_seq, SI(q)->si_seq)) {
559 spxstat.spxs_rcvoopack++;
560 break;
561 }

--- 9 unchanged lines hidden (view full) ---

571 }
572present:
573#define SPINC sizeof(struct spxhdr)
574 /*
575 * Loop through all packets queued up to update acknowledge
576 * number, and present all acknowledged data to user;
577 * If in packet interface mode, show packet headers.
578 */
549 for (q = cb->s_q.si_next; q!=&cb->s_q; q = q->si_next) {
579 for (q = cb->s_q.si_next; q != &cb->s_q; q = q->si_next) {
550 if (SI(q)->si_seq == cb->s_ack) {
551 cb->s_ack++;
552 m = dtom(q);
553 if (SI(q)->si_cc & SPX_OB) {
554 cb->s_oobflags &= ~SF_IOOB;
555 if (so->so_rcv.sb_cc)
556 so->so_oobmark = so->so_rcv.sb_cc;
557 else

--- 48 unchanged lines hidden (view full) ---

606 m->m_data += SPINC;
607 m->m_len -= SPINC;
608 m->m_pkthdr.len -= SPINC;
609 sbappend(&so->so_rcv, m);
610 }
611 } else
612 break;
613 }
580 if (SI(q)->si_seq == cb->s_ack) {
581 cb->s_ack++;
582 m = dtom(q);
583 if (SI(q)->si_cc & SPX_OB) {
584 cb->s_oobflags &= ~SF_IOOB;
585 if (so->so_rcv.sb_cc)
586 so->so_oobmark = so->so_rcv.sb_cc;
587 else

--- 48 unchanged lines hidden (view full) ---

636 m->m_data += SPINC;
637 m->m_len -= SPINC;
638 m->m_pkthdr.len -= SPINC;
639 sbappend(&so->so_rcv, m);
640 }
641 } else
642 break;
643 }
614 if (wakeup) sorwakeup(so);
644 if (wakeup)
645 sorwakeup(so);
615 return (0);
616}
617
618void
619spx_ctlinput(cmd, arg_as_sa, dummy)
620 int cmd;
621 struct sockaddr *arg_as_sa; /* XXX should be swapped with dummy */
622 void *dummy;
623{
624 caddr_t arg = (/* XXX */ caddr_t)arg_as_sa;
625 struct ipx_addr *na;
646 return (0);
647}
648
649void
650spx_ctlinput(cmd, arg_as_sa, dummy)
651 int cmd;
652 struct sockaddr *arg_as_sa; /* XXX should be swapped with dummy */
653 void *dummy;
654{
655 caddr_t arg = (/* XXX */ caddr_t)arg_as_sa;
656 struct ipx_addr *na;
626 struct ipx_errp *errp = (struct ipx_errp *)arg;
627 struct ipxpcb *ipxp;
628 struct sockaddr_ipx *sipx;
657 struct sockaddr_ipx *sipx;
658#ifdef IPXERRORMSGS
659 struct ipxpcb *ipxp;
660 struct ipx_errp *errp = (struct ipx_errp *)arg;
629 int type;
661 int type;
662#endif
630
631 if (cmd < 0 || cmd > PRC_NCMDS)
632 return;
663
664 if (cmd < 0 || cmd > PRC_NCMDS)
665 return;
666
667#ifdef IPXERRORMSGS
633 type = IPX_ERR_UNREACH_HOST;
668 type = IPX_ERR_UNREACH_HOST;
669#endif
634
635 switch (cmd) {
636
637 case PRC_ROUTEDEAD:
638 return;
639
640 case PRC_IFDOWN:
641 case PRC_HOSTDEAD:
642 case PRC_HOSTUNREACH:
643 sipx = (struct sockaddr_ipx *)arg;
644 if (sipx->sipx_family != AF_IPX)
645 return;
646 na = &sipx->sipx_addr;
647 break;
648
649 default:
670
671 switch (cmd) {
672
673 case PRC_ROUTEDEAD:
674 return;
675
676 case PRC_IFDOWN:
677 case PRC_HOSTDEAD:
678 case PRC_HOSTUNREACH:
679 sipx = (struct sockaddr_ipx *)arg;
680 if (sipx->sipx_family != AF_IPX)
681 return;
682 na = &sipx->sipx_addr;
683 break;
684
685 default:
686#ifdef IPXERRORMSGS
650 errp = (struct ipx_errp *)arg;
651 na = &errp->ipx_err_ipx.ipx_dna;
652 type = errp->ipx_err_num;
653 type = ntohs((u_short)type);
687 errp = (struct ipx_errp *)arg;
688 na = &errp->ipx_err_ipx.ipx_dna;
689 type = errp->ipx_err_num;
690 type = ntohs((u_short)type);
691#endif
654 break;
655 }
692 break;
693 }
694#ifdef IPXERRORMSGS
656 switch (type) {
657
658 case IPX_ERR_UNREACH_HOST:
659 ipx_pcbnotify(na, (int)ipxctlerrmap[cmd], spx_abort, (long)0);
660 break;
661
662 case IPX_ERR_TOO_BIG:
663 case IPX_ERR_NOSOCK:
664 ipxp = ipx_pcblookup(na, errp->ipx_err_ipx.ipx_sna.x_port,
665 IPX_WILDCARD);
695 switch (type) {
696
697 case IPX_ERR_UNREACH_HOST:
698 ipx_pcbnotify(na, (int)ipxctlerrmap[cmd], spx_abort, (long)0);
699 break;
700
701 case IPX_ERR_TOO_BIG:
702 case IPX_ERR_NOSOCK:
703 ipxp = ipx_pcblookup(na, errp->ipx_err_ipx.ipx_sna.x_port,
704 IPX_WILDCARD);
666 if (ipxp) {
667 if(ipxp->ipxp_pcb)
668 (void) spx_drop((struct spxpcb *)ipxp->ipxp_pcb,
705 if (ipxp != NULL) {
706 if(ipxp->ipxp_pcb != NULL)
707 spx_drop((struct spxpcb *)ipxp->ipxp_pcb,
669 (int)ipxctlerrmap[cmd]);
670 else
708 (int)ipxctlerrmap[cmd]);
709 else
671 (void) ipx_drop(ipxp, (int)ipxctlerrmap[cmd]);
710 ipx_drop(ipxp, (int)ipxctlerrmap[cmd]);
672 }
673 break;
674
675 case IPX_ERR_FULLUP:
676 ipx_pcbnotify(na, 0, spx_quench, (long)0);
677 break;
678 }
711 }
712 break;
713
714 case IPX_ERR_FULLUP:
715 ipx_pcbnotify(na, 0, spx_quench, (long)0);
716 break;
717 }
718#endif
679}
680/*
681 * When a source quench is received, close congestion window
682 * to one packet. We will gradually open it again as we proceed.
683 */
719}
720/*
721 * When a source quench is received, close congestion window
722 * to one packet. We will gradually open it again as we proceed.
723 */
684void
724static void
685spx_quench(ipxp)
686 struct ipxpcb *ipxp;
687{
688 struct spxpcb *cb = ipxtospxpcb(ipxp);
689
725spx_quench(ipxp)
726 struct ipxpcb *ipxp;
727{
728 struct spxpcb *cb = ipxtospxpcb(ipxp);
729
690 if (cb)
730 if (cb != NULL)
691 cb->s_cwnd = CUNIT;
692}
693
694#ifdef notdef
695int
696spx_fixmtu(ipxp)
697register struct ipxpcb *ipxp;
698{
699 register struct spxpcb *cb = (struct spxpcb *)(ipxp->ipxp_pcb);
700 register struct mbuf *m;
701 register struct spx *si;
702 struct ipx_errp *ep;
703 struct sockbuf *sb;
704 int badseq, len;
705 struct mbuf *firstbad, *m0;
706
731 cb->s_cwnd = CUNIT;
732}
733
734#ifdef notdef
735int
736spx_fixmtu(ipxp)
737register struct ipxpcb *ipxp;
738{
739 register struct spxpcb *cb = (struct spxpcb *)(ipxp->ipxp_pcb);
740 register struct mbuf *m;
741 register struct spx *si;
742 struct ipx_errp *ep;
743 struct sockbuf *sb;
744 int badseq, len;
745 struct mbuf *firstbad, *m0;
746
707 if (cb) {
747 if (cb != NULL) {
708 /*
709 * The notification that we have sent
710 * too much is bad news -- we will
711 * have to go through queued up so far
712 * splitting ones which are too big and
713 * reassigning sequence numbers and checksums.
714 * we should then retransmit all packets from
715 * one above the offending packet to the last one
716 * we had sent (or our allocation)
717 * then the offending one so that the any queued
718 * data at our destination will be discarded.
719 */
720 ep = (struct ipx_errp *)ipxp->ipxp_notify_param;
721 sb = &ipxp->ipxp_socket->so_snd;
722 cb->s_mtu = ep->ipx_err_param;
723 badseq = SI(&ep->ipx_err_ipx)->si_seq;
748 /*
749 * The notification that we have sent
750 * too much is bad news -- we will
751 * have to go through queued up so far
752 * splitting ones which are too big and
753 * reassigning sequence numbers and checksums.
754 * we should then retransmit all packets from
755 * one above the offending packet to the last one
756 * we had sent (or our allocation)
757 * then the offending one so that the any queued
758 * data at our destination will be discarded.
759 */
760 ep = (struct ipx_errp *)ipxp->ipxp_notify_param;
761 sb = &ipxp->ipxp_socket->so_snd;
762 cb->s_mtu = ep->ipx_err_param;
763 badseq = SI(&ep->ipx_err_ipx)->si_seq;
724 for (m = sb->sb_mb; m; m = m->m_act) {
764 for (m = sb->sb_mb; m != NULL; m = m->m_act) {
725 si = mtod(m, struct spx *);
726 if (si->si_seq == badseq)
727 break;
728 }
765 si = mtod(m, struct spx *);
766 if (si->si_seq == badseq)
767 break;
768 }
729 if (m == 0) return;
769 if (m == NULL)
770 return;
730 firstbad = m;
731 /*for (;;) {*/
732 /* calculate length */
771 firstbad = m;
772 /*for (;;) {*/
773 /* calculate length */
733 for (m0 = m, len = 0; m ; m = m->m_next)
774 for (m0 = m, len = 0; m != NULL; m = m->m_next)
734 len += m->m_len;
735 if (len > cb->s_mtu) {
736 }
737 /* FINISH THIS
738 } */
739 }
740}
741#endif
742
775 len += m->m_len;
776 if (len > cb->s_mtu) {
777 }
778 /* FINISH THIS
779 } */
780 }
781}
782#endif
783
743int
784static int
744spx_output(cb, m0)
745 register struct spxpcb *cb;
746 struct mbuf *m0;
747{
748 struct socket *so = cb->s_ipxpcb->ipxp_socket;
749 register struct mbuf *m;
785spx_output(cb, m0)
786 register struct spxpcb *cb;
787 struct mbuf *m0;
788{
789 struct socket *so = cb->s_ipxpcb->ipxp_socket;
790 register struct mbuf *m;
750 register struct spx *si = (struct spx *) 0;
791 register struct spx *si = (struct spx *)NULL;
751 register struct sockbuf *sb = &so->so_snd;
752 int len = 0, win, rcv_win;
753 short span, off, recordp = 0;
754 u_short alo;
755 int error = 0, sendalot;
756#ifdef notdef
757 int idle;
758#endif
759 struct mbuf *mprev;
760
792 register struct sockbuf *sb = &so->so_snd;
793 int len = 0, win, rcv_win;
794 short span, off, recordp = 0;
795 u_short alo;
796 int error = 0, sendalot;
797#ifdef notdef
798 int idle;
799#endif
800 struct mbuf *mprev;
801
761 if (m0) {
802 if (m0 != NULL) {
762 int mtu = cb->s_mtu;
763 int datalen;
764 /*
765 * Make sure that packet isn't too big.
766 */
803 int mtu = cb->s_mtu;
804 int datalen;
805 /*
806 * Make sure that packet isn't too big.
807 */
767 for (m = m0; m ; m = m->m_next) {
808 for (m = m0; m != NULL; m = m->m_next) {
768 mprev = m;
769 len += m->m_len;
770 if (m->m_flags & M_EOR)
771 recordp = 1;
772 }
773 datalen = (cb->s_flags & SF_HO) ?
809 mprev = m;
810 len += m->m_len;
811 if (m->m_flags & M_EOR)
812 recordp = 1;
813 }
814 datalen = (cb->s_flags & SF_HO) ?
774 len - sizeof (struct spxhdr) : len;
815 len - sizeof(struct spxhdr) : len;
775 if (datalen > mtu) {
776 if (cb->s_flags & SF_PI) {
777 m_freem(m0);
778 return (EMSGSIZE);
779 } else {
780 int oldEM = cb->s_cc & SPX_EM;
781
782 cb->s_cc &= ~SPX_EM;
783 while (len > mtu) {
784 /*
785 * Here we are only being called
786 * from usrreq(), so it is OK to
787 * block.
788 */
789 m = m_copym(m0, 0, mtu, M_WAIT);
790 if (cb->s_flags & SF_NEWCALL) {
791 struct mbuf *mm = m;
792 spx_newchecks[7]++;
816 if (datalen > mtu) {
817 if (cb->s_flags & SF_PI) {
818 m_freem(m0);
819 return (EMSGSIZE);
820 } else {
821 int oldEM = cb->s_cc & SPX_EM;
822
823 cb->s_cc &= ~SPX_EM;
824 while (len > mtu) {
825 /*
826 * Here we are only being called
827 * from usrreq(), so it is OK to
828 * block.
829 */
830 m = m_copym(m0, 0, mtu, M_WAIT);
831 if (cb->s_flags & SF_NEWCALL) {
832 struct mbuf *mm = m;
833 spx_newchecks[7]++;
793 while (mm) {
834 while (mm != NULL) {
794 mm->m_flags &= ~M_EOR;
795 mm = mm->m_next;
796 }
797 }
798 error = spx_output(cb, m);
799 if (error) {
800 cb->s_cc |= oldEM;
801 m_freem(m0);
835 mm->m_flags &= ~M_EOR;
836 mm = mm->m_next;
837 }
838 }
839 error = spx_output(cb, m);
840 if (error) {
841 cb->s_cc |= oldEM;
842 m_freem(m0);
802 return(error);
843 return (error);
803 }
804 m_adj(m0, mtu);
805 len -= mtu;
806 }
807 cb->s_cc |= oldEM;
808 }
809 }
810 /*
811 * Force length even, by adding a "garbage byte" if
812 * necessary.
813 */
814 if (len & 1) {
815 m = mprev;
816 if (M_TRAILINGSPACE(m) >= 1)
817 m->m_len++;
818 else {
819 struct mbuf *m1 = m_get(M_DONTWAIT, MT_DATA);
820
844 }
845 m_adj(m0, mtu);
846 len -= mtu;
847 }
848 cb->s_cc |= oldEM;
849 }
850 }
851 /*
852 * Force length even, by adding a "garbage byte" if
853 * necessary.
854 */
855 if (len & 1) {
856 m = mprev;
857 if (M_TRAILINGSPACE(m) >= 1)
858 m->m_len++;
859 else {
860 struct mbuf *m1 = m_get(M_DONTWAIT, MT_DATA);
861
821 if (m1 == 0) {
862 if (m1 == NULL) {
822 m_freem(m0);
823 return (ENOBUFS);
824 }
825 m1->m_len = 1;
826 *(mtod(m1, u_char *)) = 0;
827 m->m_next = m1;
828 }
829 }
830 m = m_gethdr(M_DONTWAIT, MT_HEADER);
863 m_freem(m0);
864 return (ENOBUFS);
865 }
866 m1->m_len = 1;
867 *(mtod(m1, u_char *)) = 0;
868 m->m_next = m1;
869 }
870 }
871 m = m_gethdr(M_DONTWAIT, MT_HEADER);
831 if (m == 0) {
872 if (m == NULL) {
832 m_freem(m0);
833 return (ENOBUFS);
834 }
835 /*
836 * Fill in mbuf with extended SP header
837 * and addresses and length put into network format.
838 */
873 m_freem(m0);
874 return (ENOBUFS);
875 }
876 /*
877 * Fill in mbuf with extended SP header
878 * and addresses and length put into network format.
879 */
839 MH_ALIGN(m, sizeof (struct spx));
840 m->m_len = sizeof (struct spx);
880 MH_ALIGN(m, sizeof(struct spx));
881 m->m_len = sizeof(struct spx);
841 m->m_next = m0;
842 si = mtod(m, struct spx *);
843 si->si_i = *cb->s_ipx;
844 si->si_s = cb->s_shdr;
845 if ((cb->s_flags & SF_PI) && (cb->s_flags & SF_HO)) {
846 register struct spxhdr *sh;
882 m->m_next = m0;
883 si = mtod(m, struct spx *);
884 si->si_i = *cb->s_ipx;
885 si->si_s = cb->s_shdr;
886 if ((cb->s_flags & SF_PI) && (cb->s_flags & SF_HO)) {
887 register struct spxhdr *sh;
847 if (m0->m_len < sizeof (*sh)) {
888 if (m0->m_len < sizeof(*sh)) {
848 if((m0 = m_pullup(m0, sizeof(*sh))) == NULL) {
889 if((m0 = m_pullup(m0, sizeof(*sh))) == NULL) {
849 (void) m_free(m);
890 m_free(m);
850 m_freem(m0);
851 return (EINVAL);
852 }
853 m->m_next = m0;
854 }
855 sh = mtod(m0, struct spxhdr *);
856 si->si_dt = sh->spx_dt;
857 si->si_cc |= sh->spx_cc & SPX_EM;
891 m_freem(m0);
892 return (EINVAL);
893 }
894 m->m_next = m0;
895 }
896 sh = mtod(m0, struct spxhdr *);
897 si->si_dt = sh->spx_dt;
898 si->si_cc |= sh->spx_cc & SPX_EM;
858 m0->m_len -= sizeof (*sh);
859 m0->m_data += sizeof (*sh);
860 len -= sizeof (*sh);
899 m0->m_len -= sizeof(*sh);
900 m0->m_data += sizeof(*sh);
901 len -= sizeof(*sh);
861 }
862 len += sizeof(*si);
863 if ((cb->s_flags2 & SF_NEWCALL) && recordp) {
902 }
903 len += sizeof(*si);
904 if ((cb->s_flags2 & SF_NEWCALL) && recordp) {
864 si->si_cc |= SPX_EM;
905 si->si_cc |= SPX_EM;
865 spx_newchecks[8]++;
866 }
867 if (cb->s_oobflags & SF_SOOB) {
868 /*
869 * Per jqj@cornell:
870 * make sure OB packets convey exactly 1 byte.
871 * If the packet is 1 byte or larger, we
872 * have already guaranted there to be at least

--- 14 unchanged lines hidden (view full) ---

887 cb->s_seq++;
888 }
889#ifdef notdef
890 idle = (cb->s_smax == (cb->s_rack - 1));
891#endif
892again:
893 sendalot = 0;
894 off = cb->s_snxt - cb->s_rack;
906 spx_newchecks[8]++;
907 }
908 if (cb->s_oobflags & SF_SOOB) {
909 /*
910 * Per jqj@cornell:
911 * make sure OB packets convey exactly 1 byte.
912 * If the packet is 1 byte or larger, we
913 * have already guaranted there to be at least

--- 14 unchanged lines hidden (view full) ---

928 cb->s_seq++;
929 }
930#ifdef notdef
931 idle = (cb->s_smax == (cb->s_rack - 1));
932#endif
933again:
934 sendalot = 0;
935 off = cb->s_snxt - cb->s_rack;
895 win = min(cb->s_swnd, (cb->s_cwnd/CUNIT));
936 win = min(cb->s_swnd, (cb->s_cwnd / CUNIT));
896
897 /*
898 * If in persist timeout with window of 0, send a probe.
899 * Otherwise, if window is small but nonzero
900 * and timer expired, send what we can and go into
901 * transmit state.
902 */
903 if (cb->s_force == 1 + SPXT_PERSIST) {

--- 87 unchanged lines hidden (view full) ---

991
992send:
993 /*
994 * Find requested packet.
995 */
996 si = 0;
997 if (len > 0) {
998 cb->s_want = cb->s_snxt;
937
938 /*
939 * If in persist timeout with window of 0, send a probe.
940 * Otherwise, if window is small but nonzero
941 * and timer expired, send what we can and go into
942 * transmit state.
943 */
944 if (cb->s_force == 1 + SPXT_PERSIST) {

--- 87 unchanged lines hidden (view full) ---

1032
1033send:
1034 /*
1035 * Find requested packet.
1036 */
1037 si = 0;
1038 if (len > 0) {
1039 cb->s_want = cb->s_snxt;
999 for (m = sb->sb_mb; m; m = m->m_act) {
1040 for (m = sb->sb_mb; m != NULL; m = m->m_act) {
1000 si = mtod(m, struct spx *);
1001 if (SSEQ_LEQ(cb->s_snxt, si->si_seq))
1002 break;
1003 }
1004 found:
1041 si = mtod(m, struct spx *);
1042 if (SSEQ_LEQ(cb->s_snxt, si->si_seq))
1043 break;
1044 }
1045 found:
1005 if (si) {
1046 if (si != NULL) {
1006 if (si->si_seq == cb->s_snxt)
1007 cb->s_snxt++;
1008 else
1009 spxstat.spxs_sndvoid++, si = 0;
1010 }
1011 }
1012 /*
1013 * update window
1014 */
1015 if (rcv_win < 0)
1016 rcv_win = 0;
1017 alo = cb->s_ack - 1 + (rcv_win / ((short)cb->s_mtu));
1018 if (SSEQ_LT(alo, cb->s_alo))
1019 alo = cb->s_alo;
1020
1047 if (si->si_seq == cb->s_snxt)
1048 cb->s_snxt++;
1049 else
1050 spxstat.spxs_sndvoid++, si = 0;
1051 }
1052 }
1053 /*
1054 * update window
1055 */
1056 if (rcv_win < 0)
1057 rcv_win = 0;
1058 alo = cb->s_ack - 1 + (rcv_win / ((short)cb->s_mtu));
1059 if (SSEQ_LT(alo, cb->s_alo))
1060 alo = cb->s_alo;
1061
1021 if (si) {
1062 if (si != NULL) {
1022 /*
1023 * must make a copy of this packet for
1024 * ipx_output to monkey with
1025 */
1026 m = m_copy(dtom(si), 0, (int)M_COPYALL);
1027 if (m == NULL) {
1028 return (ENOBUFS);
1029 }

--- 6 unchanged lines hidden (view full) ---

1036 /*
1037 * Must send an acknowledgement or a probe
1038 */
1039 if (cb->s_force)
1040 spxstat.spxs_sndprobe++;
1041 if (cb->s_flags & SF_ACKNOW)
1042 spxstat.spxs_sndacks++;
1043 m = m_gethdr(M_DONTWAIT, MT_HEADER);
1063 /*
1064 * must make a copy of this packet for
1065 * ipx_output to monkey with
1066 */
1067 m = m_copy(dtom(si), 0, (int)M_COPYALL);
1068 if (m == NULL) {
1069 return (ENOBUFS);
1070 }

--- 6 unchanged lines hidden (view full) ---

1077 /*
1078 * Must send an acknowledgement or a probe
1079 */
1080 if (cb->s_force)
1081 spxstat.spxs_sndprobe++;
1082 if (cb->s_flags & SF_ACKNOW)
1083 spxstat.spxs_sndacks++;
1084 m = m_gethdr(M_DONTWAIT, MT_HEADER);
1044 if (m == 0)
1085 if (m == NULL)
1045 return (ENOBUFS);
1046 /*
1047 * Fill in mbuf with extended SP header
1048 * and addresses and length put into network format.
1049 */
1086 return (ENOBUFS);
1087 /*
1088 * Fill in mbuf with extended SP header
1089 * and addresses and length put into network format.
1090 */
1050 MH_ALIGN(m, sizeof (struct spx));
1051 m->m_len = sizeof (*si);
1052 m->m_pkthdr.len = sizeof (*si);
1091 MH_ALIGN(m, sizeof(struct spx));
1092 m->m_len = sizeof(*si);
1093 m->m_pkthdr.len = sizeof(*si);
1053 si = mtod(m, struct spx *);
1054 si->si_i = *cb->s_ipx;
1055 si->si_s = cb->s_shdr;
1056 si->si_seq = cb->s_smax + 1;
1094 si = mtod(m, struct spx *);
1095 si->si_i = *cb->s_ipx;
1096 si->si_s = cb->s_shdr;
1097 si->si_seq = cb->s_smax + 1;
1057 si->si_len = htons(sizeof (*si));
1098 si->si_len = htons(sizeof(*si));
1058 si->si_cc |= SPX_SP;
1059 } else {
1060 cb->s_outx = 3;
1061 if (so->so_options & SO_DEBUG || traceallspxs)
1062 spx_trace(SA_OUTPUT, cb->s_state, cb, si, 0);
1063 return (0);
1064 }
1065 /*

--- 58 unchanged lines hidden (view full) ---

1124 } else
1125 si->si_sum = 0xffff;
1126
1127 cb->s_outx = 4;
1128 if (so->so_options & SO_DEBUG || traceallspxs)
1129 spx_trace(SA_OUTPUT, cb->s_state, cb, si, 0);
1130
1131 if (so->so_options & SO_DONTROUTE)
1099 si->si_cc |= SPX_SP;
1100 } else {
1101 cb->s_outx = 3;
1102 if (so->so_options & SO_DEBUG || traceallspxs)
1103 spx_trace(SA_OUTPUT, cb->s_state, cb, si, 0);
1104 return (0);
1105 }
1106 /*

--- 58 unchanged lines hidden (view full) ---

1165 } else
1166 si->si_sum = 0xffff;
1167
1168 cb->s_outx = 4;
1169 if (so->so_options & SO_DEBUG || traceallspxs)
1170 spx_trace(SA_OUTPUT, cb->s_state, cb, si, 0);
1171
1172 if (so->so_options & SO_DONTROUTE)
1132 error = ipx_outputfl(m, (struct route *)0, IPX_ROUTETOIF);
1173 error = ipx_outputfl(m, (struct route *)NULL, IPX_ROUTETOIF);
1133 else
1134 error = ipx_outputfl(m, &cb->s_ipxpcb->ipxp_route, 0);
1135 }
1136 if (error) {
1137 return (error);
1138 }
1139 spxstat.spxs_sndtotal++;
1140 /*

--- 9 unchanged lines hidden (view full) ---

1150 if (sendalot)
1151 goto again;
1152 cb->s_outx = 5;
1153 return (0);
1154}
1155
1156int spx_do_persist_panics = 0;
1157
1174 else
1175 error = ipx_outputfl(m, &cb->s_ipxpcb->ipxp_route, 0);
1176 }
1177 if (error) {
1178 return (error);
1179 }
1180 spxstat.spxs_sndtotal++;
1181 /*

--- 9 unchanged lines hidden (view full) ---

1191 if (sendalot)
1192 goto again;
1193 cb->s_outx = 5;
1194 return (0);
1195}
1196
1197int spx_do_persist_panics = 0;
1198
1158void
1199static void
1159spx_setpersist(cb)
1160 register struct spxpcb *cb;
1161{
1162 register t = ((cb->s_srtt >> 2) + cb->s_rttvar) >> 1;
1163
1164 if (cb->s_timer[SPXT_REXMT] && spx_do_persist_panics)
1165 panic("spx_output REXMT");
1166 /*
1167 * Start/restart persistance timer.
1168 */
1169 SPXT_RANGESET(cb->s_timer[SPXT_PERSIST],
1170 t*spx_backoff[cb->s_rxtshift],
1171 SPXTV_PERSMIN, SPXTV_PERSMAX);
1172 if (cb->s_rxtshift < SPX_MAXRXTSHIFT)
1173 cb->s_rxtshift++;
1174}
1200spx_setpersist(cb)
1201 register struct spxpcb *cb;
1202{
1203 register t = ((cb->s_srtt >> 2) + cb->s_rttvar) >> 1;
1204
1205 if (cb->s_timer[SPXT_REXMT] && spx_do_persist_panics)
1206 panic("spx_output REXMT");
1207 /*
1208 * Start/restart persistance timer.
1209 */
1210 SPXT_RANGESET(cb->s_timer[SPXT_PERSIST],
1211 t*spx_backoff[cb->s_rxtshift],
1212 SPXTV_PERSMIN, SPXTV_PERSMAX);
1213 if (cb->s_rxtshift < SPX_MAXRXTSHIFT)
1214 cb->s_rxtshift++;
1215}
1175/*ARGSUSED*/
1216
1176int
1177spx_ctloutput(req, so, level, name, value, p)
1178 int req;
1179 struct socket *so;
1180 int level, name;
1181 struct mbuf **value;
1182 struct proc *p;
1183{

--- 143 unchanged lines hidden (view full) ---

1327 struct mbuf *nam;
1328{
1329 struct ipxpcb *ipxp;
1330 struct sockaddr_ipx *sipx;
1331
1332 ipxp = sotoipxpcb(so);
1333 sipx = mtod(nam, struct sockaddr_ipx *);
1334
1217int
1218spx_ctloutput(req, so, level, name, value, p)
1219 int req;
1220 struct socket *so;
1221 int level, name;
1222 struct mbuf **value;
1223 struct proc *p;
1224{

--- 143 unchanged lines hidden (view full) ---

1368 struct mbuf *nam;
1369{
1370 struct ipxpcb *ipxp;
1371 struct sockaddr_ipx *sipx;
1372
1373 ipxp = sotoipxpcb(so);
1374 sipx = mtod(nam, struct sockaddr_ipx *);
1375
1335 nam->m_len = sizeof (struct sockaddr_ipx);
1376 nam->m_len = sizeof(struct sockaddr_ipx);
1336 sipx->sipx_family = AF_IPX;
1337 sipx->sipx_addr = ipxp->ipxp_faddr;
1338 return (0);
1339}
1340
1341static int
1342spx_attach(so, proto, p)
1343 struct socket *so;

--- 38 unchanged lines hidden (view full) ---

1382 goto spx_attach_end;
1383 }
1384 cb->s_ipx = mtod(mm, struct ipx *);
1385 cb->s_state = TCPS_LISTEN;
1386 cb->s_smax = -1;
1387 cb->s_swl1 = -1;
1388 cb->s_q.si_next = cb->s_q.si_prev = &cb->s_q;
1389 cb->s_ipxpcb = ipxp;
1377 sipx->sipx_family = AF_IPX;
1378 sipx->sipx_addr = ipxp->ipxp_faddr;
1379 return (0);
1380}
1381
1382static int
1383spx_attach(so, proto, p)
1384 struct socket *so;

--- 38 unchanged lines hidden (view full) ---

1423 goto spx_attach_end;
1424 }
1425 cb->s_ipx = mtod(mm, struct ipx *);
1426 cb->s_state = TCPS_LISTEN;
1427 cb->s_smax = -1;
1428 cb->s_swl1 = -1;
1429 cb->s_q.si_next = cb->s_q.si_prev = &cb->s_q;
1430 cb->s_ipxpcb = ipxp;
1390 cb->s_mtu = 576 - sizeof (struct spx);
1431 cb->s_mtu = 576 - sizeof(struct spx);
1391 cb->s_cwnd = sbspace(sb) * CUNIT / cb->s_mtu;
1392 cb->s_ssthresh = cb->s_cwnd;
1432 cb->s_cwnd = sbspace(sb) * CUNIT / cb->s_mtu;
1433 cb->s_ssthresh = cb->s_cwnd;
1393 cb->s_cwmx = sbspace(sb) * CUNIT /
1394 (2 * sizeof (struct spx));
1434 cb->s_cwmx = sbspace(sb) * CUNIT / (2 * sizeof(struct spx));
1395 /* Above is recomputed when connecting to account
1396 for changed buffering or mtu's */
1397 cb->s_rtt = SPXTV_SRTTBASE;
1398 cb->s_rttvar = SPXTV_SRTTDFLT << 2;
1399 SPXT_RANGESET(cb->s_rxtcur,
1400 ((SPXTV_SRTTBASE >> 2) + (SPXTV_SRTTDFLT << 2)) >> 1,
1401 SPXTV_MIN, SPXTV_REXMTMAX);
1435 /* Above is recomputed when connecting to account
1436 for changed buffering or mtu's */
1437 cb->s_rtt = SPXTV_SRTTBASE;
1438 cb->s_rttvar = SPXTV_SRTTDFLT << 2;
1439 SPXT_RANGESET(cb->s_rxtcur,
1440 ((SPXTV_SRTTBASE >> 2) + (SPXTV_SRTTDFLT << 2)) >> 1,
1441 SPXTV_MIN, SPXTV_REXMTMAX);
1402 ipxp->ipxp_pcb = (caddr_t) cb;
1442 ipxp->ipxp_pcb = (caddr_t)cb;
1403spx_attach_end:
1404 splx(s);
1405 return (error);
1406}
1407
1408static int
1409spx_bind(so, nam, p)
1410 struct socket *so;

--- 24 unchanged lines hidden (view full) ---

1435 struct ipxpcb *ipxp;
1436 struct spxpcb *cb;
1437
1438 ipxp = sotoipxpcb(so);
1439 cb = ipxtospxpcb(ipxp);
1440
1441 s = splnet();
1442 if (ipxp->ipxp_lport == 0) {
1443spx_attach_end:
1444 splx(s);
1445 return (error);
1446}
1447
1448static int
1449spx_bind(so, nam, p)
1450 struct socket *so;

--- 24 unchanged lines hidden (view full) ---

1475 struct ipxpcb *ipxp;
1476 struct spxpcb *cb;
1477
1478 ipxp = sotoipxpcb(so);
1479 cb = ipxtospxpcb(ipxp);
1480
1481 s = splnet();
1482 if (ipxp->ipxp_lport == 0) {
1443 error = ipx_pcbbind(ipxp, (struct mbuf *)0, p);
1483 error = ipx_pcbbind(ipxp, (struct mbuf *)NULL, p);
1444 if (error)
1445 goto spx_connect_end;
1446 }
1447 error = ipx_pcbconnect(ipxp, nam, p);
1448 if (error)
1449 goto spx_connect_end;
1450 soisconnecting(so);
1451 spxstat.spxs_connattempt++;

--- 6 unchanged lines hidden (view full) ---

1458 * Other party is required to respond to
1459 * the port I send from, but he is not
1460 * required to answer from where I am sending to,
1461 * so allow wildcarding.
1462 * original port I am sending to is still saved in
1463 * cb->s_dport.
1464 */
1465 ipxp->ipxp_fport = 0;
1484 if (error)
1485 goto spx_connect_end;
1486 }
1487 error = ipx_pcbconnect(ipxp, nam, p);
1488 if (error)
1489 goto spx_connect_end;
1490 soisconnecting(so);
1491 spxstat.spxs_connattempt++;

--- 6 unchanged lines hidden (view full) ---

1498 * Other party is required to respond to
1499 * the port I send from, but he is not
1500 * required to answer from where I am sending to,
1501 * so allow wildcarding.
1502 * original port I am sending to is still saved in
1503 * cb->s_dport.
1504 */
1505 ipxp->ipxp_fport = 0;
1466 error = spx_output(cb, (struct mbuf *) 0);
1506 error = spx_output(cb, (struct mbuf *)NULL);
1467spx_connect_end:
1468 splx(s);
1469 return (error);
1470}
1471
1472static int
1473spx_detach(so)
1474 struct socket *so;

--- 47 unchanged lines hidden (view full) ---

1522 struct ipxpcb *ipxp;
1523 struct spxpcb *cb;
1524
1525 error = 0;
1526 ipxp = sotoipxpcb(so);
1527 cb = ipxtospxpcb(ipxp);
1528
1529 if (ipxp->ipxp_lport == 0)
1507spx_connect_end:
1508 splx(s);
1509 return (error);
1510}
1511
1512static int
1513spx_detach(so)
1514 struct socket *so;

--- 47 unchanged lines hidden (view full) ---

1562 struct ipxpcb *ipxp;
1563 struct spxpcb *cb;
1564
1565 error = 0;
1566 ipxp = sotoipxpcb(so);
1567 cb = ipxtospxpcb(ipxp);
1568
1569 if (ipxp->ipxp_lport == 0)
1530 error = ipx_pcbbind(ipxp, (struct mbuf *)0, p);
1570 error = ipx_pcbbind(ipxp, (struct mbuf *)NULL, p);
1531 if (error == 0)
1532 cb->s_state = TCPS_LISTEN;
1533 return (error);
1534}
1535
1536/*
1537 * After a receive, possibly send acknowledgment
1538 * updating allocation.

--- 7 unchanged lines hidden (view full) ---

1546 struct ipxpcb *ipxp;
1547 struct spxpcb *cb;
1548
1549 ipxp = sotoipxpcb(so);
1550 cb = ipxtospxpcb(ipxp);
1551
1552 s = splnet();
1553 cb->s_flags |= SF_RVD;
1571 if (error == 0)
1572 cb->s_state = TCPS_LISTEN;
1573 return (error);
1574}
1575
1576/*
1577 * After a receive, possibly send acknowledgment
1578 * updating allocation.

--- 7 unchanged lines hidden (view full) ---

1586 struct ipxpcb *ipxp;
1587 struct spxpcb *cb;
1588
1589 ipxp = sotoipxpcb(so);
1590 cb = ipxtospxpcb(ipxp);
1591
1592 s = splnet();
1593 cb->s_flags |= SF_RVD;
1554 spx_output(cb, (struct mbuf *) 0);
1594 spx_output(cb, (struct mbuf *)NULL);
1555 cb->s_flags &= ~SF_RVD;
1556 splx(s);
1557 return (0);
1558}
1559
1560static int
1561spx_rcvoob(so, m, flags)
1562 struct socket *so;

--- 36 unchanged lines hidden (view full) ---

1599 s = splnet();
1600 if (flags & PRUS_OOB) {
1601 if (sbspace(&so->so_snd) < -512) {
1602 error = ENOBUFS;
1603 goto spx_send_end;
1604 }
1605 cb->s_oobflags |= SF_SOOB;
1606 }
1595 cb->s_flags &= ~SF_RVD;
1596 splx(s);
1597 return (0);
1598}
1599
1600static int
1601spx_rcvoob(so, m, flags)
1602 struct socket *so;

--- 36 unchanged lines hidden (view full) ---

1639 s = splnet();
1640 if (flags & PRUS_OOB) {
1641 if (sbspace(&so->so_snd) < -512) {
1642 error = ENOBUFS;
1643 goto spx_send_end;
1644 }
1645 cb->s_oobflags |= SF_SOOB;
1646 }
1607 if (controlp) {
1647 if (controlp != NULL) {
1608 u_short *p = mtod(controlp, u_short *);
1609 spx_newchecks[2]++;
1648 u_short *p = mtod(controlp, u_short *);
1649 spx_newchecks[2]++;
1610 if ((p[0] == 5) && p[1] == 1) { /* XXXX, for testing */
1650 if ((p[0] == 5) && (p[1] == 1)) { /* XXXX, for testing */
1611 cb->s_shdr.spx_dt = *(u_char *)(&p[2]);
1612 spx_newchecks[3]++;
1613 }
1614 m_freem(controlp);
1615 }
1616 controlp = NULL;
1617 error = spx_output(cb, m);
1618 m = NULL;

--- 17 unchanged lines hidden (view full) ---

1636
1637 error = 0;
1638 ipxp = sotoipxpcb(so);
1639 cb = ipxtospxpcb(ipxp);
1640
1641 s = splnet();
1642 socantsendmore(so);
1643 cb = spx_usrclosed(cb);
1651 cb->s_shdr.spx_dt = *(u_char *)(&p[2]);
1652 spx_newchecks[3]++;
1653 }
1654 m_freem(controlp);
1655 }
1656 controlp = NULL;
1657 error = spx_output(cb, m);
1658 m = NULL;

--- 17 unchanged lines hidden (view full) ---

1676
1677 error = 0;
1678 ipxp = sotoipxpcb(so);
1679 cb = ipxtospxpcb(ipxp);
1680
1681 s = splnet();
1682 socantsendmore(so);
1683 cb = spx_usrclosed(cb);
1644 if (cb)
1645 error = spx_output(cb, (struct mbuf *) 0);
1684 if (cb != NULL)
1685 error = spx_output(cb, (struct mbuf *)NULL);
1646 splx(s);
1647 return (error);
1648}
1649
1650static int
1651spx_sp_attach(so, proto, p)
1652 struct socket *so;
1653 int proto;
1654 struct proc *p;
1655{
1656 int error;
1657 struct ipxpcb *ipxp;
1686 splx(s);
1687 return (error);
1688}
1689
1690static int
1691spx_sp_attach(so, proto, p)
1692 struct socket *so;
1693 int proto;
1694 struct proc *p;
1695{
1696 int error;
1697 struct ipxpcb *ipxp;
1658 struct spxpcb *cb;
1659
1660 error = spx_attach(so, proto, p);
1661 if (error == 0) {
1662 ipxp = sotoipxpcb(so);
1663 ((struct spxpcb *)ipxp->ipxp_pcb)->s_flags |=
1664 (SF_HI | SF_HO | SF_PI);
1665 }
1666 return (error);
1667}
1668
1669/*
1670 * Create template to be used to send spx packets on a connection.
1671 * Called after host entry created, fills
1672 * in a skeletal spx header (choosing connection id),
1673 * minimizing the amount of work necessary when the connection is used.
1674 */
1698
1699 error = spx_attach(so, proto, p);
1700 if (error == 0) {
1701 ipxp = sotoipxpcb(so);
1702 ((struct spxpcb *)ipxp->ipxp_pcb)->s_flags |=
1703 (SF_HI | SF_HO | SF_PI);
1704 }
1705 return (error);
1706}
1707
1708/*
1709 * Create template to be used to send spx packets on a connection.
1710 * Called after host entry created, fills
1711 * in a skeletal spx header (choosing connection id),
1712 * minimizing the amount of work necessary when the connection is used.
1713 */
1675void
1714static void
1676spx_template(cb)
1677 register struct spxpcb *cb;
1678{
1679 register struct ipxpcb *ipxp = cb->s_ipxpcb;
1680 register struct ipx *ipx = cb->s_ipx;
1681 register struct sockbuf *sb = &(ipxp->ipxp_socket->so_snd);
1682
1683 ipx->ipx_pt = IPXPROTO_SPX;

--- 11 unchanged lines hidden (view full) ---

1695}
1696
1697/*
1698 * Close a SPIP control block:
1699 * discard spx control block itself
1700 * discard ipx protocol control block
1701 * wake up any sleepers
1702 */
1715spx_template(cb)
1716 register struct spxpcb *cb;
1717{
1718 register struct ipxpcb *ipxp = cb->s_ipxpcb;
1719 register struct ipx *ipx = cb->s_ipx;
1720 register struct sockbuf *sb = &(ipxp->ipxp_socket->so_snd);
1721
1722 ipx->ipx_pt = IPXPROTO_SPX;

--- 11 unchanged lines hidden (view full) ---

1734}
1735
1736/*
1737 * Close a SPIP control block:
1738 * discard spx control block itself
1739 * discard ipx protocol control block
1740 * wake up any sleepers
1741 */
1703struct spxpcb *
1742static struct spxpcb *
1704spx_close(cb)
1705 register struct spxpcb *cb;
1706{
1707 register struct spx_q *s;
1708 struct ipxpcb *ipxp = cb->s_ipxpcb;
1709 struct socket *so = ipxp->ipxp_socket;
1710 register struct mbuf *m;
1711
1712 s = cb->s_q.si_next;
1713 while (s != &(cb->s_q)) {
1714 s = s->si_next;
1715 m = dtom(s->si_prev);
1716 remque(s->si_prev);
1717 m_freem(m);
1718 }
1743spx_close(cb)
1744 register struct spxpcb *cb;
1745{
1746 register struct spx_q *s;
1747 struct ipxpcb *ipxp = cb->s_ipxpcb;
1748 struct socket *so = ipxp->ipxp_socket;
1749 register struct mbuf *m;
1750
1751 s = cb->s_q.si_next;
1752 while (s != &(cb->s_q)) {
1753 s = s->si_next;
1754 m = dtom(s->si_prev);
1755 remque(s->si_prev);
1756 m_freem(m);
1757 }
1719 (void) m_free(dtom(cb->s_ipx));
1720 (void) m_free(dtom(cb));
1758 m_free(dtom(cb->s_ipx));
1759 m_free(dtom(cb));
1721 ipxp->ipxp_pcb = 0;
1722 soisdisconnected(so);
1723 ipx_pcbdetach(ipxp);
1724 spxstat.spxs_closed++;
1760 ipxp->ipxp_pcb = 0;
1761 soisdisconnected(so);
1762 ipx_pcbdetach(ipxp);
1763 spxstat.spxs_closed++;
1725 return ((struct spxpcb *)0);
1764 return ((struct spxpcb *)NULL);
1726}
1765}
1766
1727/*
1728 * Someday we may do level 3 handshaking
1729 * to close a connection or send a xerox style error.
1730 * For now, just close.
1731 */
1767/*
1768 * Someday we may do level 3 handshaking
1769 * to close a connection or send a xerox style error.
1770 * For now, just close.
1771 */
1732struct spxpcb *
1772static struct spxpcb *
1733spx_usrclosed(cb)
1734 register struct spxpcb *cb;
1735{
1736 return (spx_close(cb));
1737}
1773spx_usrclosed(cb)
1774 register struct spxpcb *cb;
1775{
1776 return (spx_close(cb));
1777}
1738struct spxpcb *
1778
1779static struct spxpcb *
1739spx_disconnect(cb)
1740 register struct spxpcb *cb;
1741{
1742 return (spx_close(cb));
1743}
1780spx_disconnect(cb)
1781 register struct spxpcb *cb;
1782{
1783 return (spx_close(cb));
1784}
1785
1744/*
1745 * Drop connection, reporting
1746 * the specified error.
1747 */
1786/*
1787 * Drop connection, reporting
1788 * the specified error.
1789 */
1748struct spxpcb *
1790static struct spxpcb *
1749spx_drop(cb, errno)
1750 register struct spxpcb *cb;
1751 int errno;
1752{
1753 struct socket *so = cb->s_ipxpcb->ipxp_socket;
1754
1755 /*
1756 * someday, in the xerox world
1757 * we will generate error protocol packets
1758 * announcing that the socket has gone away.
1759 */
1760 if (TCPS_HAVERCVDSYN(cb->s_state)) {
1761 spxstat.spxs_drops++;
1762 cb->s_state = TCPS_CLOSED;
1791spx_drop(cb, errno)
1792 register struct spxpcb *cb;
1793 int errno;
1794{
1795 struct socket *so = cb->s_ipxpcb->ipxp_socket;
1796
1797 /*
1798 * someday, in the xerox world
1799 * we will generate error protocol packets
1800 * announcing that the socket has gone away.
1801 */
1802 if (TCPS_HAVERCVDSYN(cb->s_state)) {
1803 spxstat.spxs_drops++;
1804 cb->s_state = TCPS_CLOSED;
1763 /*(void) tcp_output(cb);*/
1805 /*tcp_output(cb);*/
1764 } else
1765 spxstat.spxs_conndrops++;
1766 so->so_error = errno;
1767 return (spx_close(cb));
1768}
1769
1806 } else
1807 spxstat.spxs_conndrops++;
1808 so->so_error = errno;
1809 return (spx_close(cb));
1810}
1811
1770void
1812static void
1771spx_abort(ipxp)
1772 struct ipxpcb *ipxp;
1773{
1774
1813spx_abort(ipxp)
1814 struct ipxpcb *ipxp;
1815{
1816
1775 (void) spx_close((struct spxpcb *)ipxp->ipxp_pcb);
1817 spx_close((struct spxpcb *)ipxp->ipxp_pcb);
1776}
1777
1818}
1819
1778int spx_backoff[SPX_MAXRXTSHIFT+1] =
1779 { 1, 2, 4, 8, 16, 32, 64, 64, 64, 64, 64, 64, 64 };
1780/*
1781 * Fast timeout routine for processing delayed acks
1782 */
1783void
1784spx_fasttimo()
1785{
1786 register struct ipxpcb *ipxp;
1787 register struct spxpcb *cb;
1788 int s = splnet();
1789
1790 ipxp = ipxpcb.ipxp_next;
1820/*
1821 * Fast timeout routine for processing delayed acks
1822 */
1823void
1824spx_fasttimo()
1825{
1826 register struct ipxpcb *ipxp;
1827 register struct spxpcb *cb;
1828 int s = splnet();
1829
1830 ipxp = ipxpcb.ipxp_next;
1791 if (ipxp)
1831 if (ipxp != NULL)
1792 for (; ipxp != &ipxpcb; ipxp = ipxp->ipxp_next)
1832 for (; ipxp != &ipxpcb; ipxp = ipxp->ipxp_next)
1793 if ((cb = (struct spxpcb *)ipxp->ipxp_pcb) &&
1833 if ((cb = (struct spxpcb *)ipxp->ipxp_pcb) != NULL &&
1794 (cb->s_flags & SF_DELACK)) {
1795 cb->s_flags &= ~SF_DELACK;
1796 cb->s_flags |= SF_ACKNOW;
1797 spxstat.spxs_delack++;
1834 (cb->s_flags & SF_DELACK)) {
1835 cb->s_flags &= ~SF_DELACK;
1836 cb->s_flags |= SF_ACKNOW;
1837 spxstat.spxs_delack++;
1798 (void) spx_output(cb, (struct mbuf *) 0);
1838 spx_output(cb, (struct mbuf *)NULL);
1799 }
1800 splx(s);
1801}
1802
1803/*
1804 * spx protocol timeout routine called every 500 ms.
1805 * Updates the timers in all active pcb's and
1806 * causes finite state machine actions if timers expire.

--- 5 unchanged lines hidden (view full) ---

1812 register struct spxpcb *cb;
1813 int s = splnet();
1814 register int i;
1815
1816 /*
1817 * Search through tcb's and update active timers.
1818 */
1819 ip = ipxpcb.ipxp_next;
1839 }
1840 splx(s);
1841}
1842
1843/*
1844 * spx protocol timeout routine called every 500 ms.
1845 * Updates the timers in all active pcb's and
1846 * causes finite state machine actions if timers expire.

--- 5 unchanged lines hidden (view full) ---

1852 register struct spxpcb *cb;
1853 int s = splnet();
1854 register int i;
1855
1856 /*
1857 * Search through tcb's and update active timers.
1858 */
1859 ip = ipxpcb.ipxp_next;
1820 if (ip == 0) {
1860 if (ip == NULL) {
1821 splx(s);
1822 return;
1823 }
1824 while (ip != &ipxpcb) {
1825 cb = ipxtospxpcb(ip);
1826 ipnxt = ip->ipxp_next;
1861 splx(s);
1862 return;
1863 }
1864 while (ip != &ipxpcb) {
1865 cb = ipxtospxpcb(ip);
1866 ipnxt = ip->ipxp_next;
1827 if (cb == 0)
1867 if (cb == NULL)
1828 goto tpgone;
1829 for (i = 0; i < SPXT_NTIMERS; i++) {
1830 if (cb->s_timer[i] && --cb->s_timer[i] == 0) {
1831 spx_timers(cb, i);
1832 if (ipnxt->ipxp_prev != ip)
1833 goto tpgone;
1834 }
1835 }
1836 cb->s_idle++;
1837 if (cb->s_rtt)
1838 cb->s_rtt++;
1839tpgone:
1840 ip = ipnxt;
1841 }
1842 spx_iss += SPX_ISSINCR/PR_SLOWHZ; /* increment iss */
1843 splx(s);
1844}
1868 goto tpgone;
1869 for (i = 0; i < SPXT_NTIMERS; i++) {
1870 if (cb->s_timer[i] && --cb->s_timer[i] == 0) {
1871 spx_timers(cb, i);
1872 if (ipnxt->ipxp_prev != ip)
1873 goto tpgone;
1874 }
1875 }
1876 cb->s_idle++;
1877 if (cb->s_rtt)
1878 cb->s_rtt++;
1879tpgone:
1880 ip = ipnxt;
1881 }
1882 spx_iss += SPX_ISSINCR/PR_SLOWHZ; /* increment iss */
1883 splx(s);
1884}
1885
1845/*
1846 * SPX timer processing.
1847 */
1886/*
1887 * SPX timer processing.
1888 */
1848struct spxpcb *
1889static struct spxpcb *
1849spx_timers(cb, timer)
1850 register struct spxpcb *cb;
1851 int timer;
1852{
1853 long rexmt;
1854 int win;
1855
1856 cb->s_force = 1 + timer;

--- 45 unchanged lines hidden (view full) ---

1902 * See very long discussion in tcp_timer.c about congestion
1903 * window and sstrhesh
1904 */
1905 win = min(cb->s_swnd, (cb->s_cwnd/CUNIT)) / 2;
1906 if (win < 2)
1907 win = 2;
1908 cb->s_cwnd = CUNIT;
1909 cb->s_ssthresh = win * CUNIT;
1890spx_timers(cb, timer)
1891 register struct spxpcb *cb;
1892 int timer;
1893{
1894 long rexmt;
1895 int win;
1896
1897 cb->s_force = 1 + timer;

--- 45 unchanged lines hidden (view full) ---

1943 * See very long discussion in tcp_timer.c about congestion
1944 * window and sstrhesh
1945 */
1946 win = min(cb->s_swnd, (cb->s_cwnd/CUNIT)) / 2;
1947 if (win < 2)
1948 win = 2;
1949 cb->s_cwnd = CUNIT;
1950 cb->s_ssthresh = win * CUNIT;
1910 (void) spx_output(cb, (struct mbuf *) 0);
1951 spx_output(cb, (struct mbuf *)NULL);
1911 break;
1912
1913 /*
1914 * Persistance timer into zero window.
1915 * Force a probe to be sent.
1916 */
1917 case SPXT_PERSIST:
1918 spxstat.spxs_persisttimeo++;
1919 spx_setpersist(cb);
1952 break;
1953
1954 /*
1955 * Persistance timer into zero window.
1956 * Force a probe to be sent.
1957 */
1958 case SPXT_PERSIST:
1959 spxstat.spxs_persisttimeo++;
1960 spx_setpersist(cb);
1920 (void) spx_output(cb, (struct mbuf *) 0);
1961 spx_output(cb, (struct mbuf *)NULL);
1921 break;
1922
1923 /*
1924 * Keep-alive timer went off; send something
1925 * or drop connection if idle for too long.
1926 */
1927 case SPXT_KEEP:
1928 spxstat.spxs_keeptimeo++;
1929 if (cb->s_state < TCPS_ESTABLISHED)
1930 goto dropit;
1931 if (cb->s_ipxpcb->ipxp_socket->so_options & SO_KEEPALIVE) {
1932 if (cb->s_idle >= SPXTV_MAXIDLE)
1933 goto dropit;
1934 spxstat.spxs_keepprobe++;
1962 break;
1963
1964 /*
1965 * Keep-alive timer went off; send something
1966 * or drop connection if idle for too long.
1967 */
1968 case SPXT_KEEP:
1969 spxstat.spxs_keeptimeo++;
1970 if (cb->s_state < TCPS_ESTABLISHED)
1971 goto dropit;
1972 if (cb->s_ipxpcb->ipxp_socket->so_options & SO_KEEPALIVE) {
1973 if (cb->s_idle >= SPXTV_MAXIDLE)
1974 goto dropit;
1975 spxstat.spxs_keepprobe++;
1935 (void) spx_output(cb, (struct mbuf *) 0);
1976 spx_output(cb, (struct mbuf *)NULL);
1936 } else
1937 cb->s_idle = 0;
1938 cb->s_timer[SPXT_KEEP] = SPXTV_KEEP;
1939 break;
1940 dropit:
1941 spxstat.spxs_keepdrops++;
1942 cb = spx_drop(cb, ETIMEDOUT);
1943 break;
1944 }
1945 return (cb);
1946}
1977 } else
1978 cb->s_idle = 0;
1979 cb->s_timer[SPXT_KEEP] = SPXTV_KEEP;
1980 break;
1981 dropit:
1982 spxstat.spxs_keepdrops++;
1983 cb = spx_drop(cb, ETIMEDOUT);
1984 break;
1985 }
1986 return (cb);
1987}