source: rtems/cpukit/libnetworking/netinet/tcp_output.c @ 65c6425

4.115
Last change on this file since 65c6425 was 65c6425, checked in by Joel Sherrill <joel.sherrill@…>, on 05/03/12 at 17:24:46

Remove CVS Id Strings (manual edits after script)

These modifications were required by hand after running the script.
In some cases, the file names did not match patterns. In others,
the format of the file did not match any common patterns.

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