ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/slirp/tcp_output.c
Revision: 1.2
Committed: 2012-03-30T01:10:28Z (12 years, 7 months ago) by asvitkine
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +1 -5 lines
Log Message:
Switch slirp to 3-clause BSD license. This change went in upstream to QEMU's
version of slirp (where this code comes from), with the following checkin:

commit 2f5f89963186d42a7ded253bc6cf5b32abb45cec
Author: aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>
Date:   Mon Jan 26 19:37:41 2009 +0000

    Remove the advertising clause from the slirp license

    According to the FSF, the 4-clause BSD license, which slirp is covered under,
    is not compatible with the GPL or LGPL[1].

    [1] http://www.fsf.org/licensing/licenses/index_html#GPLIncompatibleLicenses

    There are three declared copyright holders in slirp that use the 4-clause
    BSD license, the Regents of UC Berkley, Danny Gasparovski, and Kelly Price.
    Below are the appropriate permissions to remove the advertise clause from slirp
    from each party.

    Special thanks go to Richard Fontana from Red Hat for contacting all of the
    necessary authors to resolve this issue!

    Regents of UC Berkley:
    From ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change

    July 22, 1999

    To All Licensees, Distributors of Any Version of BSD:

    As you know, certain of the Berkeley Software Distribution ("BSD") source
    code files require that further distributions of products containing all or
    portions of the software, acknowledge within their advertising materials
    that such products contain software developed by UC Berkeley and its
    contributors.

    Specifically, the provision reads:

    "     * 3. All advertising materials mentioning features or use of this software
          *    must display the following acknowledgement:
          *    This product includes software developed by the University of
          *    California, Berkeley and its contributors."

    Effective immediately, licensees and distributors are no longer required to
    include the acknowledgement within advertising materials.  Accordingly, the
    foregoing paragraph of those BSD Unix files containing it is hereby deleted
    in its entirety.

    William Hoskins
    Director, Office of Technology Licensing
    University of California, Berkeley

    Danny Gasparovski:

    Subject: RE: Slirp license
    Date: Thu, 8 Jan 2009 10:51:00 +1100
    From: "Gasparovski, Daniel" <Daniel.Gasparovski@ato.gov.au>
    To: "Richard Fontana" <rfontana@redhat.com>

    Hi Richard,

    I have no objection to having Slirp code in QEMU be licensed under the
    3-clause BSD license.

    Thanks for taking the effort to consult me about this.


    Dan ...

    Kelly Price:

    Date: Thu, 8 Jan 2009 19:38:56 -0500
    From: "Kelly Price" <strredwolf@gmail.com>
    To: "Richard Fontana" <rfontana@redhat.com>
    Subject: Re: Slirp license

    Thanks for contacting me, Richard.  I'm glad you were able to find
    Dan, as I've been "keeping the light on" for Slirp.  I have no use for
    it now, and I have little time for it (now holding onto Keenspot's
    Comic Genesis and having a regular US state government position). If
    Dan would like to return to the project, I'd love to give it back to
    him.

    As for copyright, I don't own all of it.  Dan does, so I will defer to
    him.  Any of my patches I will gladly license to the 3-part BSD
    license.  My interest in re-licensing was because we didn't have ready
    info to contact Dan.  If Dan would like to port Slirp back out of
    QEMU, a lot of us 64-bit users would be grateful.

    Feel free to share this email address with Dan.  I will be glad to
    effect a transfer of the project to him and Mr. Bellard of the QEMU
    project.

    Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


    git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6451 c046a42c-6fe2-441c-8c8c-71466251a162

File Contents

# Content
1 /*
2 * Copyright (c) 1982, 1986, 1988, 1990, 1993
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 * 3. 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.3 (Berkeley) 12/30/93
30 * tcp_output.c,v 1.3 1994/09/15 10:36:55 davidg Exp
31 */
32
33 /*
34 * Changes and additions relating to SLiRP
35 * Copyright (c) 1995 Danny Gasparovski.
36 *
37 * Please read the file COPYRIGHT for the
38 * terms and conditions of the copyright.
39 */
40
41 #include <slirp.h>
42
43 /*
44 * Since this is only used in "stats socket", we give meaning
45 * names instead of the REAL names
46 */
47 char *tcpstates[] = {
48 /* "CLOSED", "LISTEN", "SYN_SENT", "SYN_RCVD", */
49 "REDIRECT", "LISTEN", "SYN_SENT", "SYN_RCVD",
50 "ESTABLISHED", "CLOSE_WAIT", "FIN_WAIT_1", "CLOSING",
51 "LAST_ACK", "FIN_WAIT_2", "TIME_WAIT",
52 };
53
54 u_char tcp_outflags[TCP_NSTATES] = {
55 TH_RST|TH_ACK, 0, TH_SYN, TH_SYN|TH_ACK,
56 TH_ACK, TH_ACK, TH_FIN|TH_ACK, TH_FIN|TH_ACK,
57 TH_FIN|TH_ACK, TH_ACK, TH_ACK,
58 };
59
60
61 #define MAX_TCPOPTLEN 32 /* max # bytes that go in options */
62
63 /*
64 * Tcp output routine: figure out what should be sent and send it.
65 */
66 int
67 tcp_output(tp)
68 register struct tcpcb *tp;
69 {
70 register struct socket *so = tp->t_socket;
71 register long len, win;
72 int off, flags, error;
73 register struct mbuf *m;
74 register struct tcpiphdr *ti;
75 u_char opt[MAX_TCPOPTLEN];
76 unsigned optlen, hdrlen;
77 int idle, sendalot;
78
79 DEBUG_CALL("tcp_output");
80 DEBUG_ARG("tp = %lx", (long )tp);
81
82 /*
83 * Determine length of data that should be transmitted,
84 * and flags that will be used.
85 * If there is some data or critical controls (SYN, RST)
86 * to send, then transmit; otherwise, investigate further.
87 */
88 idle = (tp->snd_max == tp->snd_una);
89 if (idle && tp->t_idle >= tp->t_rxtcur)
90 /*
91 * We have been idle for "a while" and no acks are
92 * expected to clock out any data we send --
93 * slow start to get ack "clock" running again.
94 */
95 tp->snd_cwnd = tp->t_maxseg;
96 again:
97 sendalot = 0;
98 off = tp->snd_nxt - tp->snd_una;
99 win = min(tp->snd_wnd, tp->snd_cwnd);
100
101 flags = tcp_outflags[tp->t_state];
102
103 DEBUG_MISC((dfd, " --- tcp_output flags = 0x%x\n",flags));
104
105 /*
106 * If in persist timeout with window of 0, send 1 byte.
107 * Otherwise, if window is small but nonzero
108 * and timer expired, we will send what we can
109 * and go to transmit state.
110 */
111 if (tp->t_force) {
112 if (win == 0) {
113 /*
114 * If we still have some data to send, then
115 * clear the FIN bit. Usually this would
116 * happen below when it realizes that we
117 * aren't sending all the data. However,
118 * if we have exactly 1 byte of unset data,
119 * then it won't clear the FIN bit below,
120 * and if we are in persist state, we wind
121 * up sending the packet without recording
122 * that we sent the FIN bit.
123 *
124 * We can't just blindly clear the FIN bit,
125 * because if we don't have any more data
126 * to send then the probe will be the FIN
127 * itself.
128 */
129 if (off < so->so_snd.sb_cc)
130 flags &= ~TH_FIN;
131 win = 1;
132 } else {
133 tp->t_timer[TCPT_PERSIST] = 0;
134 tp->t_rxtshift = 0;
135 }
136 }
137
138 len = min(so->so_snd.sb_cc, win) - off;
139
140 if (len < 0) {
141 /*
142 * If FIN has been sent but not acked,
143 * but we haven't been called to retransmit,
144 * len will be -1. Otherwise, window shrank
145 * after we sent into it. If window shrank to 0,
146 * cancel pending retransmit and pull snd_nxt
147 * back to (closed) window. We will enter persist
148 * state below. If the window didn't close completely,
149 * just wait for an ACK.
150 */
151 len = 0;
152 if (win == 0) {
153 tp->t_timer[TCPT_REXMT] = 0;
154 tp->snd_nxt = tp->snd_una;
155 }
156 }
157
158 if (len > tp->t_maxseg) {
159 len = tp->t_maxseg;
160 sendalot = 1;
161 }
162 if (SEQ_LT(tp->snd_nxt + len, tp->snd_una + so->so_snd.sb_cc))
163 flags &= ~TH_FIN;
164
165 win = sbspace(&so->so_rcv);
166
167 /*
168 * Sender silly window avoidance. If connection is idle
169 * and can send all data, a maximum segment,
170 * at least a maximum default-size segment do it,
171 * or are forced, do it; otherwise don't bother.
172 * If peer's buffer is tiny, then send
173 * when window is at least half open.
174 * If retransmitting (possibly after persist timer forced us
175 * to send into a small window), then must resend.
176 */
177 if (len) {
178 if (len == tp->t_maxseg)
179 goto send;
180 if ((1 || idle || tp->t_flags & TF_NODELAY) &&
181 len + off >= so->so_snd.sb_cc)
182 goto send;
183 if (tp->t_force)
184 goto send;
185 if (len >= tp->max_sndwnd / 2 && tp->max_sndwnd > 0)
186 goto send;
187 if (SEQ_LT(tp->snd_nxt, tp->snd_max))
188 goto send;
189 }
190
191 /*
192 * Compare available window to amount of window
193 * known to peer (as advertised window less
194 * next expected input). If the difference is at least two
195 * max size segments, or at least 50% of the maximum possible
196 * window, then want to send a window update to peer.
197 */
198 if (win > 0) {
199 /*
200 * "adv" is the amount we can increase the window,
201 * taking into account that we are limited by
202 * TCP_MAXWIN << tp->rcv_scale.
203 */
204 long adv = min(win, (long)TCP_MAXWIN << tp->rcv_scale) -
205 (tp->rcv_adv - tp->rcv_nxt);
206
207 if (adv >= (long) (2 * tp->t_maxseg))
208 goto send;
209 if (2 * adv >= (long) so->so_rcv.sb_datalen)
210 goto send;
211 }
212
213 /*
214 * Send if we owe peer an ACK.
215 */
216 if (tp->t_flags & TF_ACKNOW)
217 goto send;
218 if (flags & (TH_SYN|TH_RST))
219 goto send;
220 if (SEQ_GT(tp->snd_up, tp->snd_una))
221 goto send;
222 /*
223 * If our state indicates that FIN should be sent
224 * and we have not yet done so, or we're retransmitting the FIN,
225 * then we need to send.
226 */
227 if (flags & TH_FIN &&
228 ((tp->t_flags & TF_SENTFIN) == 0 || tp->snd_nxt == tp->snd_una))
229 goto send;
230
231 /*
232 * TCP window updates are not reliable, rather a polling protocol
233 * using ``persist'' packets is used to insure receipt of window
234 * updates. The three ``states'' for the output side are:
235 * idle not doing retransmits or persists
236 * persisting to move a small or zero window
237 * (re)transmitting and thereby not persisting
238 *
239 * tp->t_timer[TCPT_PERSIST]
240 * is set when we are in persist state.
241 * tp->t_force
242 * is set when we are called to send a persist packet.
243 * tp->t_timer[TCPT_REXMT]
244 * is set when we are retransmitting
245 * The output side is idle when both timers are zero.
246 *
247 * If send window is too small, there is data to transmit, and no
248 * retransmit or persist is pending, then go to persist state.
249 * If nothing happens soon, send when timer expires:
250 * if window is nonzero, transmit what we can,
251 * otherwise force out a byte.
252 */
253 if (so->so_snd.sb_cc && tp->t_timer[TCPT_REXMT] == 0 &&
254 tp->t_timer[TCPT_PERSIST] == 0) {
255 tp->t_rxtshift = 0;
256 tcp_setpersist(tp);
257 }
258
259 /*
260 * No reason to send a segment, just return.
261 */
262 tcpstat.tcps_didnuttin++;
263
264 return (0);
265
266 send:
267 /*
268 * Before ESTABLISHED, force sending of initial options
269 * unless TCP set not to do any options.
270 * NOTE: we assume that the IP/TCP header plus TCP options
271 * always fit in a single mbuf, leaving room for a maximum
272 * link header, i.e.
273 * max_linkhdr + sizeof (struct tcpiphdr) + optlen <= MHLEN
274 */
275 optlen = 0;
276 hdrlen = sizeof (struct tcpiphdr);
277 if (flags & TH_SYN) {
278 tp->snd_nxt = tp->iss;
279 if ((tp->t_flags & TF_NOOPT) == 0) {
280 u_int16_t mss;
281
282 opt[0] = TCPOPT_MAXSEG;
283 opt[1] = 4;
284 mss = htons((u_int16_t) tcp_mss(tp, 0));
285 memcpy((caddr_t)(opt + 2), (caddr_t)&mss, sizeof(mss));
286 optlen = 4;
287
288 /* if ((tp->t_flags & TF_REQ_SCALE) &&
289 * ((flags & TH_ACK) == 0 ||
290 * (tp->t_flags & TF_RCVD_SCALE))) {
291 * *((u_int32_t *) (opt + optlen)) = htonl(
292 * TCPOPT_NOP << 24 |
293 * TCPOPT_WINDOW << 16 |
294 * TCPOLEN_WINDOW << 8 |
295 * tp->request_r_scale);
296 * optlen += 4;
297 * }
298 */
299 }
300 }
301
302 /*
303 * Send a timestamp and echo-reply if this is a SYN and our side
304 * wants to use timestamps (TF_REQ_TSTMP is set) or both our side
305 * and our peer have sent timestamps in our SYN's.
306 */
307 /* if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP &&
308 * (flags & TH_RST) == 0 &&
309 * ((flags & (TH_SYN|TH_ACK)) == TH_SYN ||
310 * (tp->t_flags & TF_RCVD_TSTMP))) {
311 * u_int32_t *lp = (u_int32_t *)(opt + optlen);
312 *
313 * / * Form timestamp option as shown in appendix A of RFC 1323. * /
314 * *lp++ = htonl(TCPOPT_TSTAMP_HDR);
315 * *lp++ = htonl(tcp_now);
316 * *lp = htonl(tp->ts_recent);
317 * optlen += TCPOLEN_TSTAMP_APPA;
318 * }
319 */
320 hdrlen += optlen;
321
322 /*
323 * Adjust data length if insertion of options will
324 * bump the packet length beyond the t_maxseg length.
325 */
326 if (len > tp->t_maxseg - optlen) {
327 len = tp->t_maxseg - optlen;
328 sendalot = 1;
329 }
330
331 /*
332 * Grab a header mbuf, attaching a copy of data to
333 * be transmitted, and initialize the header from
334 * the template for sends on this connection.
335 */
336 if (len) {
337 if (tp->t_force && len == 1)
338 tcpstat.tcps_sndprobe++;
339 else if (SEQ_LT(tp->snd_nxt, tp->snd_max)) {
340 tcpstat.tcps_sndrexmitpack++;
341 tcpstat.tcps_sndrexmitbyte += len;
342 } else {
343 tcpstat.tcps_sndpack++;
344 tcpstat.tcps_sndbyte += len;
345 }
346
347 m = m_get();
348 if (m == NULL) {
349 /* error = ENOBUFS; */
350 error = 1;
351 goto out;
352 }
353 m->m_data += if_maxlinkhdr;
354 m->m_len = hdrlen;
355
356 /*
357 * This will always succeed, since we make sure our mbufs
358 * are big enough to hold one MSS packet + header + ... etc.
359 */
360 /* if (len <= MHLEN - hdrlen - max_linkhdr) { */
361
362 sbcopy(&so->so_snd, off, (int) len, mtod(m, caddr_t) + hdrlen);
363 m->m_len += len;
364
365 /* } else {
366 * m->m_next = m_copy(so->so_snd.sb_mb, off, (int) len);
367 * if (m->m_next == 0)
368 * len = 0;
369 * }
370 */
371 /*
372 * If we're sending everything we've got, set PUSH.
373 * (This will keep happy those implementations which only
374 * give data to the user when a buffer fills or
375 * a PUSH comes in.)
376 */
377 if (off + len == so->so_snd.sb_cc)
378 flags |= TH_PUSH;
379 } else {
380 if (tp->t_flags & TF_ACKNOW)
381 tcpstat.tcps_sndacks++;
382 else if (flags & (TH_SYN|TH_FIN|TH_RST))
383 tcpstat.tcps_sndctrl++;
384 else if (SEQ_GT(tp->snd_up, tp->snd_una))
385 tcpstat.tcps_sndurg++;
386 else
387 tcpstat.tcps_sndwinup++;
388
389 m = m_get();
390 if (m == NULL) {
391 /* error = ENOBUFS; */
392 error = 1;
393 goto out;
394 }
395 m->m_data += if_maxlinkhdr;
396 m->m_len = hdrlen;
397 }
398
399 ti = mtod(m, struct tcpiphdr *);
400
401 memcpy((caddr_t)ti, &tp->t_template, sizeof (struct tcpiphdr));
402
403 /*
404 * Fill in fields, remembering maximum advertised
405 * window for use in delaying messages about window sizes.
406 * If resending a FIN, be sure not to use a new sequence number.
407 */
408 if (flags & TH_FIN && tp->t_flags & TF_SENTFIN &&
409 tp->snd_nxt == tp->snd_max)
410 tp->snd_nxt--;
411 /*
412 * If we are doing retransmissions, then snd_nxt will
413 * not reflect the first unsent octet. For ACK only
414 * packets, we do not want the sequence number of the
415 * retransmitted packet, we want the sequence number
416 * of the next unsent octet. So, if there is no data
417 * (and no SYN or FIN), use snd_max instead of snd_nxt
418 * when filling in ti_seq. But if we are in persist
419 * state, snd_max might reflect one byte beyond the
420 * right edge of the window, so use snd_nxt in that
421 * case, since we know we aren't doing a retransmission.
422 * (retransmit and persist are mutually exclusive...)
423 */
424 if (len || (flags & (TH_SYN|TH_FIN)) || tp->t_timer[TCPT_PERSIST])
425 ti->ti_seq = htonl(tp->snd_nxt);
426 else
427 ti->ti_seq = htonl(tp->snd_max);
428 ti->ti_ack = htonl(tp->rcv_nxt);
429 if (optlen) {
430 memcpy((caddr_t)(ti + 1), (caddr_t)opt, optlen);
431 ti->ti_off = (sizeof (struct tcphdr) + optlen) >> 2;
432 }
433 ti->ti_flags = flags;
434 /*
435 * Calculate receive window. Don't shrink window,
436 * but avoid silly window syndrome.
437 */
438 if (win < (long)(so->so_rcv.sb_datalen / 4) && win < (long)tp->t_maxseg)
439 win = 0;
440 if (win > (long)TCP_MAXWIN << tp->rcv_scale)
441 win = (long)TCP_MAXWIN << tp->rcv_scale;
442 if (win < (long)(tp->rcv_adv - tp->rcv_nxt))
443 win = (long)(tp->rcv_adv - tp->rcv_nxt);
444 ti->ti_win = htons((u_int16_t) (win>>tp->rcv_scale));
445
446 if (SEQ_GT(tp->snd_up, tp->snd_una)) {
447 ti->ti_urp = htons((u_int16_t)(tp->snd_up - ntohl(ti->ti_seq)));
448 #ifdef notdef
449 if (SEQ_GT(tp->snd_up, tp->snd_nxt)) {
450 ti->ti_urp = htons((u_int16_t)(tp->snd_up - tp->snd_nxt));
451 #endif
452 ti->ti_flags |= TH_URG;
453 } else
454 /*
455 * If no urgent pointer to send, then we pull
456 * the urgent pointer to the left edge of the send window
457 * so that it doesn't drift into the send window on sequence
458 * number wraparound.
459 */
460 tp->snd_up = tp->snd_una; /* drag it along */
461
462 /*
463 * Put TCP length in extended header, and then
464 * checksum extended header and data.
465 */
466 if (len + optlen)
467 ti->ti_len = htons((u_int16_t)(sizeof (struct tcphdr) +
468 optlen + len));
469 ti->ti_sum = cksum(m, (int)(hdrlen + len));
470
471 /*
472 * In transmit state, time the transmission and arrange for
473 * the retransmit. In persist state, just set snd_max.
474 */
475 if (tp->t_force == 0 || tp->t_timer[TCPT_PERSIST] == 0) {
476 tcp_seq startseq = tp->snd_nxt;
477
478 /*
479 * Advance snd_nxt over sequence space of this segment.
480 */
481 if (flags & (TH_SYN|TH_FIN)) {
482 if (flags & TH_SYN)
483 tp->snd_nxt++;
484 if (flags & TH_FIN) {
485 tp->snd_nxt++;
486 tp->t_flags |= TF_SENTFIN;
487 }
488 }
489 tp->snd_nxt += len;
490 if (SEQ_GT(tp->snd_nxt, tp->snd_max)) {
491 tp->snd_max = tp->snd_nxt;
492 /*
493 * Time this transmission if not a retransmission and
494 * not currently timing anything.
495 */
496 if (tp->t_rtt == 0) {
497 tp->t_rtt = 1;
498 tp->t_rtseq = startseq;
499 tcpstat.tcps_segstimed++;
500 }
501 }
502
503 /*
504 * Set retransmit timer if not currently set,
505 * and not doing an ack or a keep-alive probe.
506 * Initial value for retransmit timer is smoothed
507 * round-trip time + 2 * round-trip time variance.
508 * Initialize shift counter which is used for backoff
509 * of retransmit time.
510 */
511 if (tp->t_timer[TCPT_REXMT] == 0 &&
512 tp->snd_nxt != tp->snd_una) {
513 tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
514 if (tp->t_timer[TCPT_PERSIST]) {
515 tp->t_timer[TCPT_PERSIST] = 0;
516 tp->t_rxtshift = 0;
517 }
518 }
519 } else
520 if (SEQ_GT(tp->snd_nxt + len, tp->snd_max))
521 tp->snd_max = tp->snd_nxt + len;
522
523 /*
524 * Fill in IP length and desired time to live and
525 * send to IP level. There should be a better way
526 * to handle ttl and tos; we could keep them in
527 * the template, but need a way to checksum without them.
528 */
529 m->m_len = hdrlen + len; /* XXX Needed? m_len should be correct */
530
531 {
532
533 ((struct ip *)ti)->ip_len = m->m_len;
534
535 ((struct ip *)ti)->ip_ttl = ip_defttl;
536 ((struct ip *)ti)->ip_tos = so->so_iptos;
537
538 /* #if BSD >= 43 */
539 /* Don't do IP options... */
540 /* error = ip_output(m, tp->t_inpcb->inp_options, &tp->t_inpcb->inp_route,
541 * so->so_options & SO_DONTROUTE, 0);
542 */
543 error = ip_output(so, m);
544
545 /* #else
546 * error = ip_output(m, (struct mbuf *)0, &tp->t_inpcb->inp_route,
547 * so->so_options & SO_DONTROUTE);
548 * #endif
549 */
550 }
551 if (error) {
552 out:
553 /* if (error == ENOBUFS) {
554 * tcp_quench(tp->t_inpcb, 0);
555 * return (0);
556 * }
557 */
558 /* if ((error == EHOSTUNREACH || error == ENETDOWN)
559 * && TCPS_HAVERCVDSYN(tp->t_state)) {
560 * tp->t_softerror = error;
561 * return (0);
562 * }
563 */
564 return (error);
565 }
566 tcpstat.tcps_sndtotal++;
567
568 /*
569 * Data sent (as far as we can tell).
570 * If this advertises a larger window than any other segment,
571 * then remember the size of the advertised window.
572 * Any pending ACK has now been sent.
573 */
574 if (win > 0 && SEQ_GT(tp->rcv_nxt+win, tp->rcv_adv))
575 tp->rcv_adv = tp->rcv_nxt + win;
576 tp->last_ack_sent = tp->rcv_nxt;
577 tp->t_flags &= ~(TF_ACKNOW|TF_DELACK);
578 if (sendalot)
579 goto again;
580
581 return (0);
582 }
583
584 void
585 tcp_setpersist(tp)
586 register struct tcpcb *tp;
587 {
588 int t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1;
589
590 /* if (tp->t_timer[TCPT_REXMT])
591 * panic("tcp_output REXMT");
592 */
593 /*
594 * Start/restart persistence timer.
595 */
596 TCPT_RANGESET(tp->t_timer[TCPT_PERSIST],
597 t * tcp_backoff[tp->t_rxtshift],
598 TCPTV_PERSMIN, TCPTV_PERSMAX);
599 if (tp->t_rxtshift < TCP_MAXRXTSHIFT)
600 tp->t_rxtshift++;
601 }