tcp_output.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:23k
源码类别:

VxWorks

开发平台:

C/C++

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