PERFORCE change 161598 for review
Andre Oppermann
andre at FreeBSD.org
Tue May 5 07:32:36 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=161598
Change 161598 by andre at andre_t61 on 2009/05/05 07:32:16
Various WIP.
Affected files ...
.. //depot/projects/tcp_new/netinet/tcp_output.c#7 edit
Differences ...
==== //depot/projects/tcp_new/netinet/tcp_output.c#7 (text+ko) ====
@@ -200,7 +200,7 @@
*
* duna = unacknowledged data in flight
* swnd = remaining space in send window as advertised by remote end
- * cwnd = congestion window, remaing amount of data that can be unacknowledged in flight
+ * cwnd = congestion window, remaing amount of data that can be in flight unacknowledged
* dlen = remaing amount of data in send buffer available for sending
* len = amount of data we have *and* can send righ now
*
@@ -218,14 +218,25 @@
dlen = so->so_snd.sb_cc - duna;
len = min(dlen, min(swnd, cwnd));
+ /*
+ * XXXAO: todo token bucket, mss sized
+ * Retransmits should not fall under pacing limit
+ * and neither ACKs, window updates, etc. if there
+ * is no data pending.
+ */
if (len > 0 && (tp->t_flags & TF_PACE)) {
- len = tcp_snd_pace(tp, len); /* XXXAO: todo token bucket, mss sized */
+ len = tcp_snd_pace(tp, len);
if (len == 0)
return (0); /* next token is pending */
}
inflight = duna - tp->snd_sacked;
+ switch (tp->t_phase) {
+ case TP_IDLE:
+ break;
+ }
+
/*
* Send out a SYN immediatly.
*/
@@ -248,7 +259,7 @@
* if the window is big enough. Do not care about nagle
* and others. Otherwise things will go their normal way.
*/
- if (len > 0)
+ if (len <= dlen)
goto send;
}
@@ -259,6 +270,7 @@
goto send;
if (SEQ_LT(tp->snd_lastack, tp->snd_nxt) && !(tp->t_flags & TF_DELACK))
goto send;
+
/*
* For a duplicate ACK to be acceptable it must not carry any
* data nor update the window. This is a serious problem for
@@ -268,9 +280,9 @@
* a duplicate ACK (if the ack value didn't move forward). The
* question whether the other implementations see it the same way.
*/
- if ((tp->t_flags & TF_DUPACK) && tp->snd_dupack > 0 &&
- (tp->t_flags & TF_SACK_PERMIT)) {
- len = 0;
+ if ((tp->t_flags & TF_DUPACK) && tp->snd_dupack > 0) {
+ if (!(tp->t_flags & TF_SACK_PERMIT))
+ len = 0;
goto send;
}
@@ -431,81 +443,13 @@
return (0);
send:
- SOCKBUF_LOCK(&so->so_snd);
+ tcp_options(tp, &to, flags);
+ return (tcp_send(tp, &to, flags));
+}
- /*
- * Compute options for segment.
- * We only have to care about SYN and established connection
- * segments. Options for SYN-ACK segments are handled in TCP
- * syncache. Before ESTABLISHED, force sending of initial options
- * unless TCP set not to do any options.
- */
- to.to_flags = 0;
- if (!(tp->t_flags & TF_NOOPT)) {
- /*
- * Maximum segment size.
- */
- if (flags & TH_SYN) {
- to.to_mss = tcp_mss(&inp->inp_inc, 0, 0);
- to.to_flags |= TOF_MSS;
- }
-
- /*
- * Window scaling.
- */
- if ((flags & TH_SYN) && (tp->t_flags & TF_WINSCALE)) {
- to.to_wscale = tp->rcv_scale;
- to.to_flags |= TOF_SCALE;
- }
-
- /*
- * Timestamps.
- */
- if (tp->t_flags & TF_TIMESTAMP) {
- to.to_tsval = ticks + tp->ts_offset;
- to.to_tsecr = tp->ts_recent;
- to.to_flags |= TOF_TS;
- /*
- * Set receive buffer autosizing timestamp.
- */
- if (tp->rfbuf_ts == 0 &&
- (so->so_rcv.sb_flags & SB_AUTOSIZE))
- tp->rfbuf_ts = ticks;
- }
-
- /*
- * Selective ACK's.
- */
- if (tp->t_flags & TF_SACK_PERMIT) {
- if (flags & TH_SYN)
- to.to_flags |= TOF_SACKPERM;
- else if (TCPS_HAVEESTABLISHED(tp->t_state) &&
- tp->rcv_numsacks > 0) {
- to.to_flags |= TOF_SACK;
- to.to_nsacks = tp->rcv_numsacks;
- to.to_sacks = (u_char *)tp->sackblks;
- }
- }
-
- /*
- * TCP-MD5 (RFC2385).
- */
-#ifdef TCP_SIGNATURE
-#ifdef INET6
- if (!isipv6 && (tp->t_flags & TF_SIGNATURE)) {
-#else
- if (tp->t_flags & TF_SIGNATURE) {
-#endif /* INET6 */
- to.to_flags |= TOF_SIGNATURE;
- }
-#endif /* TCP_SIGNATURE */
-
- /*
- * Processing the options.
- */
- optlen = tcp_addoptions(&to, (u_char *)&opt);
- } else
- optlen = 0;
+int
+tcp_send(struct tcpcb *tp, struct tcpopt *to, int flags)
+{
/*
* Be careful not to send data and/or FIN on SYN segments.
@@ -535,6 +479,7 @@
else
th->th_win = (u_short)(rwin >> tp->rcv_scale);
+ SOCKBUF_LOCK(&so->so_snd);
/*
* Fill in fields.
*/
@@ -547,7 +492,7 @@
}
/*
- * If resending a SYN or FIN, be sure not to use a new sequence number.
+ * If resending a SYN or FIN, be sure NOT to use a new sequence number.
*/
if ((flags & TH_SYN) && (tp->t_flags & TF_SENTSYN))
th->th_seq--;
@@ -598,6 +543,18 @@
}
/*
+ * Update last send timestamp.
+ */
+ if ((tp->t_flags & TF_TIMESTAMP) && tp->snd_tslast != to->to_tsval)
+ tp->snd_tslast = to->to_tsval;
+
+ /*
+ * Last ACK we sent.
+ */
+ if (tp->snd_lastack != th->th_ack)
+ tp->snd_lastack = th->th_ack;
+
+ /*
* Any pending ACK has been sent.
* Clear related flags and disarm the delayed ACK timer.
*/
@@ -808,6 +765,7 @@
int off, int *olen, int optlen)
{
int len, slen, hdrs, hdrlen, linkhdr, optlen, ipoptlen;
+ int error = 0;
struct tcphdr *th;
struct ip *ip;
struct inpcb *inp = tp->t_inpcb;
@@ -997,18 +955,12 @@
("%s: data beyond FIN", __func__);
/*
- * Set the PUSH bit to indicate that we have reached
- * the end of the send buffer.
- */
- if (off + slen == so->so_snd.sb_cc) {
- th->th_flags =| TH_PSH;
- }
-
- /*
* If we're sending everything we've got, set PUSH.
* This will keep happy those implementations which
* only give data to the user when a buffer fills or
* a PUSH comes in.
+ * Set the PUSH bit to indicate that we have reached
+ * the end of the send buffer.
*/
if (slen > 0 && off + slen == so->so_snd.sb_cc)
th->th_flags |= TH_PUSH;
@@ -1201,6 +1153,84 @@
return;
}
+void
+tcp_options(struct tcpcb *tp, struct tcpopt *to, int flags)
+{
+ /*
+ * Compute options for segment.
+ * We only have to care about SYN and established connection
+ * segments. Options for SYN-ACK segments are handled in TCP
+ * syncache. Before ESTABLISHED, force sending of initial options
+ * unless TCP set not to do any options.
+ */
+ to.to_flags = 0;
+ if (!(tp->t_flags & TF_NOOPT)) {
+ /*
+ * Maximum segment size.
+ */
+ if (flags & TH_SYN) {
+ to.to_mss = tcp_mss(&inp->inp_inc, 0, 0);
+ to.to_flags |= TOF_MSS;
+ }
+
+ /*
+ * Window scaling.
+ */
+ if ((flags & TH_SYN) && (tp->t_flags & TF_WINSCALE)) {
+ to.to_wscale = tp->rcv_scale;
+ to.to_flags |= TOF_SCALE;
+ }
+
+ /*
+ * Timestamps.
+ */
+ if (tp->t_flags & TF_TIMESTAMP) {
+ to.to_tsval = ticks + tp->ts_offset;
+ to.to_tsecr = tp->ts_recent;
+ to.to_flags |= TOF_TS;
+ /*
+ * Set receive buffer autosizing timestamp.
+ */
+ if (tp->rfbuf_ts == 0 &&
+ (so->so_rcv.sb_flags & SB_AUTOSIZE))
+ tp->rfbuf_ts = ticks;
+ }
+
+ /*
+ * Selective ACK's.
+ */
+ if (tp->t_flags & TF_SACK_PERMIT) {
+ if (flags & TH_SYN)
+ to.to_flags |= TOF_SACKPERM;
+ else if (TCPS_HAVEESTABLISHED(tp->t_state) &&
+ tp->rcv_numsacks > 0) {
+ to.to_flags |= TOF_SACK;
+ to.to_nsacks = tp->rcv_numsacks;
+ to.to_sacks = (u_char *)tp->sackblks;
+ }
+ }
+
+ /*
+ * TCP-MD5 (RFC2385).
+ */
+#ifdef TCP_SIGNATURE
+#ifdef INET6
+ if (!isipv6 && (tp->t_flags & TF_SIGNATURE)) {
+#else
+ if (tp->t_flags & TF_SIGNATURE) {
+#endif /* INET6 */
+ to.to_flags |= TOF_SIGNATURE;
+ }
+#endif /* TCP_SIGNATURE */
+
+ /*
+ * Processing the options.
+ */
+ optlen = tcp_addoptions(&to, (u_char *)&opt);
+ } else
+ optlen = 0;
+}
+
static void
tcp_snd_autoscale(struct tcpcb *tp, int swnd)
{
More information about the p4-projects
mailing list