diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 1996-03-04 10:37:32 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 1996-03-04 10:37:32 +0000 |
commit | 19b3595c2000294ed57cd7cb23e1d91ee553215d (patch) | |
tree | 404b337fc172b005d07d5f30eeeb873a270a9eac /sys/netiso/tp_subr.c | |
parent | d4b3fca05966647ecd8191d973cdce74570844ca (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.c | 741 |
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"); } } |