|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.