summaryrefslogtreecommitdiff
path: root/sys/netiso/tp_subr.c
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>1996-03-04 10:37:32 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>1996-03-04 10:37:32 +0000
commit19b3595c2000294ed57cd7cb23e1d91ee553215d (patch)
tree404b337fc172b005d07d5f30eeeb873a270a9eac /sys/netiso/tp_subr.c
parentd4b3fca05966647ecd8191d973cdce74570844ca (diff)
Initial commit of NetBSD 960217 netiso.
all the rest is the fixes to the import by Niklas.
Diffstat (limited to 'sys/netiso/tp_subr.c')
-rw-r--r--sys/netiso/tp_subr.c741
1 files changed, 416 insertions, 325 deletions
diff --git a/sys/netiso/tp_subr.c b/sys/netiso/tp_subr.c
index c16c842c3f2..6334e4faf80 100644
--- a/sys/netiso/tp_subr.c
+++ b/sys/netiso/tp_subr.c
@@ -1,4 +1,5 @@
-/* $NetBSD: tp_subr.c,v 1.6 1995/08/04 01:13:29 mycroft Exp $ */
+/* $OpenBSD: tp_subr.c,v 1.2 1996/03/04 10:36:29 mickey Exp $ */
+/* $NetBSD: tp_subr.c,v 1.7 1996/02/13 22:11:59 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -40,13 +41,13 @@
All Rights Reserved
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
+both that copyright notice and this permission notice appear in
supporting documentation, and that the name of IBM not be
used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
+software without specific, written prior permission.
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
@@ -61,14 +62,13 @@ SOFTWARE.
/*
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
-/*
- * The main work of data transfer is done here.
- * These routines are called from tp.trans.
- * They include the routines that check the validity of acks and Xacks,
- * (tp_goodack() and tp_goodXack() )
- * take packets from socket buffers and send them (tp_send()),
- * drop the data from the socket buffers (tp_sbdrop()),
- * and put incoming packet data into socket buffers (tp_stash()).
+/*
+ * The main work of data transfer is done here. These routines are called
+ * from tp.trans. They include the routines that check the validity of acks
+ * and Xacks, (tp_goodack() and tp_goodXack() ) take packets from socket
+ * buffers and send them (tp_send()), drop the data from the socket buffers
+ * (tp_sbdrop()), and put incoming packet data into socket buffers
+ * (tp_stash()).
*/
#include <sys/param.h>
@@ -92,17 +92,16 @@ SOFTWARE.
#include <netiso/tp_trace.h>
#include <netiso/tp_meas.h>
#include <netiso/tp_seq.h>
+#include <netiso/tp_var.h>
-int tp_emit(), tp_sbdrop();
-int tprexmtthresh = 3;
-extern int ticks;
-void tp_send();
+int tprexmtthresh = 3;
+extern int ticks;
/*
* CALLED FROM:
* tp.trans, when an XAK arrives
* FUNCTION and ARGUMENTS:
- * Determines if the sequence number (seq) from the XAK
+ * Determines if the sequence number (seq) from the XAK
* acks anything new. If so, drop the appropriate tpdu
* from the XPD send queue.
* RETURN VALUE:
@@ -110,40 +109,46 @@ void tp_send();
*/
int
tp_goodXack(tpcb, seq)
- struct tp_pcb *tpcb;
- SeqNum seq;
+ struct tp_pcb *tpcb;
+ SeqNum seq;
{
- IFTRACE(D_XPD)
- tptraceTPCB(TPPTgotXack,
- seq, tpcb->tp_Xuna, tpcb->tp_Xsndnxt, tpcb->tp_sndnew,
- tpcb->tp_snduna);
- ENDTRACE
-
- if ( seq == tpcb->tp_Xuna ) {
- tpcb->tp_Xuna = tpcb->tp_Xsndnxt;
-
- /* DROP 1 packet from the Xsnd socket buf - just so happens
- * that only one packet can be there at any time
- * so drop the whole thing. If you allow > 1 packet
- * the socket buffer, then you'll have to keep
- * track of how many characters went w/ each XPD tpdu, so this
- * will get messier
- */
- IFDEBUG(D_XPD)
- dump_mbuf(tpcb->tp_Xsnd.sb_mb,
- "tp_goodXack Xsnd before sbdrop");
- ENDDEBUG
-
- IFTRACE(D_XPD)
- tptraceTPCB(TPPTmisc,
- "goodXack: dropping cc ",
- (int)(tpcb->tp_Xsnd.sb_cc),
- 0,0,0);
- ENDTRACE
- sbdroprecord(&tpcb->tp_Xsnd);
- return 1;
- }
+#ifdef TPPT
+ if (tp_traceflags[D_XPD]) {
+ tptraceTPCB(TPPTgotXack,
+ seq, tpcb->tp_Xuna, tpcb->tp_Xsndnxt, tpcb->tp_sndnew,
+ tpcb->tp_snduna);
+ }
+#endif
+
+ if (seq == tpcb->tp_Xuna) {
+ tpcb->tp_Xuna = tpcb->tp_Xsndnxt;
+
+ /*
+ * DROP 1 packet from the Xsnd socket buf - just so happens
+ * that only one packet can be there at any time so drop the
+ * whole thing. If you allow > 1 packet the socket buffer,
+ * then you'll have to keep track of how many characters went
+ * w/ each XPD tpdu, so this will get messier
+ */
+#ifdef ARGO_DEBUG
+ if (argo_debug[D_XPD]) {
+ dump_mbuf(tpcb->tp_Xsnd.sb_mb,
+ "tp_goodXack Xsnd before sbdrop");
+ }
+#endif
+
+#ifdef TPPT
+ if (tp_traceflags[D_XPD]) {
+ tptraceTPCB(TPPTmisc,
+ "goodXack: dropping cc ",
+ (int) (tpcb->tp_Xsnd.sb_cc),
+ 0, 0, 0);
+ }
+#endif
+ sbdroprecord(&tpcb->tp_Xsnd);
+ return 1;
+ }
return 0;
}
@@ -161,19 +166,22 @@ tp_goodXack(tpcb, seq)
void
tp_rtt_rtv(tpcb)
-register struct tp_pcb *tpcb;
+ register struct tp_pcb *tpcb;
{
- int old = tpcb->tp_rtt;
- int delta, elapsed = ticks - tpcb->tp_rttemit;
+ int old = tpcb->tp_rtt;
+ int delta = 0,
+ elapsed = ticks - tpcb->tp_rttemit;
if (tpcb->tp_rtt != 0) {
/*
- * rtt is the smoothed round trip time in machine clock ticks (hz).
- * It is stored as a fixed point number, unscaled (unlike the tcp
- * srtt). The rationale here is that it is only significant to the
- * nearest unit of slowtimo, which is at least 8 machine clock ticks
- * so there is no need to scale. The smoothing is done according
- * to the same formula as TCP (rtt = rtt*7/8 + measured_rtt/8).
+ * rtt is the smoothed round trip time in machine clock
+ * ticks (hz). It is stored as a fixed point number,
+ * unscaled (unlike the tcp srtt). The rationale here
+ * is that it is only significant to the nearest unit of
+ * slowtimo, which is at least 8 machine clock ticks
+ * so there is no need to scale. The smoothing is done
+ * according to the same formula as TCP (rtt = rtt*7/8
+ * + measured_rtt/8).
*/
delta = elapsed - tpcb->tp_rtt;
if ((tpcb->tp_rtt += (delta >> TP_RTT_ALPHA)) <= 0)
@@ -189,10 +197,10 @@ register struct tp_pcb *tpcb;
if ((tpcb->tp_rtv += ((delta - tpcb->tp_rtv) >> TP_RTV_ALPHA)) <= 0)
tpcb->tp_rtv = 1;
} else {
- /*
- * No rtt measurement yet - use the unsmoothed rtt.
- * Set the variance to half the rtt (so our first
- * retransmit happens at 3*rtt)
+ /*
+ * No rtt measurement yet - use the unsmoothed rtt. Set the
+ * variance to half the rtt (so our first retransmit happens
+ * at 3*rtt)
*/
tpcb->tp_rtt = elapsed;
tpcb->tp_rtv = elapsed >> 1;
@@ -211,11 +219,13 @@ register struct tp_pcb *tpcb;
* the minimum feasible timer (which is 2 ticks)."
*/
TP_RANGESET(tpcb->tp_dt_ticks, TP_REXMTVAL(tpcb),
- tpcb->tp_peer_acktime, 128 /* XXX */);
- IFDEBUG(D_RTT)
+ tpcb->tp_peer_acktime, 128 /* XXX */ );
+#ifdef ARGO_DEBUG
+ if (argo_debug[D_RTT]) {
printf("%s tpcb 0x%x, elapsed %d, delta %d, rtt %d, rtv %d, old %d\n",
- "tp_rtt_rtv:",tpcb,elapsed,delta,tpcb->tp_rtt,tpcb->tp_rtv,old);
- ENDDEBUG
+ "tp_rtt_rtv:", tpcb, elapsed, delta, tpcb->tp_rtt, tpcb->tp_rtv, old);
+ }
+#endif
tpcb->tp_rxtcur = tpcb->tp_dt_ticks;
}
@@ -223,7 +233,7 @@ register struct tp_pcb *tpcb;
* CALLED FROM:
* tp.trans when an AK arrives
* FUNCTION and ARGUMENTS:
- * Given (cdt), the credit from the AK tpdu, and
+ * Given (cdt), the credit from the AK tpdu, and
* (seq), the sequence number from the AK tpdu,
* tp_goodack() determines if the AK acknowledges something in the send
* window, and if so, drops the appropriate packets from the retransmission
@@ -240,55 +250,71 @@ register struct tp_pcb *tpcb;
*/
int
tp_goodack(tpcb, cdt, seq, subseq)
- register struct tp_pcb *tpcb;
- u_int cdt;
- register SeqNum seq;
- u_int subseq;
+ register struct tp_pcb *tpcb;
+ u_int cdt;
+ register SeqNum seq;
+ u_int subseq;
{
- int old_fcredit;
- int bang = 0; /* bang --> ack for something heretofore unacked */
- u_int bytes_acked;
+ int old_fcredit = 0;
+ int bang = 0; /* bang --> ack for something
+ * heretofore unacked */
+ u_int bytes_acked;
- IFDEBUG(D_ACKRECV)
+#ifdef ARGO_DEBUG
+ if (argo_debug[D_ACKRECV]) {
printf("goodack tpcb 0x%x seq 0x%x cdt %d una 0x%x new 0x%x nxt 0x%x\n",
- tpcb, seq, cdt, tpcb->tp_snduna, tpcb->tp_sndnew, tpcb->tp_sndnxt);
- ENDDEBUG
- IFTRACE(D_ACKRECV)
- tptraceTPCB(TPPTgotack,
- seq,cdt, tpcb->tp_snduna,tpcb->tp_sndnew,subseq);
- ENDTRACE
+ tpcb, seq, cdt, tpcb->tp_snduna, tpcb->tp_sndnew, tpcb->tp_sndnxt);
+ }
+#endif
- IFPERF(tpcb)
- tpmeas(tpcb->tp_lref, TPtime_ack_rcvd, (struct timeval *)0, seq, 0, 0);
- ENDPERF
+#ifdef TPPT
+ if (tp_traceflags[D_ACKRECV]) {
+ tptraceTPCB(TPPTgotack,
+ seq, cdt, tpcb->tp_snduna, tpcb->tp_sndnew, subseq);
+ }
+#endif
+
+#ifdef TP_PERF_MEAS
+ if (DOPERF(tpcb)) {
+ tpmeas(tpcb->tp_lref, TPtime_ack_rcvd, (struct timeval *) 0, seq, 0, 0);
+ }
+#endif
if (seq == tpcb->tp_snduna) {
if (subseq < tpcb->tp_r_subseq ||
- (subseq == tpcb->tp_r_subseq && cdt <= tpcb->tp_fcredit)) {
- discard_the_ack:
- IFDEBUG(D_ACKRECV)
+ (subseq == tpcb->tp_r_subseq && cdt <= tpcb->tp_fcredit)) {
+ discard_the_ack:
+#ifdef ARGO_DEBUG
+ if (argo_debug[D_ACKRECV]) {
printf("goodack discard : tpcb 0x%x subseq %d r_subseq %d\n",
- tpcb, subseq, tpcb->tp_r_subseq);
- ENDDEBUG
+ tpcb, subseq, tpcb->tp_r_subseq);
+ }
+#endif
goto done;
}
- if (cdt == tpcb->tp_fcredit /*&& thus subseq > tpcb->tp_r_subseq */) {
+ if (cdt == tpcb->tp_fcredit /* && thus subseq >
+ tpcb->tp_r_subseq */ ) {
tpcb->tp_r_subseq = subseq;
if (tpcb->tp_timer[TM_data_retrans] == 0)
tpcb->tp_dupacks = 0;
else if (++tpcb->tp_dupacks == tprexmtthresh) {
- /* partner went out of his way to signal with different
- subsequences that he has the same lack of an expected
- packet. This may be an early indiciation of a loss */
-
- SeqNum onxt = tpcb->tp_sndnxt;
- struct mbuf *onxt_m = tpcb->tp_sndnxt_m;
- u_int win = min(tpcb->tp_fcredit,
- tpcb->tp_cong_win / tpcb->tp_l_tpdusize) / 2;
- IFDEBUG(D_ACKRECV)
+ /*
+ * partner went out of his way to signal with
+ * different subsequences that he has the
+ * same lack of an expected packet. This may
+ * be an early indiciation of a loss
+ */
+
+ SeqNum onxt = tpcb->tp_sndnxt;
+ struct mbuf *onxt_m = tpcb->tp_sndnxt_m;
+ u_int win = min(tpcb->tp_fcredit,
+ tpcb->tp_cong_win / tpcb->tp_l_tpdusize) / 2;
+#ifdef ARGO_DEBUG
+ if (argo_debug[D_ACKRECV]) {
printf("%s tpcb 0x%x seq 0x%x rttseq 0x%x onxt 0x%x\n",
- "goodack dupacks:", tpcb, seq, tpcb->tp_rttseq, onxt);
- ENDDEBUG
+ "goodack dupacks:", tpcb, seq, tpcb->tp_rttseq, onxt);
+ }
+#endif
if (win < 2)
win = 2;
tpcb->tp_ssthresh = win * tpcb->tp_l_tpdusize;
@@ -304,7 +330,6 @@ tp_goodack(tpcb, cdt, seq, subseq)
tpcb->tp_sndnxt = onxt;
tpcb->tp_sndnxt_m = onxt_m;
}
-
} else if (tpcb->tp_dupacks > tprexmtthresh) {
tpcb->tp_cong_win += tpcb->tp_l_tpdusize;
}
@@ -317,8 +342,8 @@ tp_goodack(tpcb, cdt, seq, subseq)
* for the other side's cached packets, retract it.
*/
if (tpcb->tp_dupacks > tprexmtthresh &&
- tpcb->tp_cong_win > tpcb->tp_ssthresh)
- tpcb->tp_cong_win = tpcb->tp_ssthresh;
+ tpcb->tp_cong_win > tpcb->tp_ssthresh)
+ tpcb->tp_cong_win = tpcb->tp_ssthresh;
tpcb->tp_r_subseq = subseq;
old_fcredit = tpcb->tp_fcredit;
tpcb->tp_fcredit = cdt;
@@ -360,7 +385,7 @@ tp_goodack(tpcb, cdt, seq, subseq)
* open quickly enough.
*/
{
- u_int cw = tpcb->tp_cong_win, incr = tpcb->tp_l_tpdusize;
+ u_int cw = tpcb->tp_cong_win, incr = tpcb->tp_l_tpdusize;
incr = min(incr, bytes_acked);
if (cw > tpcb->tp_ssthresh)
@@ -370,13 +395,12 @@ tp_goodack(tpcb, cdt, seq, subseq)
}
tpcb->tp_snduna = seq;
if (SEQ_LT(tpcb, tpcb->tp_sndnxt, seq)) {
- tpcb->tp_sndnxt = seq;
- tpcb->tp_sndnxt_m = 0;
+ tpcb->tp_sndnxt = seq;
+ tpcb->tp_sndnxt_m = 0;
}
bang++;
- }
-
- if( cdt != 0 && old_fcredit == 0 ) {
+ }
+ if (cdt != 0 && old_fcredit == 0) {
tpcb->tp_sendfcc = 1;
}
if (cdt == 0) {
@@ -396,12 +420,17 @@ tp_goodack(tpcb, cdt, seq, subseq)
bang |= (old_fcredit < cdt);
done:
- IFDEBUG(D_ACKRECV)
+#ifdef ARGO_DEBUG
+ if (argo_debug[D_ACKRECV]) {
printf("goodack returns 0x%x, cdt 0x%x ocdt 0x%x cwin 0x%x\n",
- bang, cdt, old_fcredit, tpcb->tp_cong_win);
- ENDDEBUG
- /* if (bang) XXXXX Very bad to remove this test, but somethings broken */
- tp_send(tpcb);
+ bang, cdt, old_fcredit, tpcb->tp_cong_win);
+ }
+#endif
+ /*
+ * if (bang) XXXXX Very bad to remove this test, but somethings
+ * broken
+ */
+ tp_send(tpcb);
return (bang);
}
@@ -412,22 +441,25 @@ done:
* drops everything up TO but not INCLUDING seq # (seq)
* from the retransmission queue.
*/
-tp_sbdrop(tpcb, seq)
- register struct tp_pcb *tpcb;
- SeqNum seq;
+int
+tp_sbdrop(tpcb, seq)
+ register struct tp_pcb *tpcb;
+ SeqNum seq;
{
struct sockbuf *sb = &tpcb->tp_sock->so_snd;
- register int i = SEQ_SUB(tpcb, seq, tpcb->tp_snduna);
- int oldcc = sb->sb_cc, oldi = i;
+ register int i = SEQ_SUB(tpcb, seq, tpcb->tp_snduna);
+ int oldcc = sb->sb_cc, oldi = i;
if (i >= tpcb->tp_seqhalf)
printf("tp_spdropping too much -- should panic");
while (i-- > 0)
sbdroprecord(sb);
- IFDEBUG(D_ACKRECV)
+#ifdef ARGO_DEBUG
+ if (argo_debug[D_ACKRECV]) {
printf("tp_sbdroping %d pkts %d bytes on %x at 0x%x\n",
- oldi, oldcc - sb->sb_cc, tpcb, seq);
- ENDDEBUG
+ oldi, oldcc - sb->sb_cc, tpcb, seq);
+ }
+#endif
if (sb_notify(sb))
sowwakeup(tpcb->tp_sock);
return (oldcc - sb->sb_cc);
@@ -453,18 +485,18 @@ tp_sbdrop(tpcb, seq)
*/
void
tp_send(tpcb)
- register struct tp_pcb *tpcb;
+ register struct tp_pcb *tpcb;
{
- register int len;
- register struct mbuf *m;
- struct mbuf *mb = 0;
- struct sockbuf *sb = &tpcb->tp_sock->so_snd;
- unsigned int eotsdu = 0;
- SeqNum highseq, checkseq;
- int idle, idleticks, off, cong_win;
+ register int len;
+ register struct mbuf *m;
+ struct mbuf *mb = 0;
+ struct sockbuf *sb = &tpcb->tp_sock->so_snd;
+ unsigned int eotsdu = 0;
+ SeqNum highseq, checkseq;
+ int idle, idleticks, off, cong_win;
#ifdef TP_PERF_MEAS
- int send_start_time = ticks;
- SeqNum oldnxt = tpcb->tp_sndnxt;
+ int send_start_time = ticks;
+ SeqNum oldnxt = tpcb->tp_sndnxt;
#endif /* TP_PERF_MEAS */
idle = (tpcb->tp_snduna == tpcb->tp_sndnew);
@@ -478,74 +510,86 @@ tp_send(tpcb)
*/
tpcb->tp_cong_win = tpcb->tp_l_tpdusize;
}
-
cong_win = tpcb->tp_cong_win;
highseq = SEQ(tpcb, tpcb->tp_fcredit + tpcb->tp_snduna);
if (tpcb->tp_Xsnd.sb_mb)
highseq = SEQ_MIN(tpcb, highseq, tpcb->tp_sndnew);
-
- IFDEBUG(D_DATA)
+
+#ifdef ARGO_DEBUG
+ if (argo_debug[D_DATA]) {
printf("tp_send enter tpcb 0x%x nxt 0x%x win %d high 0x%x\n",
- tpcb, tpcb->tp_sndnxt, cong_win, highseq);
- ENDDEBUG
- IFTRACE(D_DATA)
- tptraceTPCB( TPPTmisc, "tp_send sndnew snduna",
- tpcb->tp_sndnew, tpcb->tp_snduna, 0, 0);
- tptraceTPCB( TPPTmisc, "tp_send tpcb->tp_sndnxt win fcredit congwin",
- tpcb->tp_sndnxt, cong_win, tpcb->tp_fcredit, tpcb->tp_cong_win);
- ENDTRACE
- IFTRACE(D_DATA)
- tptraceTPCB( TPPTmisc, "tp_send 2 nxt high fcredit congwin",
- tpcb->tp_sndnxt, highseq, tpcb->tp_fcredit, cong_win);
- ENDTRACE
-
- if (tpcb->tp_sndnxt_m)
+ tpcb, tpcb->tp_sndnxt, cong_win, highseq);
+ }
+#endif
+#ifdef TPPT
+ if (tp_traceflags[D_DATA]) {
+ tptraceTPCB(TPPTmisc, "tp_send sndnew snduna",
+ tpcb->tp_sndnew, tpcb->tp_snduna, 0, 0);
+ tptraceTPCB(TPPTmisc, "tp_send tpcb->tp_sndnxt win fcredit congwin",
+ tpcb->tp_sndnxt, cong_win, tpcb->tp_fcredit, tpcb->tp_cong_win);
+ }
+#endif
+#ifdef TPPT
+ if (tp_traceflags[D_DATA]) {
+ tptraceTPCB(TPPTmisc, "tp_send 2 nxt high fcredit congwin",
+ tpcb->tp_sndnxt, highseq, tpcb->tp_fcredit, cong_win);
+ }
+#endif
+
+ if (tpcb->tp_sndnxt_m)
m = tpcb->tp_sndnxt_m;
else {
off = SEQ_SUB(tpcb, tpcb->tp_sndnxt, tpcb->tp_snduna);
for (m = sb->sb_mb; m && off > 0; m = m->m_next)
off--;
}
-send:
/*
* Avoid silly window syndrome here . . . figure out how!
*/
checkseq = tpcb->tp_sndnum;
if (idle && SEQ_LT(tpcb, tpcb->tp_sndnum, highseq))
- checkseq = highseq; /* i.e. DON'T retain highest assigned packet */
+ checkseq = highseq; /* i.e. DON'T retain highest assigned
+ * packet */
while ((SEQ_LT(tpcb, tpcb->tp_sndnxt, highseq)) && m && cong_win > 0) {
eotsdu = (m->m_flags & M_EOR) != 0;
len = m->m_pkthdr.len;
if (tpcb->tp_sndnxt == checkseq && eotsdu == 0 &&
- len < (tpcb->tp_l_tpdusize / 2))
- break; /* Nagle . . . . . */
+ len < (tpcb->tp_l_tpdusize / 2))
+ break; /* Nagle . . . . . */
cong_win -= len;
- /* make a copy - mb goes into the retransmission list
- * while m gets emitted. m_copy won't copy a zero-length mbuf.
+ /*
+ * make a copy - mb goes into the retransmission list while m
+ * gets emitted. m_copy won't copy a zero-length mbuf.
*/
mb = m;
m = m_copy(mb, 0, M_COPYALL);
if (m == MNULL)
- break;
- IFTRACE(D_STASH)
- tptraceTPCB( TPPTmisc,
- "tp_send mcopy nxt high eotsdu len",
- tpcb->tp_sndnxt, highseq, eotsdu, len);
- ENDTRACE
-
- IFDEBUG(D_DATA)
+ break;
+#ifdef TPPT
+ if (tp_traceflags[D_STASH]) {
+ tptraceTPCB(TPPTmisc,
+ "tp_send mcopy nxt high eotsdu len",
+ tpcb->tp_sndnxt, highseq, eotsdu, len);
+ }
+#endif
+
+#ifdef ARGO_DEBUG
+ if (argo_debug[D_DATA]) {
printf("tp_sending tpcb 0x%x nxt 0x%x\n",
- tpcb, tpcb->tp_sndnxt);
- ENDDEBUG
- /* when headers are precomputed, may need to fill
- in checksum here */
- if (tpcb->tp_sock->so_error =
- tp_emit(DT_TPDU_type, tpcb, tpcb->tp_sndnxt, eotsdu, m)) {
+ tpcb, tpcb->tp_sndnxt);
+ }
+#endif
+ /*
+ * when headers are precomputed, may need to fill in checksum
+ * here
+ */
+ tpcb->tp_sock->so_error =
+ tp_emit(DT_TPDU_type, tpcb, tpcb->tp_sndnxt, eotsdu, m);
+ if (tpcb->tp_sock->so_error != 0)
/* error */
break;
- }
m = mb->m_nextpkt;
tpcb->tp_sndnxt_m = m;
if (tpcb->tp_sndnxt == tpcb->tp_sndnew) {
@@ -569,7 +613,7 @@ send:
* of retransmit time.
*/
if (tpcb->tp_timer[TM_data_retrans] == 0 &&
- tpcb->tp_class != TP_CLASS_0) {
+ tpcb->tp_class != TP_CLASS_0) {
tpcb->tp_timer[TM_data_retrans] = tpcb->tp_dt_ticks;
tpcb->tp_timer[TM_sendack] = tpcb->tp_keepalive_ticks;
tpcb->tp_rxtshift = 0;
@@ -578,61 +622,63 @@ send:
if (SEQ_GT(tpcb, tpcb->tp_sndnew, tpcb->tp_sndnum))
tpcb->tp_oktonagle = 0;
#ifdef TP_PERF_MEAS
- IFPERF(tpcb)
- {
- register int npkts;
- int elapsed = ticks - send_start_time, *t;
- struct timeval now;
+ if (DOPERF(tpcb)) {
+ register int npkts;
+ int elapsed = ticks - send_start_time, *t;
+ struct timeval now;
- npkts = SEQ_SUB(tpcb, tpcb->tp_sndnxt, oldnxt);
+ npkts = SEQ_SUB(tpcb, tpcb->tp_sndnxt, oldnxt);
- if (npkts > 0)
- tpcb->tp_Nwindow++;
+ if (npkts > 0)
+ tpcb->tp_Nwindow++;
- if (npkts > TP_PM_MAX)
- npkts = TP_PM_MAX;
+ if (npkts > TP_PM_MAX)
+ npkts = TP_PM_MAX;
- t = &(tpcb->tp_p_meas->tps_sendtime[npkts]);
- *t += (t - elapsed) >> TP_RTT_ALPHA;
+ t = &(tpcb->tp_p_meas->tps_sendtime[npkts]);
+ *t += (t - elapsed) >> TP_RTT_ALPHA;
- if (mb == 0) {
- IncPStat(tpcb, tps_win_lim_by_data[npkts] );
- } else {
- IncPStat(tpcb, tps_win_lim_by_cdt[npkts] );
- /* not true with congestion-window being used */
- }
- now.tv_sec = elapsed / hz;
- now.tv_usec = (elapsed - (hz * now.tv_sec)) * 1000000 / hz;
- tpmeas( tpcb->tp_lref,
- TPsbsend, &elapsed, newseq, tpcb->tp_Nwindow, npkts);
+ if (mb == 0) {
+ IncPStat(tpcb, tps_win_lim_by_data[npkts]);
+ } else {
+ IncPStat(tpcb, tps_win_lim_by_cdt[npkts]);
+ /* not true with congestion-window being used */
}
- ENDPERF
-#endif /* TP_PERF_MEAS */
+ now.tv_sec = elapsed / hz;
+ now.tv_usec = (elapsed - (hz * now.tv_sec)) * 1000000 / hz;
+ tpmeas(tpcb->tp_lref,
+ TPsbsend, &elapsed, newseq, tpcb->tp_Nwindow, npkts);
+ }
+#endif /* TP_PERF_MEAS */
+
+#ifdef TPPT
+ if (tp_traceflags[D_DATA]) {
+ tptraceTPCB(TPPTmisc,
+ "tp_send at end: new nxt eotsdu error",
+ tpcb->tp_sndnew, tpcb->tp_sndnxt, eotsdu,
+ tpcb->tp_sock->so_error);
- IFTRACE(D_DATA)
- tptraceTPCB( TPPTmisc,
- "tp_send at end: new nxt eotsdu error",
- tpcb->tp_sndnew, tpcb->tp_sndnxt, eotsdu, tpcb->tp_sock->so_error);
-
- ENDTRACE
+ }
+#endif
}
-int TPNagleok;
-int TPNagled;
+int TPNagleok;
+int TPNagled;
+int
tp_packetize(tpcb, m, eotsdu)
-register struct tp_pcb *tpcb;
-register struct mbuf *m;
-int eotsdu;
+ register struct tp_pcb *tpcb;
+ register struct mbuf *m;
+ int eotsdu;
{
- register struct mbuf *n;
+ register struct mbuf *n = NULL;
register struct sockbuf *sb = &tpcb->tp_sock->so_snd;
- int maxsize = tpcb->tp_l_tpdusize
- - tp_headersize(DT_TPDU_type, tpcb)
- - (tpcb->tp_use_checksum?4:0) ;
- int totlen = m->m_pkthdr.len;
- struct mbuf *m_split();
+ int maxsize = tpcb->tp_l_tpdusize
+ - tp_headersize(DT_TPDU_type, tpcb)
+ - (tpcb->tp_use_checksum ? 4 : 0);
+ int totlen = m->m_pkthdr.len;
+
/*
* Pre-packetize the data in the sockbuf
* according to negotiated mtu. Do it here
@@ -641,10 +687,12 @@ int eotsdu;
* This presumes knowledge of sockbuf conventions.
* TODO: allocate space for header and fill it in (once!).
*/
- IFDEBUG(D_DATA)
+#ifdef ARGO_DEBUG
+ if (argo_debug[D_DATA]) {
printf("SEND BF: maxsize %d totlen %d eotsdu %d sndnum 0x%x\n",
- maxsize, totlen, eotsdu, tpcb->tp_sndnum);
- ENDTRACE
+ maxsize, totlen, eotsdu, tpcb->tp_sndnum);
+ }
+#endif
if (tpcb->tp_oktonagle) {
if ((n = sb->sb_mb) == 0)
panic("tp_packetize");
@@ -654,19 +702,23 @@ int eotsdu;
panic("tp_packetize 2");
SEQ_INC(tpcb, tpcb->tp_sndnum);
if (totlen + n->m_pkthdr.len < maxsize) {
- /* There is an unsent packet with space, combine data */
- struct mbuf *old_n = n;
- tpsbcheck(tpcb,3);
+ /*
+ * There is an unsent packet with space,
+ * combine data
+ */
+ struct mbuf *old_n = n;
+ tpsbcheck(tpcb, 3);
n->m_pkthdr.len += totlen;
while (n->m_next)
n = n->m_next;
sbcompress(sb, m, n);
- tpsbcheck(tpcb,4);
+ tpsbcheck(tpcb, 4);
n = old_n;
TPNagled++;
goto out;
}
}
+
while (m) {
n = m;
if (totlen > maxsize) {
@@ -682,17 +734,20 @@ int eotsdu;
}
out:
if (eotsdu) {
- n->m_flags |= M_EOR; /* XXX belongs at end */
+ n->m_flags |= M_EOR; /* XXX belongs at end */
tpcb->tp_oktonagle = 0;
} else {
SEQ_DEC(tpcb, tpcb->tp_sndnum);
tpcb->tp_oktonagle = 1;
TPNagleok++;
}
- IFDEBUG(D_DATA)
+
+#ifdef ARGO_DEBUG
+ if (argo_debug[D_DATA]) {
printf("SEND out: oktonagle %d sndnum 0x%x\n",
- tpcb->tp_oktonagle, tpcb->tp_sndnum);
- ENDTRACE
+ tpcb->tp_oktonagle, tpcb->tp_sndnum);
+ }
+#endif
return 0;
}
@@ -702,77 +757,85 @@ out:
* CALLED FROM:
* tp.trans on arrival of a DT tpdu
* FUNCTION, ARGUMENTS, and RETURN VALUE:
- * Returns 1 if
- * a) something new arrived and it's got eotsdu_reached bit on,
- * b) this arrival was caused other out-of-sequence things to be
+ * Returns 1 if
+ * a) something new arrived and it's got eotsdu_reached bit on,
+ * b) this arrival was caused other out-of-sequence things to be
* accepted, or
- * c) this arrival is the highest seq # for which we last gave credit
+ * c) this arrival is the highest seq # for which we last gave credit
* (sender just sent a whole window)
- * In other words, returns 1 if tp should send an ack immediately, 0 if
+ * In other words, returns 1 if tp should send an ack immediately, 0 if
* the ack can wait a while.
*
* Note: this implementation no longer renegs on credit, (except
* when debugging option D_RENEG is on, for the purpose of testing
- * ack subsequencing), so we don't need to check for incoming tpdus
+ * ack subsequencing), so we don't need to check for incoming tpdus
* being in a reneged portion of the window.
*/
+int
tp_stash(tpcb, e)
- register struct tp_pcb *tpcb;
- register struct tp_event *e;
+ register struct tp_pcb *tpcb;
+ register struct tp_event *e;
{
- register int ack_reason= tpcb->tp_ack_strat & ACK_STRAT_EACH;
- /* 0--> delay acks until full window */
- /* 1--> ack each tpdu */
-#ifndef lint
-#define E e->ATTR(DT_TPDU)
-#else /* lint */
-#define E e->ev_union.EV_DT_TPDU
-#endif /* lint */
-
- if ( E.e_eot ) {
+ register int ack_reason = tpcb->tp_ack_strat & ACK_STRAT_EACH;
+ /* 0--> delay acks until full window */
+ /* 1--> ack each tpdu */
+#define E e->TPDU_ATTR(DT)
+
+ if (E.e_eot) {
register struct mbuf *n = E.e_data;
n->m_flags |= M_EOR;
n->m_act = 0;
}
- IFDEBUG(D_STASH)
- dump_mbuf(tpcb->tp_sock->so_rcv.sb_mb,
- "stash: so_rcv before appending");
- dump_mbuf(E.e_data,
- "stash: e_data before appending");
- ENDDEBUG
+#ifdef ARGO_DEBUG
+ if (argo_debug[D_STASH]) {
+ dump_mbuf(tpcb->tp_sock->so_rcv.sb_mb,
+ "stash: so_rcv before appending");
+ dump_mbuf(E.e_data,
+ "stash: e_data before appending");
+ }
+#endif
- IFPERF(tpcb)
+#ifdef TP_PERF_MEAS
+ if (DOPERF(tpcb)) {
PStat(tpcb, Nb_from_ll) += E.e_datalen;
- tpmeas(tpcb->tp_lref, TPtime_from_ll, &e->e_time,
- E.e_seq, (u_int)PStat(tpcb, Nb_from_ll), (u_int)E.e_datalen);
- ENDPERF
+ tpmeas(tpcb->tp_lref, TPtime_from_ll,
+ &e->e_time, E.e_seq,
+ (u_int) PStat(tpcb, Nb_from_ll),
+ (u_int) E.e_datalen);
+ }
+#endif
if (E.e_seq == tpcb->tp_rcvnxt) {
- IFDEBUG(D_STASH)
- printf("stash EQ: seq 0x%x datalen 0x%x eot 0x%x\n",
- E.e_seq, E.e_datalen, E.e_eot);
- ENDDEBUG
+#ifdef ARGO_DEBUG
+ if (argo_debug[D_STASH]) {
+ printf("stash EQ: seq 0x%x datalen 0x%x eot 0x%x\n",
+ E.e_seq, E.e_datalen, E.e_eot);
+ }
+#endif
- IFTRACE(D_STASH)
- tptraceTPCB(TPPTmisc, "stash EQ: seq len eot",
- E.e_seq, E.e_datalen, E.e_eot, 0);
- ENDTRACE
+#ifdef TPPT
+ if (tp_traceflags[D_STASH]) {
+ tptraceTPCB(TPPTmisc, "stash EQ: seq len eot",
+ E.e_seq, E.e_datalen, E.e_eot, 0);
+ }
+#endif
SET_DELACK(tpcb);
sbappend(&tpcb->tp_sock->so_rcv, E.e_data);
- SEQ_INC( tpcb, tpcb->tp_rcvnxt );
- /*
+ SEQ_INC(tpcb, tpcb->tp_rcvnxt);
+ /*
* move chains from the reassembly queue to the socket buffer
*/
if (tpcb->tp_rsycnt) {
register struct mbuf **mp;
- struct mbuf **mplim;
+ struct mbuf **mplim;
- mp = tpcb->tp_rsyq + (tpcb->tp_rcvnxt % tpcb->tp_maxlcredit);
+ mp = tpcb->tp_rsyq + (tpcb->tp_rcvnxt %
+ tpcb->tp_maxlcredit);
mplim = tpcb->tp_rsyq + tpcb->tp_maxlcredit;
while (tpcb->tp_rsycnt && *mp) {
@@ -785,39 +848,52 @@ tp_stash(tpcb, e)
mp = tpcb->tp_rsyq;
}
}
- IFDEBUG(D_STASH)
- dump_mbuf(tpcb->tp_sock->so_rcv.sb_mb,
- "stash: so_rcv after appending");
- ENDDEBUG
+#ifdef ARGO_DEBUG
+ if (argo_debug[D_STASH]) {
+ dump_mbuf(tpcb->tp_sock->so_rcv.sb_mb,
+ "stash: so_rcv after appending");
+ }
+#endif
} else {
register struct mbuf **mp;
- SeqNum uwe;
+ SeqNum uwe;
- IFTRACE(D_STASH)
- tptraceTPCB(TPPTmisc, "stash Reseq: seq rcvnxt lcdt",
- E.e_seq, tpcb->tp_rcvnxt, tpcb->tp_lcredit, 0);
- ENDTRACE
+#ifdef TPPT
+ if (tp_traceflags[D_STASH]) {
+ tptraceTPCB(TPPTmisc, "stash Reseq: seq rcvnxt lcdt",
+ E.e_seq, tpcb->tp_rcvnxt,
+ tpcb->tp_lcredit, 0);
+ }
+#endif
if (tpcb->tp_rsyq == 0)
tp_rsyset(tpcb);
uwe = SEQ(tpcb, tpcb->tp_rcvnxt + tpcb->tp_maxlcredit);
if (tpcb->tp_rsyq == 0 ||
- !IN_RWINDOW(tpcb, E.e_seq, tpcb->tp_rcvnxt, uwe)) {
+ !IN_RWINDOW(tpcb, E.e_seq, tpcb->tp_rcvnxt, uwe)) {
ack_reason = ACK_DONT;
m_freem(E.e_data);
- } else if (*(mp = tpcb->tp_rsyq + (E.e_seq % tpcb->tp_maxlcredit))) {
- IFDEBUG(D_STASH)
+ } else if (*(mp = tpcb->tp_rsyq +
+ (E.e_seq % tpcb->tp_maxlcredit)) != NULL ) {
+#ifdef ARGO_DEBUG
+ if (argo_debug[D_STASH]) {
printf("tp_stash - drop & ack\n");
- ENDDEBUG
+ }
+#endif
- /* retransmission - drop it and force an ack */
+ /*
+ * retransmission - drop it and force
+ * an ack
+ */
IncStat(ts_dt_dup);
- IFPERF(tpcb)
+#ifdef TP_PERF_MEAS
+ if (DOPERF(tpcb)) {
IncPStat(tpcb, tps_n_ack_cuz_dup);
- ENDPERF
+ }
+#endif
- m_freem(E.e_data);
+ m_freem(E.e_data);
ack_reason |= ACK_DUP;
} else {
*mp = E.e_data;
@@ -825,41 +901,51 @@ tp_stash(tpcb, e)
ack_reason = ACK_DONT;
}
}
- /* there were some comments of historical interest here. */
+ /*
+ * there were some comments of historical interest
+ * here.
+ */
{
LOCAL_CREDIT(tpcb);
- if ( E.e_seq == tpcb->tp_sent_uwe )
+ if (E.e_seq == tpcb->tp_sent_uwe)
ack_reason |= ACK_STRAT_FULLWIN;
- IFTRACE(D_STASH)
- tptraceTPCB(TPPTmisc,
- "end of stash, eot, ack_reason, sent_uwe ",
- E.e_eot, ack_reason, tpcb->tp_sent_uwe, 0);
- ENDTRACE
+#ifdef TPPT
+ if (tp_traceflags[D_STASH]) {
+ tptraceTPCB(TPPTmisc,
+ "end of stash, eot, ack_reason, sent_uwe ",
+ E.e_eot, ack_reason, tpcb->tp_sent_uwe, 0);
+ }
+#endif
- if ( ack_reason == ACK_DONT ) {
- IncStat( ts_ackreason[ACK_DONT] );
+ if (ack_reason == ACK_DONT) {
+ IncStat(ts_ackreason[ACK_DONT]);
return 0;
} else {
- IFPERF(tpcb)
- if(ack_reason & ACK_STRAT_EACH) {
- IncPStat(tpcb, tps_n_ack_cuz_strat);
- } else if(ack_reason & ACK_STRAT_FULLWIN) {
- IncPStat(tpcb, tps_n_ack_cuz_fullwin);
- } else if(ack_reason & ACK_REORDER) {
- IncPStat(tpcb, tps_n_ack_cuz_reorder);
- }
- tpmeas(tpcb->tp_lref, TPtime_ack_sent, 0,
- SEQ_ADD(tpcb, E.e_seq, 1), 0, 0);
- ENDPERF
+#ifdef TP_PERF_MEAS
+ if (DOPERF(tpcb)) {
+ if (ack_reason & ACK_STRAT_EACH) {
+ IncPStat(tpcb, tps_n_ack_cuz_strat);
+ } else if (ack_reason & ACK_STRAT_FULLWIN) {
+ IncPStat(tpcb, tps_n_ack_cuz_fullwin);
+ } else if (ack_reason & ACK_REORDER) {
+ IncPStat(tpcb, tps_n_ack_cuz_reorder);
+ }
+ tpmeas(tpcb->tp_lref, TPtime_ack_sent, 0,
+ SEQ_ADD(tpcb, E.e_seq, 1), 0, 0);
+ }
+#endif
{
- register int i;
-
- /* keep track of all reasons that apply */
- for( i=1; i<_ACK_NUM_REASONS_ ;i++) {
- if( ack_reason & (1<<i) )
- IncStat( ts_ackreason[i] );
+ register int i;
+
+ /*
+ * keep track of all reasons
+ * that apply
+ */
+ for (i = 1; i < _ACK_NUM_REASONS_; i++) {
+ if (ack_reason & (1 << i))
+ IncStat(ts_ackreason[i]);
}
}
return 1;
@@ -872,13 +958,14 @@ tp_stash(tpcb, e)
* Do this when closing the socket, or when somebody has changed
* the space avaible in the receive socket (XXX).
*/
+void
tp_rsyflush(tpcb)
-register struct tp_pcb *tpcb;
+ register struct tp_pcb *tpcb;
{
- register struct mbuf *m, **mp;
+ register struct mbuf **mp;
if (tpcb->tp_rsycnt) {
- for (mp == tpcb->tp_rsyq + tpcb->tp_maxlcredit;
- --mp >= tpcb->tp_rsyq; )
+ for (mp = tpcb->tp_rsyq + tpcb->tp_maxlcredit;
+ --mp >= tpcb->tp_rsyq;)
if (*mp) {
tpcb->tp_rsycnt--;
m_freem(*mp);
@@ -888,43 +975,47 @@ register struct tp_pcb *tpcb;
tpcb->tp_rsycnt = 0;
}
}
- free((caddr_t)tpcb->tp_rsyq, M_PCB);
+ free((caddr_t) tpcb->tp_rsyq, M_PCB);
tpcb->tp_rsyq = 0;
}
+void
tp_rsyset(tpcb)
-register struct tp_pcb *tpcb;
+ register struct tp_pcb *tpcb;
{
register struct socket *so = tpcb->tp_sock;
- int maxcredit = tpcb->tp_xtd_format ? 0xffff : 0xf;
- int old_credit = tpcb->tp_maxlcredit;
- caddr_t rsyq;
+ int maxcredit = tpcb->tp_xtd_format ? 0xffff : 0xf;
+ int old_credit = tpcb->tp_maxlcredit;
+ caddr_t rsyq;
tpcb->tp_maxlcredit = maxcredit = min(maxcredit,
- (so->so_rcv.sb_hiwat + tpcb->tp_l_tpdusize)/ tpcb->tp_l_tpdusize);
+ (so->so_rcv.sb_hiwat + tpcb->tp_l_tpdusize) / tpcb->tp_l_tpdusize);
if (old_credit == tpcb->tp_maxlcredit && tpcb->tp_rsyq != 0)
return;
maxcredit *= sizeof(struct mbuf *);
if (tpcb->tp_rsyq)
tp_rsyflush(tpcb);
- if (rsyq = (caddr_t)malloc(maxcredit, M_PCB, M_NOWAIT))
+ if ((rsyq = (caddr_t) malloc(maxcredit, M_PCB, M_NOWAIT)) != NULL)
bzero(rsyq, maxcredit);
- tpcb->tp_rsyq = (struct mbuf **)rsyq;
+ tpcb->tp_rsyq = (struct mbuf **) rsyq;
}
+
+void
tpsbcheck(tpcb, i)
-struct tp_pcb *tpcb;
+ struct tp_pcb *tpcb;
+ int i;
{
register struct mbuf *n, *m;
- register int len = 0, mbcnt = 0, pktlen;
+ register int len = 0, mbcnt = 0, pktlen;
struct sockbuf *sb = &tpcb->tp_sock->so_snd;
for (n = sb->sb_mb; n; n = n->m_nextpkt) {
if ((n->m_flags & M_PKTHDR) == 0)
panic("tpsbcheck nohdr");
pktlen = len + n->m_pkthdr.len;
- for (m = n; m; m = m->m_next) {
+ for (m = n; m; m = m->m_next) {
len += m->m_len;
mbcnt += MSIZE;
if (m->m_flags & M_EXT)
@@ -932,13 +1023,13 @@ struct tp_pcb *tpcb;
}
if (len != pktlen) {
printf("test %d; len %d != pktlen %d on mbuf 0x%x\n",
- i, len, pktlen, n);
+ i, len, pktlen, n);
panic("tpsbcheck short");
}
}
if (len != sb->sb_cc || mbcnt != sb->sb_mbcnt) {
printf("test %d: cc %d != %d || mbcnt %d != %d\n", i, len, sb->sb_cc,
- mbcnt, sb->sb_mbcnt);
+ mbcnt, sb->sb_mbcnt);
panic("tpsbcheck");
}
}