1 /* $NetBSD: tcp_output.c,v 1.27 1998/01/05 10:32:05 thorpej Exp $ */ 2 3 /* 4 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by the University of 18 * California, Berkeley and its contributors. 19 * 4. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * @(#)tcp_output.c 8.4 (Berkeley) 5/24/95 36 */ 37 38 #include <sys/param.h> 39 #include <sys/systm.h> 40 #include <sys/malloc.h> 41 #include <sys/mbuf.h> 42 #include <sys/protosw.h> 43 #include <sys/socket.h> 44 #include <sys/socketvar.h> 45 #include <sys/errno.h> 46 47 #include <net/if.h> 48 #include <net/route.h> 49 50 #include <netinet/in.h> 51 #include <netinet/in_systm.h> 52 #include <netinet/ip.h> 53 #include <netinet/in_pcb.h> 54 #include <netinet/ip_var.h> 55 #include <netinet/tcp.h> 56 #define TCPOUTFLAGS 57 #include <netinet/tcp_fsm.h> 58 #include <netinet/tcp_seq.h> 59 #include <netinet/tcp_timer.h> 60 #include <netinet/tcp_var.h> 61 #include <netinet/tcpip.h> 62 #include <netinet/tcp_debug.h> 63 64 #ifdef TUBA 65 #include <netiso/iso.h> 66 #include <netiso/tuba_table.h> 67 #endif 68 69 #ifdef notyet 70 extern struct mbuf *m_copypack(); 71 #endif 72 73 #define MAX_TCPOPTLEN 32 /* max # bytes that go in options */ 74 75 static __inline void tcp_segsize __P((struct tcpcb *, int *, int *)); 76 static __inline void 77 tcp_segsize(tp, txsegsizep, rxsegsizep) 78 struct tcpcb *tp; 79 int *txsegsizep, *rxsegsizep; 80 { 81 struct inpcb *inp = tp->t_inpcb; 82 struct rtentry *rt; 83 struct ifnet *ifp; 84 int size; 85 86 if ((rt = in_pcbrtentry(inp)) == NULL) { 87 size = tcp_mssdflt; 88 goto out; 89 } 90 91 ifp = rt->rt_ifp; 92 93 if (rt->rt_rmx.rmx_mtu != 0) 94 size = rt->rt_rmx.rmx_mtu - sizeof(struct tcpiphdr); 95 else if (ip_mtudisc || in_localaddr(inp->inp_faddr) || 96 ifp->if_flags & IFF_LOOPBACK) 97 size = ifp->if_mtu - sizeof(struct tcpiphdr); 98 else 99 size = tcp_mssdflt; 100 101 out: 102 *txsegsizep = min(tp->t_peermss, size); 103 *rxsegsizep = min(tp->t_ourmss, size); 104 105 if (*txsegsizep != tp->t_segsz) { 106 tp->snd_cwnd = (tp->snd_cwnd / tp->t_segsz) * *txsegsizep; 107 tp->snd_ssthresh = (tp->snd_ssthresh / tp->t_segsz) * 108 *txsegsizep; 109 tp->t_segsz = *txsegsizep; 110 } 111 } 112 113 /* 114 * Tcp output routine: figure out what should be sent and send it. 115 */ 116 int 117 tcp_output(tp) 118 register struct tcpcb *tp; 119 { 120 register struct socket *so = tp->t_inpcb->inp_socket; 121 register long len, win; 122 int off, flags, error; 123 register struct mbuf *m; 124 register struct tcpiphdr *ti; 125 u_char opt[MAX_TCPOPTLEN]; 126 unsigned optlen, hdrlen; 127 int idle, sendalot, txsegsize, rxsegsize; 128 129 tcp_segsize(tp, &txsegsize, &rxsegsize); 130 131 /* 132 * Determine length of data that should be transmitted, 133 * and flags that will be used. 134 * If there is some data or critical controls (SYN, RST) 135 * to send, then transmit; otherwise, investigate further. 136 */ 137 idle = (tp->snd_max == tp->snd_una); 138 if (idle && tp->t_idle >= tp->t_rxtcur) 139 /* 140 * We have been idle for "a while" and no acks are 141 * expected to clock out any data we send -- 142 * slow start to get ack "clock" running again. 143 */ 144 tp->snd_cwnd = TCP_INITIAL_WINDOW(txsegsize); 145 again: 146 sendalot = 0; 147 off = tp->snd_nxt - tp->snd_una; 148 win = min(tp->snd_wnd, tp->snd_cwnd); 149 150 flags = tcp_outflags[tp->t_state]; 151 /* 152 * If in persist timeout with window of 0, send 1 byte. 153 * Otherwise, if window is small but nonzero 154 * and timer expired, we will send what we can 155 * and go to transmit state. 156 */ 157 if (tp->t_force) { 158 if (win == 0) { 159 /* 160 * If we still have some data to send, then 161 * clear the FIN bit. Usually this would 162 * happen below when it realizes that we 163 * aren't sending all the data. However, 164 * if we have exactly 1 byte of unset data, 165 * then it won't clear the FIN bit below, 166 * and if we are in persist state, we wind 167 * up sending the packet without recording 168 * that we sent the FIN bit. 169 * 170 * We can't just blindly clear the FIN bit, 171 * because if we don't have any more data 172 * to send then the probe will be the FIN 173 * itself. 174 */ 175 if (off < so->so_snd.sb_cc) 176 flags &= ~TH_FIN; 177 win = 1; 178 } else { 179 tp->t_timer[TCPT_PERSIST] = 0; 180 tp->t_rxtshift = 0; 181 } 182 } 183 184 if (win < so->so_snd.sb_cc) { 185 len = win - off; 186 flags &= ~TH_FIN; 187 } else 188 len = so->so_snd.sb_cc - off; 189 190 if (len < 0) { 191 /* 192 * If FIN has been sent but not acked, 193 * but we haven't been called to retransmit, 194 * len will be -1. Otherwise, window shrank 195 * after we sent into it. If window shrank to 0, 196 * cancel pending retransmit, pull snd_nxt back 197 * to (closed) window, and set the persist timer 198 * if it isn't already going. If the window didn't 199 * close completely, just wait for an ACK. 200 */ 201 len = 0; 202 if (win == 0) { 203 tp->t_timer[TCPT_REXMT] = 0; 204 tp->t_rxtshift = 0; 205 tp->snd_nxt = tp->snd_una; 206 if (tp->t_timer[TCPT_PERSIST] == 0) 207 tcp_setpersist(tp); 208 } 209 } 210 if (len > txsegsize) { 211 len = txsegsize; 212 flags &= ~TH_FIN; 213 sendalot = 1; 214 } 215 216 win = sbspace(&so->so_rcv); 217 218 /* 219 * Sender silly window avoidance. If connection is idle 220 * and can send all data, a maximum segment, 221 * at least a maximum default-size segment do it, 222 * or are forced, do it; otherwise don't bother. 223 * If peer's buffer is tiny, then send 224 * when window is at least half open. 225 * If retransmitting (possibly after persist timer forced us 226 * to send into a small window), then must resend. 227 */ 228 if (len) { 229 if (len == txsegsize) 230 goto send; 231 if ((idle || tp->t_flags & TF_NODELAY) && 232 len + off >= so->so_snd.sb_cc) 233 goto send; 234 if (tp->t_force) 235 goto send; 236 if (len >= tp->max_sndwnd / 2) 237 goto send; 238 if (SEQ_LT(tp->snd_nxt, tp->snd_max)) 239 goto send; 240 } 241 242 /* 243 * Compare available window to amount of window known to peer 244 * (as advertised window less next expected input). If the 245 * difference is at least twice the size of the largest segment 246 * we expect to receive (i.e. two segments) or at least 50% of 247 * the maximum possible window, then want to send a window update 248 * to peer. 249 */ 250 if (win > 0) { 251 /* 252 * "adv" is the amount we can increase the window, 253 * taking into account that we are limited by 254 * TCP_MAXWIN << tp->rcv_scale. 255 */ 256 long adv = min(win, (long)TCP_MAXWIN << tp->rcv_scale) - 257 (tp->rcv_adv - tp->rcv_nxt); 258 259 if (adv >= (long) (2 * rxsegsize)) 260 goto send; 261 if (2 * adv >= (long) so->so_rcv.sb_hiwat) 262 goto send; 263 } 264 265 /* 266 * Send if we owe peer an ACK. 267 */ 268 if (tp->t_flags & TF_ACKNOW) 269 goto send; 270 if (flags & (TH_SYN|TH_RST)) 271 goto send; 272 if (SEQ_GT(tp->snd_up, tp->snd_una)) 273 goto send; 274 /* 275 * If our state indicates that FIN should be sent 276 * and we have not yet done so, or we're retransmitting the FIN, 277 * then we need to send. 278 */ 279 if (flags & TH_FIN && 280 ((tp->t_flags & TF_SENTFIN) == 0 || tp->snd_nxt == tp->snd_una)) 281 goto send; 282 283 /* 284 * TCP window updates are not reliable, rather a polling protocol 285 * using ``persist'' packets is used to insure receipt of window 286 * updates. The three ``states'' for the output side are: 287 * idle not doing retransmits or persists 288 * persisting to move a small or zero window 289 * (re)transmitting and thereby not persisting 290 * 291 * tp->t_timer[TCPT_PERSIST] 292 * is set when we are in persist state. 293 * tp->t_force 294 * is set when we are called to send a persist packet. 295 * tp->t_timer[TCPT_REXMT] 296 * is set when we are retransmitting 297 * The output side is idle when both timers are zero. 298 * 299 * If send window is too small, there is data to transmit, and no 300 * retransmit or persist is pending, then go to persist state. 301 * If nothing happens soon, send when timer expires: 302 * if window is nonzero, transmit what we can, 303 * otherwise force out a byte. 304 */ 305 if (so->so_snd.sb_cc && tp->t_timer[TCPT_REXMT] == 0 && 306 tp->t_timer[TCPT_PERSIST] == 0) { 307 tp->t_rxtshift = 0; 308 tcp_setpersist(tp); 309 } 310 311 /* 312 * No reason to send a segment, just return. 313 */ 314 return (0); 315 316 send: 317 /* 318 * Before ESTABLISHED, force sending of initial options 319 * unless TCP set not to do any options. 320 * NOTE: we assume that the IP/TCP header plus TCP options 321 * always fit in a single mbuf, leaving room for a maximum 322 * link header, i.e. 323 * max_linkhdr + sizeof (struct tcpiphdr) + optlen <= MHLEN 324 */ 325 optlen = 0; 326 hdrlen = sizeof (struct tcpiphdr); 327 if (flags & TH_SYN) { 328 tp->snd_nxt = tp->iss; 329 tp->t_ourmss = tcp_mss_to_advertise(tp); 330 if ((tp->t_flags & TF_NOOPT) == 0) { 331 opt[0] = TCPOPT_MAXSEG; 332 opt[1] = 4; 333 opt[2] = (tp->t_ourmss >> 8) & 0xff; 334 opt[3] = tp->t_ourmss & 0xff; 335 optlen = 4; 336 337 if ((tp->t_flags & TF_REQ_SCALE) && 338 ((flags & TH_ACK) == 0 || 339 (tp->t_flags & TF_RCVD_SCALE))) { 340 *((u_int32_t *) (opt + optlen)) = htonl( 341 TCPOPT_NOP << 24 | 342 TCPOPT_WINDOW << 16 | 343 TCPOLEN_WINDOW << 8 | 344 tp->request_r_scale); 345 optlen += 4; 346 } 347 } 348 } 349 350 /* 351 * Send a timestamp and echo-reply if this is a SYN and our side 352 * wants to use timestamps (TF_REQ_TSTMP is set) or both our side 353 * and our peer have sent timestamps in our SYN's. 354 */ 355 if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP && 356 (flags & TH_RST) == 0 && 357 ((flags & (TH_SYN|TH_ACK)) == TH_SYN || 358 (tp->t_flags & TF_RCVD_TSTMP))) { 359 u_int32_t *lp = (u_int32_t *)(opt + optlen); 360 361 /* Form timestamp option as shown in appendix A of RFC 1323. */ 362 *lp++ = htonl(TCPOPT_TSTAMP_HDR); 363 *lp++ = htonl(tcp_now); 364 *lp = htonl(tp->ts_recent); 365 optlen += TCPOLEN_TSTAMP_APPA; 366 } 367 368 hdrlen += optlen; 369 370 /* 371 * Adjust data length if insertion of options will 372 * bump the packet length beyond the txsegsize length. 373 */ 374 if (len > txsegsize - optlen) { 375 len = txsegsize - optlen; 376 flags &= ~TH_FIN; 377 sendalot = 1; 378 } 379 380 #ifdef DIAGNOSTIC 381 if (max_linkhdr + hdrlen > MHLEN) 382 panic("tcphdr too big"); 383 #endif 384 385 /* 386 * Grab a header mbuf, attaching a copy of data to 387 * be transmitted, and initialize the header from 388 * the template for sends on this connection. 389 */ 390 if (len) { 391 if (tp->t_force && len == 1) 392 tcpstat.tcps_sndprobe++; 393 else if (SEQ_LT(tp->snd_nxt, tp->snd_max)) { 394 tcpstat.tcps_sndrexmitpack++; 395 tcpstat.tcps_sndrexmitbyte += len; 396 } else { 397 tcpstat.tcps_sndpack++; 398 tcpstat.tcps_sndbyte += len; 399 } 400 #ifdef notyet 401 if ((m = m_copypack(so->so_snd.sb_mb, off, 402 (int)len, max_linkhdr + hdrlen)) == 0) { 403 error = ENOBUFS; 404 goto out; 405 } 406 /* 407 * m_copypack left space for our hdr; use it. 408 */ 409 m->m_len += hdrlen; 410 m->m_data -= hdrlen; 411 #else 412 MGETHDR(m, M_DONTWAIT, MT_HEADER); 413 if (m == NULL) { 414 error = ENOBUFS; 415 goto out; 416 } 417 m->m_data += max_linkhdr; 418 m->m_len = hdrlen; 419 if (len <= MHLEN - hdrlen - max_linkhdr) { 420 m_copydata(so->so_snd.sb_mb, off, (int) len, 421 mtod(m, caddr_t) + hdrlen); 422 m->m_len += len; 423 } else { 424 m->m_next = m_copy(so->so_snd.sb_mb, off, (int) len); 425 if (m->m_next == 0) { 426 (void) m_freem(m); 427 error = ENOBUFS; 428 goto out; 429 } 430 } 431 #endif 432 /* 433 * If we're sending everything we've got, set PUSH. 434 * (This will keep happy those implementations which only 435 * give data to the user when a buffer fills or 436 * a PUSH comes in.) 437 */ 438 if (off + len == so->so_snd.sb_cc) 439 flags |= TH_PUSH; 440 } else { 441 if (tp->t_flags & TF_ACKNOW) 442 tcpstat.tcps_sndacks++; 443 else if (flags & (TH_SYN|TH_FIN|TH_RST)) 444 tcpstat.tcps_sndctrl++; 445 else if (SEQ_GT(tp->snd_up, tp->snd_una)) 446 tcpstat.tcps_sndurg++; 447 else 448 tcpstat.tcps_sndwinup++; 449 450 MGETHDR(m, M_DONTWAIT, MT_HEADER); 451 if (m == NULL) { 452 error = ENOBUFS; 453 goto out; 454 } 455 m->m_data += max_linkhdr; 456 m->m_len = hdrlen; 457 } 458 m->m_pkthdr.rcvif = (struct ifnet *)0; 459 ti = mtod(m, struct tcpiphdr *); 460 if (tp->t_template == 0) 461 panic("tcp_output"); 462 bcopy((caddr_t)tp->t_template, (caddr_t)ti, sizeof (struct tcpiphdr)); 463 464 /* 465 * Fill in fields, remembering maximum advertised 466 * window for use in delaying messages about window sizes. 467 * If resending a FIN, be sure not to use a new sequence number. 468 */ 469 if (flags & TH_FIN && tp->t_flags & TF_SENTFIN && 470 tp->snd_nxt == tp->snd_max) 471 tp->snd_nxt--; 472 /* 473 * If we are doing retransmissions, then snd_nxt will 474 * not reflect the first unsent octet. For ACK only 475 * packets, we do not want the sequence number of the 476 * retransmitted packet, we want the sequence number 477 * of the next unsent octet. So, if there is no data 478 * (and no SYN or FIN), use snd_max instead of snd_nxt 479 * when filling in ti_seq. But if we are in persist 480 * state, snd_max might reflect one byte beyond the 481 * right edge of the window, so use snd_nxt in that 482 * case, since we know we aren't doing a retransmission. 483 * (retransmit and persist are mutually exclusive...) 484 */ 485 if (len || (flags & (TH_SYN|TH_FIN)) || tp->t_timer[TCPT_PERSIST]) 486 ti->ti_seq = htonl(tp->snd_nxt); 487 else 488 ti->ti_seq = htonl(tp->snd_max); 489 ti->ti_ack = htonl(tp->rcv_nxt); 490 if (optlen) { 491 bcopy((caddr_t)opt, (caddr_t)(ti + 1), optlen); 492 ti->ti_off = (sizeof (struct tcphdr) + optlen) >> 2; 493 } 494 ti->ti_flags = flags; 495 /* 496 * Calculate receive window. Don't shrink window, 497 * but avoid silly window syndrome. 498 */ 499 if (win < (long)(so->so_rcv.sb_hiwat / 4) && win < (long)rxsegsize) 500 win = 0; 501 if (win > (long)TCP_MAXWIN << tp->rcv_scale) 502 win = (long)TCP_MAXWIN << tp->rcv_scale; 503 if (win < (long)(tp->rcv_adv - tp->rcv_nxt)) 504 win = (long)(tp->rcv_adv - tp->rcv_nxt); 505 ti->ti_win = htons((u_int16_t) (win>>tp->rcv_scale)); 506 if (SEQ_GT(tp->snd_up, tp->snd_nxt)) { 507 u_int32_t urp = tp->snd_up - tp->snd_nxt; 508 if (urp > IP_MAXPACKET) 509 urp = IP_MAXPACKET; 510 ti->ti_urp = htons((u_int16_t)urp); 511 ti->ti_flags |= TH_URG; 512 } else 513 /* 514 * If no urgent pointer to send, then we pull 515 * the urgent pointer to the left edge of the send window 516 * so that it doesn't drift into the send window on sequence 517 * number wraparound. 518 */ 519 tp->snd_up = tp->snd_una; /* drag it along */ 520 521 /* 522 * Put TCP length in extended header, and then 523 * checksum extended header and data. 524 */ 525 if (len + optlen) 526 ti->ti_len = htons((u_int16_t)(sizeof (struct tcphdr) + 527 optlen + len)); 528 ti->ti_sum = in_cksum(m, (int)(hdrlen + len)); 529 530 /* 531 * In transmit state, time the transmission and arrange for 532 * the retransmit. In persist state, just set snd_max. 533 */ 534 if (tp->t_force == 0 || tp->t_timer[TCPT_PERSIST] == 0) { 535 tcp_seq startseq = tp->snd_nxt; 536 537 /* 538 * Advance snd_nxt over sequence space of this segment. 539 */ 540 if (flags & (TH_SYN|TH_FIN)) { 541 if (flags & TH_SYN) 542 tp->snd_nxt++; 543 if (flags & TH_FIN) { 544 tp->snd_nxt++; 545 tp->t_flags |= TF_SENTFIN; 546 } 547 } 548 tp->snd_nxt += len; 549 if (SEQ_GT(tp->snd_nxt, tp->snd_max)) { 550 tp->snd_max = tp->snd_nxt; 551 /* 552 * Time this transmission if not a retransmission and 553 * not currently timing anything. 554 */ 555 if (tp->t_rtt == 0) { 556 tp->t_rtt = 1; 557 tp->t_rtseq = startseq; 558 tcpstat.tcps_segstimed++; 559 } 560 } 561 562 /* 563 * Set retransmit timer if not currently set, 564 * and not doing an ack or a keep-alive probe. 565 * Initial value for retransmit timer is smoothed 566 * round-trip time + 2 * round-trip time variance. 567 * Initialize shift counter which is used for backoff 568 * of retransmit time. 569 */ 570 if (tp->t_timer[TCPT_REXMT] == 0 && 571 tp->snd_nxt != tp->snd_una) { 572 tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; 573 if (tp->t_timer[TCPT_PERSIST]) { 574 tp->t_timer[TCPT_PERSIST] = 0; 575 tp->t_rxtshift = 0; 576 } 577 } 578 } else 579 if (SEQ_GT(tp->snd_nxt + len, tp->snd_max)) 580 tp->snd_max = tp->snd_nxt + len; 581 582 /* 583 * Trace. 584 */ 585 if (so->so_options & SO_DEBUG) 586 tcp_trace(TA_OUTPUT, tp->t_state, tp, ti, 0); 587 588 /* 589 * Fill in IP length and desired time to live and 590 * send to IP level. There should be a better way 591 * to handle ttl and tos; we could keep them in 592 * the template, but need a way to checksum without them. 593 */ 594 m->m_pkthdr.len = hdrlen + len; 595 #ifdef TUBA 596 if (tp->t_tuba_pcb) 597 error = tuba_output(m, tp); 598 else 599 #endif 600 { 601 struct rtentry *rt; 602 603 ((struct ip *)ti)->ip_len = m->m_pkthdr.len; 604 ((struct ip *)ti)->ip_ttl = tp->t_inpcb->inp_ip.ip_ttl; /* XXX */ 605 ((struct ip *)ti)->ip_tos = tp->t_inpcb->inp_ip.ip_tos; /* XXX */ 606 607 if (ip_mtudisc && (rt = in_pcbrtentry(tp->t_inpcb)) != 0 && 608 (rt->rt_rmx.rmx_locks & RTV_MTU) == 0) 609 ((struct ip *)ti)->ip_off |= IP_DF; 610 611 #if BSD >= 43 612 error = ip_output(m, tp->t_inpcb->inp_options, &tp->t_inpcb->inp_route, 613 so->so_options & SO_DONTROUTE, 0); 614 #else 615 error = ip_output(m, (struct mbuf *)0, &tp->t_inpcb->inp_route, 616 so->so_options & SO_DONTROUTE); 617 #endif 618 } 619 if (error) { 620 out: 621 if (error == ENOBUFS) { 622 tcp_quench(tp->t_inpcb, 0); 623 return (0); 624 } 625 if ((error == EHOSTUNREACH || error == ENETDOWN) 626 && TCPS_HAVERCVDSYN(tp->t_state)) { 627 tp->t_softerror = error; 628 return (0); 629 } 630 return (error); 631 } 632 tcpstat.tcps_sndtotal++; 633 if (tp->t_flags & TF_DELACK) 634 tcpstat.tcps_delack++; 635 636 /* 637 * Data sent (as far as we can tell). 638 * If this advertises a larger window than any other segment, 639 * then remember the size of the advertised window. 640 * Any pending ACK has now been sent. 641 */ 642 if (win > 0 && SEQ_GT(tp->rcv_nxt+win, tp->rcv_adv)) 643 tp->rcv_adv = tp->rcv_nxt + win; 644 tp->last_ack_sent = tp->rcv_nxt; 645 tp->t_flags &= ~TF_ACKNOW; 646 TCP_CLEAR_DELACK(tp); 647 if (sendalot) 648 goto again; 649 return (0); 650 } 651 652 void 653 tcp_setpersist(tp) 654 register struct tcpcb *tp; 655 { 656 register int t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> (1 + 2); 657 658 if (tp->t_timer[TCPT_REXMT]) 659 panic("tcp_output REXMT"); 660 /* 661 * Start/restart persistance timer. 662 */ 663 TCPT_RANGESET(tp->t_timer[TCPT_PERSIST], 664 t * tcp_backoff[tp->t_rxtshift], 665 TCPTV_PERSMIN, TCPTV_PERSMAX); 666 if (tp->t_rxtshift < TCP_MAXRXTSHIFT) 667 tp->t_rxtshift++; 668 } 669