Annotation of kernel/bsd/netinet/tcp_output.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25: /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
                     26: /*
                     27:  * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
                     28:  *     The Regents of the University of California.  All rights reserved.
                     29:  *
                     30:  * Redistribution and use in source and binary forms, with or without
                     31:  * modification, are permitted provided that the following conditions
                     32:  * are met:
                     33:  * 1. Redistributions of source code must retain the above copyright
                     34:  *    notice, this list of conditions and the following disclaimer.
                     35:  * 2. Redistributions in binary form must reproduce the above copyright
                     36:  *    notice, this list of conditions and the following disclaimer in the
                     37:  *    documentation and/or other materials provided with the distribution.
                     38:  * 3. All advertising materials mentioning features or use of this software
                     39:  *    must display the following acknowledgement:
                     40:  *     This product includes software developed by the University of
                     41:  *     California, Berkeley and its contributors.
                     42:  * 4. Neither the name of the University nor the names of its contributors
                     43:  *    may be used to endorse or promote products derived from this software
                     44:  *    without specific prior written permission.
                     45:  *
                     46:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     47:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     48:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     49:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     50:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     51:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     52:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     53:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     54:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     55:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     56:  * SUCH DAMAGE.
                     57:  *
                     58:  *     @(#)tcp_output.c        8.3 (Berkeley) 12/30/93
                     59:  */
                     60: 
                     61: #include <sys/param.h>
                     62: #include <sys/systm.h>
                     63: #include <sys/malloc.h>
                     64: #include <sys/mbuf.h>
                     65: #include <sys/protosw.h>
                     66: #include <sys/socket.h>
                     67: #include <sys/socketvar.h>
                     68: #include <sys/errno.h>
                     69: 
                     70: #include <net/route.h>
                     71: 
                     72: #include <netinet/in.h>
                     73: #include <netinet/in_systm.h>
                     74: #include <netinet/ip.h>
                     75: #include <netinet/in_pcb.h>
                     76: #include <netinet/ip_var.h>
                     77: #include <netinet/tcp.h>
                     78: #define        TCPOUTFLAGS
                     79: #include <netinet/tcp_fsm.h>
                     80: #include <netinet/tcp_seq.h>
                     81: #include <netinet/tcp_timer.h>
                     82: #include <netinet/tcp_var.h>
                     83: #include <netinet/tcpip.h>
                     84: #include <netinet/tcp_debug.h>
                     85: 
                     86: #if NEXT
                     87: #import <kern/kdebug.h>
                     88: 
                     89: #if KDEBUG
                     90: 
                     91: #define DBG_LAYER_BEG          NETDBG_CODE(DBG_NETTCP, 1)
                     92: #define DBG_LAYER_END          NETDBG_CODE(DBG_NETTCP, 3)
                     93: #define DBG_FNC_TCP_OUTPUT     NETDBG_CODE(DBG_NETTCP, (4 << 8) | 1)
                     94: 
                     95: #endif
                     96: 
                     97: #endif
                     98: 
                     99: #ifdef notyet
                    100: extern struct mbuf *m_copypack();
                    101: #endif
                    102: 
                    103: 
                    104: #define MAX_TCPOPTLEN  32      /* max # bytes that go in options */
                    105: 
                    106: /*
                    107:  * Tcp output routine: figure out what should be sent and send it.
                    108:  */
                    109: int
                    110: tcp_output(tp)
                    111:        register struct tcpcb *tp;
                    112: {
                    113:        register struct socket *so = tp->t_inpcb->inp_socket;
                    114:        register long len, win;
                    115:        int off, flags, error;
                    116:        register struct mbuf *m;
                    117:        register struct tcpiphdr *ti;
                    118:        u_char opt[MAX_TCPOPTLEN];
                    119:        unsigned optlen, hdrlen;
                    120:        int idle, sendalot;
                    121: 
                    122: 
                    123: 
                    124:        KERNEL_DEBUG(DBG_FNC_TCP_OUTPUT | DBG_FUNC_START, 0,0,0,0,0);
                    125:        KERNEL_DEBUG(DBG_LAYER_BEG,
                    126:                     ((tp->t_template->ti_dport << 16) | tp->t_template->ti_sport),
                    127:                     (((tp->t_template->ti_src.s_addr & 0xffff) << 16) |
                    128:                      (tp->t_template->ti_dst.s_addr & 0xffff)),
                    129:                     0,0,0);
                    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 = tp->t_maxseg;
                    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:        len = min(so->so_snd.sb_cc, win) - off;
                    185: 
                    186:        if (len < 0) {
                    187:                /*
                    188:                 * If FIN has been sent but not acked,
                    189:                 * but we haven't been called to retransmit,
                    190:                 * len will be -1.  Otherwise, window shrank
                    191:                 * after we sent into it.  If window shrank to 0,
                    192:                 * cancel pending retransmit and pull snd_nxt
                    193:                 * back to (closed) window.  We will enter persist
                    194:                 * state below.  If the window didn't close completely,
                    195:                 * just wait for an ACK.
                    196:                 */
                    197:                len = 0;
                    198:                if (win == 0) {
                    199:                        tp->t_timer[TCPT_REXMT] = 0;
                    200:                        tp->snd_nxt = tp->snd_una;
                    201:                }
                    202:        }
                    203:        if (len > tp->t_maxseg) {
                    204:                len = tp->t_maxseg;
                    205:                sendalot = 1;
                    206:        }
                    207:        if (SEQ_LT(tp->snd_nxt + len, tp->snd_una + so->so_snd.sb_cc))
                    208:                flags &= ~TH_FIN;
                    209: 
                    210:        win = sbspace(&so->so_rcv);
                    211: 
                    212:        /*
                    213:         * Sender silly window avoidance.  If connection is idle
                    214:         * and can send all data, a maximum segment,
                    215:         * at least a maximum default-size segment do it,
                    216:         * or are forced, do it; otherwise don't bother.
                    217:         * If peer's buffer is tiny, then send
                    218:         * when window is at least half open.
                    219:         * If retransmitting (possibly after persist timer forced us
                    220:         * to send into a small window), then must resend.
                    221:         */
                    222:        if (len) {
                    223:                if (len == tp->t_maxseg)
                    224:                        goto send;
                    225:                if (!(so->so_state & SS_MORETOCOME)) {
                    226:                        if ((idle || tp->t_flags & TF_NODELAY) &&
                    227:                            len + off >= so->so_snd.sb_cc)
                    228:                                goto send;
                    229:                }
                    230:                if (tp->t_force)
                    231:                        goto send;
                    232:                if (len >= tp->max_sndwnd / 2)
                    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 - MAX_TCPOPTLEN)))
                    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_SYN|TH_RST))
                    266:                goto send;
                    267:        if (SEQ_GT(tp->snd_up, tp->snd_una))
                    268:                goto send;
                    269:        /*
                    270:         * If our state indicates that FIN should be sent
                    271:         * and we have not yet done so, or we're retransmitting the FIN,
                    272:         * then we need to send.
                    273:         */
                    274:        if (flags & TH_FIN &&
                    275:            ((tp->t_flags & TF_SENTFIN) == 0 || tp->snd_nxt == tp->snd_una))
                    276:                goto send;
                    277: 
                    278:        /*
                    279:         * TCP window updates are not reliable, rather a polling protocol
                    280:         * using ``persist'' packets is used to insure receipt of window
                    281:         * updates.  The three ``states'' for the output side are:
                    282:         *      idle                    not doing retransmits or persists
                    283:         *      persisting              to move a small or zero window
                    284:         *      (re)transmitting        and thereby not persisting
                    285:         *
                    286:         * tp->t_timer[TCPT_PERSIST]
                    287:         *      is set when we are in persist state.
                    288:         * tp->t_force
                    289:         *      is set when we are called to send a persist packet.
                    290:         * tp->t_timer[TCPT_REXMT]
                    291:         *      is set when we are retransmitting
                    292:         * The output side is idle when both timers are zero.
                    293:         *
                    294:         * If send window is too small, there is data to transmit, and no
                    295:         * retransmit or persist is pending, then go to persist state.
                    296:         * If nothing happens soon, send when timer expires:
                    297:         * if window is nonzero, transmit what we can,
                    298:         * otherwise force out a byte.
                    299:         */
                    300:        if (so->so_snd.sb_cc && tp->t_timer[TCPT_REXMT] == 0 &&
                    301:            tp->t_timer[TCPT_PERSIST] == 0) {
                    302:                tp->t_rxtshift = 0;
                    303:                tcp_setpersist(tp);
                    304:        }
                    305: 
                    306:        /*
                    307:         * No reason to send a segment, just return.
                    308:         */
                    309:        KERNEL_DEBUG(DBG_FNC_TCP_OUTPUT | DBG_FUNC_END, 0,0,0,0,0);
                    310:        return (0);
                    311: 
                    312: send:
                    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] = 4;
                    330:                        mss = htons((u_short) tcp_mss(tp, 0));
                    331:                        bcopy((caddr_t)&mss, (caddr_t)(opt + 2), sizeof(mss));
                    332:                        optlen = 4;
                    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_SYN|TH_ACK)) == TH_SYN ||
                    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:        hdrlen += optlen;
                    366:  
                    367:        /*
                    368:         * Adjust data length if insertion of options will
                    369:         * bump the packet length beyond the t_maxseg length.
                    370:         */
                    371:        if (len > tp->t_maxseg - optlen) {
                    372:                len = tp->t_maxseg - optlen;
                    373:                sendalot = 1;
                    374:                flags &= ~TH_FIN;
                    375:         }
                    376: 
                    377: #if DIAGNOSTIC
                    378:        if (max_linkhdr + hdrlen > MHLEN)
                    379:                panic("tcphdr too big");
                    380: #endif
                    381: 
                    382:        /*
                    383:         * Grab a header mbuf, attaching a copy of data to
                    384:         * be transmitted, and initialize the header from
                    385:         * the template for sends on this connection.
                    386:         */
                    387:        if (len) {
                    388:                if (tp->t_force && len == 1)
                    389:                        tcpstat.tcps_sndprobe++;
                    390:                else if (SEQ_LT(tp->snd_nxt, tp->snd_max)) {
                    391:                        tcpstat.tcps_sndrexmitpack++;
                    392:                        tcpstat.tcps_sndrexmitbyte += len;
                    393:                } else {
                    394:                        tcpstat.tcps_sndpack++;
                    395:                        tcpstat.tcps_sndbyte += len;
                    396:                }
                    397: #ifdef notyet
                    398:                if ((m = m_copypack(so->so_snd.sb_mb, off,
                    399:                    (int)len, max_linkhdr + hdrlen)) == 0) {
                    400:                        error = ENOBUFS;
                    401:                        goto out;
                    402:                }
                    403:                /*
                    404:                 * m_copypack left space for our hdr; use it.
                    405:                 */
                    406:                m->m_len += hdrlen;
                    407:                m->m_data -= hdrlen;
                    408: #else
                    409:                MGETHDR(m, M_DONTWAIT, MT_HEADER);
                    410:                if (m == NULL) {
                    411:                        error = ENOBUFS;
                    412:                        goto out;
                    413:                }
                    414:                m->m_data += max_linkhdr;
                    415:                m->m_len = hdrlen;
                    416:                if (len <= (MHLEN - hdrlen - max_linkhdr)) {
                    417:                        register struct mbuf *m1, *m2;
                    418:                        register char        *p;
                    419:                        register int         cur_len, len1;
                    420:                        register int         off1;
                    421: 
                    422:                        p = mtod(m, caddr_t) + hdrlen;
                    423:                        m1 = so->so_snd.sb_mb;
                    424:                        off1 = off;
                    425:                        len1 = len;
                    426: 
                    427:                        for (;;) {                      
                    428:                                for (cur_len = 0, m2 = m1; m2; m2 = m2->m_next)
                    429:                                        cur_len += m2->m_len;
                    430:                                if (off1 < cur_len) {
                    431:                                        cur_len = min(cur_len - off1, len1);
                    432: 
                    433:                                        m_copydata(m1, off1, (int) cur_len, p);
                    434: 
                    435:                                        if ((len1 -= cur_len) == 0)
                    436:                                                break;
                    437:                                        p += cur_len;
                    438:                                        off1 = 0;
                    439:                                } else
                    440:                                        off1 -= cur_len;
                    441: 
                    442:                                kprintf("m_copydata: nextpkt path\n");
                    443: 
                    444:                                if ((m1 = m1->m_nextpkt) == NULL)
                    445:                                        panic("tcp_output: m_copydata");
                    446:                        }
                    447:                        m->m_len += len;
                    448:                        
                    449:                } else {
                    450:                        register struct mbuf *m1, *m2, *m3;
                    451:                        register int         cur_len, len1;
                    452:                        register int         off1;
                    453: 
                    454:                        m1 = so->so_snd.sb_mb;
                    455:                        m3 = m;
                    456:                        off1 = off;
                    457:                        len1 = len;
                    458: 
                    459:                        for (;;) {                      
                    460:                                for (cur_len = 0, m2 = m1; m2; m2 = m2->m_next)
                    461:                                        cur_len += m2->m_len;
                    462:                                if (off1 < cur_len) {
                    463:                                        cur_len = min(cur_len - off1, len1);
                    464: 
                    465:                                        m3->m_next = m_copy(m1, off1, (int) cur_len);
                    466:                                        if (m3->m_next == 0) {
                    467:                                                (void) m_free(m);
                    468:                                                error = ENOBUFS;
                    469:                                                goto out;
                    470:                                        }
                    471:                                        if ((len1 -= cur_len) == 0)
                    472:                                                break;
                    473:                                        for (m3 = m3->m_next; m3->m_next; m3 = m3->m_next);
                    474: 
                    475:                                        off1 = 0;
                    476:                                } else
                    477:                                        off1 -= cur_len;
                    478: 
                    479:                                kprintf("m_copy: nextpkt path\n");
                    480: 
                    481:                                if ((m1 = m1->m_nextpkt) == NULL)
                    482:                                        panic("tcp_output: m_copy");
                    483:                        }
                    484:                }
                    485: #endif
                    486:                /*
                    487:                 * If we're sending everything we've got, set PUSH.
                    488:                 * (This will keep happy those implementations which only
                    489:                 * give data to the user when a buffer fills or
                    490:                 * a PUSH comes in.)
                    491:                 */
                    492:                if (off + len == so->so_snd.sb_cc)
                    493:                        flags |= TH_PUSH;
                    494:        } else {
                    495:                if (tp->t_flags & TF_ACKNOW)
                    496:                        tcpstat.tcps_sndacks++;
                    497:                else if (flags & (TH_SYN|TH_FIN|TH_RST))
                    498:                        tcpstat.tcps_sndctrl++;
                    499:                else if (SEQ_GT(tp->snd_up, tp->snd_una))
                    500:                        tcpstat.tcps_sndurg++;
                    501:                else
                    502:                        tcpstat.tcps_sndwinup++;
                    503: 
                    504:                MGETHDR(m, M_DONTWAIT, MT_HEADER);
                    505:                if (m == NULL) {
                    506:                        error = ENOBUFS;
                    507:                        goto out;
                    508:                }
                    509:                m->m_data += max_linkhdr;
                    510:                m->m_len = hdrlen;
                    511:        }
                    512:        m->m_pkthdr.rcvif = (struct ifnet *)0;
                    513:        ti = mtod(m, struct tcpiphdr *);
                    514:        if (tp->t_template == 0)
                    515:                panic("tcp_output");
                    516:        bcopy((caddr_t)tp->t_template, (caddr_t)ti, sizeof (struct tcpiphdr));
                    517: 
                    518:        /*
                    519:         * Fill in fields, remembering maximum advertised
                    520:         * window for use in delaying messages about window sizes.
                    521:         * If resending a FIN, be sure not to use a new sequence number.
                    522:         */
                    523:        if (flags & TH_FIN && tp->t_flags & TF_SENTFIN && 
                    524:            tp->snd_nxt == tp->snd_max)
                    525:                tp->snd_nxt--;
                    526:        /*
                    527:         * If we are doing retransmissions, then snd_nxt will
                    528:         * not reflect the first unsent octet.  For ACK only
                    529:         * packets, we do not want the sequence number of the
                    530:         * retransmitted packet, we want the sequence number
                    531:         * of the next unsent octet.  So, if there is no data
                    532:         * (and no SYN or FIN), use snd_max instead of snd_nxt
                    533:         * when filling in ti_seq.  But if we are in persist
                    534:         * state, snd_max might reflect one byte beyond the
                    535:         * right edge of the window, so use snd_nxt in that
                    536:         * case, since we know we aren't doing a retransmission.
                    537:         * (retransmit and persist are mutually exclusive...)
                    538:         */
                    539:        if (len || (flags & (TH_SYN|TH_FIN)) || tp->t_timer[TCPT_PERSIST])
                    540:                ti->ti_seq = htonl(tp->snd_nxt);
                    541:        else
                    542:                ti->ti_seq = htonl(tp->snd_max);
                    543:        ti->ti_ack = htonl(tp->rcv_nxt);
                    544:        if (optlen) {
                    545:                bcopy((caddr_t)opt, (caddr_t)(ti + 1), optlen);
                    546:                ti->ti_off = (sizeof (struct tcphdr) + optlen) >> 2;
                    547:        }
                    548:        ti->ti_flags = flags;
                    549:        /*
                    550:         * Calculate receive window.  Don't shrink window,
                    551:         * but avoid silly window syndrome.
                    552:         */
                    553:        if (win < (long)(so->so_rcv.sb_hiwat / 4) && win < (long)tp->t_maxseg)
                    554:                win = 0;
                    555:        if (win > (long)TCP_MAXWIN << tp->rcv_scale)
                    556:                win = (long)TCP_MAXWIN << tp->rcv_scale;
                    557:        if (win < (long)(tp->rcv_adv - tp->rcv_nxt))
                    558:                win = (long)(tp->rcv_adv - tp->rcv_nxt);
                    559:        ti->ti_win = htons((u_short) (win>>tp->rcv_scale));
                    560:        if (SEQ_GT(tp->snd_up, tp->snd_nxt)) {
                    561:                ti->ti_urp = htons((u_short)(tp->snd_up - tp->snd_nxt));
                    562:                ti->ti_flags |= TH_URG;
                    563:        } else
                    564:                /*
                    565:                 * If no urgent pointer to send, then we pull
                    566:                 * the urgent pointer to the left edge of the send window
                    567:                 * so that it doesn't drift into the send window on sequence
                    568:                 * number wraparound.
                    569:                 */
                    570:                tp->snd_up = tp->snd_una;               /* drag it along */
                    571: 
                    572:        /*
                    573:         * Put TCP length in extended header, and then
                    574:         * checksum extended header and data.
                    575:         */
                    576:        if (len + optlen)
                    577:                ti->ti_len = htons((u_short)(sizeof (struct tcphdr) +
                    578:                    optlen + len));
                    579:        ti->ti_sum = in_cksum(m, (int)(hdrlen + len));
                    580: 
                    581:        /*
                    582:         * In transmit state, time the transmission and arrange for
                    583:         * the retransmit.  In persist state, just set snd_max.
                    584:         */
                    585:        if (tp->t_force == 0 || tp->t_timer[TCPT_PERSIST] == 0) {
                    586:                tcp_seq startseq = tp->snd_nxt;
                    587: 
                    588:                /*
                    589:                 * Advance snd_nxt over sequence space of this segment.
                    590:                 */
                    591:                if (flags & (TH_SYN|TH_FIN)) {
                    592:                        if (flags & TH_SYN)
                    593:                                tp->snd_nxt++;
                    594:                        if (flags & TH_FIN) {
                    595:                                tp->snd_nxt++;
                    596:                                tp->t_flags |= TF_SENTFIN;
                    597:                        }
                    598:                }
                    599:                tp->snd_nxt += len;
                    600:                if (SEQ_GT(tp->snd_nxt, tp->snd_max)) {
                    601:                        tp->snd_max = tp->snd_nxt;
                    602:                        /*
                    603:                         * Time this transmission if not a retransmission and
                    604:                         * not currently timing anything.
                    605:                         */
                    606:                        if (tp->t_rtt == 0) {
                    607:                                tp->t_rtt = 1;
                    608:                                tp->t_rtseq = startseq;
                    609:                                tcpstat.tcps_segstimed++;
                    610:                        }
                    611:                }
                    612: 
                    613:                /*
                    614:                 * Set retransmit timer if not currently set,
                    615:                 * and not doing an ack or a keep-alive probe.
                    616:                 * Initial value for retransmit timer is smoothed
                    617:                 * round-trip time + 2 * round-trip time variance.
                    618:                 * Initialize shift counter which is used for backoff
                    619:                 * of retransmit time.
                    620:                 */
                    621:                if (tp->t_timer[TCPT_REXMT] == 0 &&
                    622:                    tp->snd_nxt != tp->snd_una) {
                    623:                        tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
                    624:                        if (tp->t_timer[TCPT_PERSIST]) {
                    625:                                tp->t_timer[TCPT_PERSIST] = 0;
                    626:                                tp->t_rxtshift = 0;
                    627:                        }
                    628:                }
                    629:        } else
                    630:                if (SEQ_GT(tp->snd_nxt + len, tp->snd_max))
                    631:                        tp->snd_max = tp->snd_nxt + len;
                    632: 
                    633:        /*
                    634:         * Trace.
                    635:         */
                    636:        if (so->so_options & SO_DEBUG)
                    637:                tcp_trace(TA_OUTPUT, tp->t_state, tp, ti, 0);
                    638: 
                    639:        /*
                    640:         * Fill in IP length and desired time to live and
                    641:         * send to IP level.  There should be a better way
                    642:         * to handle ttl and tos; we could keep them in
                    643:         * the template, but need a way to checksum without them.
                    644:         */
                    645:        m->m_pkthdr.len = hdrlen + len;
                    646: #if TUBA
                    647:        if (tp->t_tuba_pcb)
                    648:                error = tuba_output(m, tp);
                    649:        else
                    650: #endif
                    651:     {
                    652:        ((struct ip *)ti)->ip_len = m->m_pkthdr.len;
                    653:        ((struct ip *)ti)->ip_ttl = tp->t_inpcb->inp_ip.ip_ttl; /* XXX */
                    654:        ((struct ip *)ti)->ip_tos = tp->t_inpcb->inp_ip.ip_tos; /* XXX */
                    655: 
                    656:        KERNEL_DEBUG(DBG_LAYER_END, ((ti->ti_dport << 16) | ti->ti_sport),
                    657:                     (((ti->ti_src.s_addr & 0xffff) << 16) | (ti->ti_dst.s_addr & 0xffff)),
                    658:                     ti->ti_seq, ti->ti_ack, ti->ti_win);
                    659: 
                    660: #if BSD >= 43
                    661:        error = ip_output(m, tp->t_inpcb->inp_options, &tp->t_inpcb->inp_route,
                    662:            so->so_options & SO_DONTROUTE, 0);
                    663: #else
                    664:        error = ip_output(m, (struct mbuf *)0, &tp->t_inpcb->inp_route, 
                    665:            so->so_options & SO_DONTROUTE);
                    666: #endif
                    667:     }
                    668:        if (error) {
                    669: out:
                    670:                if (error == ENOBUFS) {
                    671:                        tcp_quench(tp->t_inpcb, 0);
                    672:                        KERNEL_DEBUG(DBG_FNC_TCP_OUTPUT | DBG_FUNC_END, 0,0,0,0,0);
                    673:                        return (0);
                    674:                }
                    675:                if ((error == EHOSTUNREACH || error == ENETDOWN)
                    676:                    && TCPS_HAVERCVDSYN(tp->t_state)) {
                    677:                        tp->t_softerror = error;
                    678:                        KERNEL_DEBUG(DBG_FNC_TCP_OUTPUT | DBG_FUNC_END, 0,0,0,0,0);
                    679:                        return (0);
                    680:                }
                    681:                KERNEL_DEBUG(DBG_FNC_TCP_OUTPUT | DBG_FUNC_END, error,0,0,0,0);
                    682:                return (error);
                    683:        }
                    684:        tcpstat.tcps_sndtotal++;
                    685: 
                    686:        /*
                    687:         * Data sent (as far as we can tell).
                    688:         * If this advertises a larger window than any other segment,
                    689:         * then remember the size of the advertised window.
                    690:         * Any pending ACK has now been sent.
                    691:         */
                    692:        if (win > 0 && SEQ_GT(tp->rcv_nxt+win, tp->rcv_adv))
                    693:                tp->rcv_adv = tp->rcv_nxt + win;
                    694:        tp->last_ack_sent = tp->rcv_nxt;
                    695:        tp->t_flags &= ~(TF_ACKNOW|TF_DELACK);
                    696:        if (sendalot)
                    697:                goto again;
                    698: 
                    699:        KERNEL_DEBUG(DBG_FNC_TCP_OUTPUT | DBG_FUNC_END, 0,0,0,0,0);
                    700:        return (0);
                    701: }
                    702: 
                    703: void
                    704: tcp_setpersist(tp)
                    705:        register struct tcpcb *tp;
                    706: {
                    707:        register t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1;
                    708: 
                    709:        if (tp->t_timer[TCPT_REXMT])
                    710:                panic("tcp_output REXMT");
                    711:        /*
                    712:         * Start/restart persistance timer.
                    713:         */
                    714:        TCPT_RANGESET(tp->t_timer[TCPT_PERSIST],
                    715:            t * tcp_backoff[tp->t_rxtshift],
                    716:            TCPTV_PERSMIN, TCPTV_PERSMAX);
                    717:        if (tp->t_rxtshift < TCP_MAXRXTSHIFT)
                    718:                tp->t_rxtshift++;
                    719: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.