ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/slirp/tcp_timer.c
Revision: 1.2
Committed: 2012-03-30T01:10:28Z (12 years, 8 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_timer.c 8.1 (Berkeley) 6/10/93
30 * tcp_timer.c,v 1.2 1994/08/02 07:49:10 davidg Exp
31 */
32
33 #include <slirp.h>
34
35 int tcp_keepidle = TCPTV_KEEP_IDLE;
36 int tcp_keepintvl = TCPTV_KEEPINTVL;
37 int tcp_maxidle;
38 int so_options = DO_KEEPALIVE;
39
40 struct tcpstat tcpstat; /* tcp statistics */
41 u_int32_t tcp_now; /* for RFC 1323 timestamps */
42
43 /*
44 * Fast timeout routine for processing delayed acks
45 */
46 void
47 tcp_fasttimo()
48 {
49 register struct socket *so;
50 register struct tcpcb *tp;
51
52 DEBUG_CALL("tcp_fasttimo");
53
54 so = tcb.so_next;
55 if (so)
56 for (; so != &tcb; so = so->so_next)
57 if ((tp = (struct tcpcb *)so->so_tcpcb) &&
58 (tp->t_flags & TF_DELACK)) {
59 tp->t_flags &= ~TF_DELACK;
60 tp->t_flags |= TF_ACKNOW;
61 tcpstat.tcps_delack++;
62 (void) tcp_output(tp);
63 }
64 }
65
66 /*
67 * Tcp protocol timeout routine called every 500 ms.
68 * Updates the timers in all active tcb's and
69 * causes finite state machine actions if timers expire.
70 */
71 void
72 tcp_slowtimo()
73 {
74 register struct socket *ip, *ipnxt;
75 register struct tcpcb *tp;
76 register int i;
77
78 DEBUG_CALL("tcp_slowtimo");
79
80 tcp_maxidle = TCPTV_KEEPCNT * tcp_keepintvl;
81 /*
82 * Search through tcb's and update active timers.
83 */
84 ip = tcb.so_next;
85 if (ip == 0)
86 return;
87 for (; ip != &tcb; ip = ipnxt) {
88 ipnxt = ip->so_next;
89 tp = sototcpcb(ip);
90 if (tp == 0)
91 continue;
92 for (i = 0; i < TCPT_NTIMERS; i++) {
93 if (tp->t_timer[i] && --tp->t_timer[i] == 0) {
94 tcp_timers(tp,i);
95 if (ipnxt->so_prev != ip)
96 goto tpgone;
97 }
98 }
99 tp->t_idle++;
100 if (tp->t_rtt)
101 tp->t_rtt++;
102 tpgone:
103 ;
104 }
105 tcp_iss += TCP_ISSINCR/PR_SLOWHZ; /* increment iss */
106 #ifdef TCP_COMPAT_42
107 if ((int)tcp_iss < 0)
108 tcp_iss = 0; /* XXX */
109 #endif
110 tcp_now++; /* for timestamps */
111 }
112
113 /*
114 * Cancel all timers for TCP tp.
115 */
116 void
117 tcp_canceltimers(tp)
118 struct tcpcb *tp;
119 {
120 register int i;
121
122 for (i = 0; i < TCPT_NTIMERS; i++)
123 tp->t_timer[i] = 0;
124 }
125
126 int tcp_backoff[TCP_MAXRXTSHIFT + 1] =
127 { 1, 2, 4, 8, 16, 32, 64, 64, 64, 64, 64, 64, 64 };
128
129 /*
130 * TCP timer processing.
131 */
132 struct tcpcb *
133 tcp_timers(tp, timer)
134 register struct tcpcb *tp;
135 int timer;
136 {
137 register int rexmt;
138
139 DEBUG_CALL("tcp_timers");
140
141 switch (timer) {
142
143 /*
144 * 2 MSL timeout in shutdown went off. If we're closed but
145 * still waiting for peer to close and connection has been idle
146 * too long, or if 2MSL time is up from TIME_WAIT, delete connection
147 * control block. Otherwise, check again in a bit.
148 */
149 case TCPT_2MSL:
150 if (tp->t_state != TCPS_TIME_WAIT &&
151 tp->t_idle <= tcp_maxidle)
152 tp->t_timer[TCPT_2MSL] = tcp_keepintvl;
153 else
154 tp = tcp_close(tp);
155 break;
156
157 /*
158 * Retransmission timer went off. Message has not
159 * been acked within retransmit interval. Back off
160 * to a longer retransmit interval and retransmit one segment.
161 */
162 case TCPT_REXMT:
163
164 /*
165 * XXXXX If a packet has timed out, then remove all the queued
166 * packets for that session.
167 */
168
169 if (++tp->t_rxtshift > TCP_MAXRXTSHIFT) {
170 /*
171 * This is a hack to suit our terminal server here at the uni of canberra
172 * since they have trouble with zeroes... It usually lets them through
173 * unharmed, but under some conditions, it'll eat the zeros. If we
174 * keep retransmitting it, it'll keep eating the zeroes, so we keep
175 * retransmitting, and eventually the connection dies...
176 * (this only happens on incoming data)
177 *
178 * So, if we were gonna drop the connection from too many retransmits,
179 * don't... instead halve the t_maxseg, which might break up the NULLs and
180 * let them through
181 *
182 * *sigh*
183 */
184
185 tp->t_maxseg >>= 1;
186 if (tp->t_maxseg < 32) {
187 /*
188 * We tried our best, now the connection must die!
189 */
190 tp->t_rxtshift = TCP_MAXRXTSHIFT;
191 tcpstat.tcps_timeoutdrop++;
192 tp = tcp_drop(tp, tp->t_softerror);
193 /* tp->t_softerror : ETIMEDOUT); */ /* XXX */
194 return (tp); /* XXX */
195 }
196
197 /*
198 * Set rxtshift to 6, which is still at the maximum
199 * backoff time
200 */
201 tp->t_rxtshift = 6;
202 }
203 tcpstat.tcps_rexmttimeo++;
204 rexmt = TCP_REXMTVAL(tp) * tcp_backoff[tp->t_rxtshift];
205 TCPT_RANGESET(tp->t_rxtcur, rexmt,
206 (short)tp->t_rttmin, TCPTV_REXMTMAX); /* XXX */
207 tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
208 /*
209 * If losing, let the lower level know and try for
210 * a better route. Also, if we backed off this far,
211 * our srtt estimate is probably bogus. Clobber it
212 * so we'll take the next rtt measurement as our srtt;
213 * move the current srtt into rttvar to keep the current
214 * retransmit times until then.
215 */
216 if (tp->t_rxtshift > TCP_MAXRXTSHIFT / 4) {
217 /* in_losing(tp->t_inpcb); */
218 tp->t_rttvar += (tp->t_srtt >> TCP_RTT_SHIFT);
219 tp->t_srtt = 0;
220 }
221 tp->snd_nxt = tp->snd_una;
222 /*
223 * If timing a segment in this window, stop the timer.
224 */
225 tp->t_rtt = 0;
226 /*
227 * Close the congestion window down to one segment
228 * (we'll open it by one segment for each ack we get).
229 * Since we probably have a window's worth of unacked
230 * data accumulated, this "slow start" keeps us from
231 * dumping all that data as back-to-back packets (which
232 * might overwhelm an intermediate gateway).
233 *
234 * There are two phases to the opening: Initially we
235 * open by one mss on each ack. This makes the window
236 * size increase exponentially with time. If the
237 * window is larger than the path can handle, this
238 * exponential growth results in dropped packet(s)
239 * almost immediately. To get more time between
240 * drops but still "push" the network to take advantage
241 * of improving conditions, we switch from exponential
242 * to linear window opening at some threshold size.
243 * For a threshold, we use half the current window
244 * size, truncated to a multiple of the mss.
245 *
246 * (the minimum cwnd that will give us exponential
247 * growth is 2 mss. We don't allow the threshold
248 * to go below this.)
249 */
250 {
251 u_int win = min(tp->snd_wnd, tp->snd_cwnd) / 2 / tp->t_maxseg;
252 if (win < 2)
253 win = 2;
254 tp->snd_cwnd = tp->t_maxseg;
255 tp->snd_ssthresh = win * tp->t_maxseg;
256 tp->t_dupacks = 0;
257 }
258 (void) tcp_output(tp);
259 break;
260
261 /*
262 * Persistence timer into zero window.
263 * Force a byte to be output, if possible.
264 */
265 case TCPT_PERSIST:
266 tcpstat.tcps_persisttimeo++;
267 tcp_setpersist(tp);
268 tp->t_force = 1;
269 (void) tcp_output(tp);
270 tp->t_force = 0;
271 break;
272
273 /*
274 * Keep-alive timer went off; send something
275 * or drop connection if idle for too long.
276 */
277 case TCPT_KEEP:
278 tcpstat.tcps_keeptimeo++;
279 if (tp->t_state < TCPS_ESTABLISHED)
280 goto dropit;
281
282 /* if (tp->t_socket->so_options & SO_KEEPALIVE && */
283 if ((so_options) && tp->t_state <= TCPS_CLOSE_WAIT) {
284 if (tp->t_idle >= tcp_keepidle + tcp_maxidle)
285 goto dropit;
286 /*
287 * Send a packet designed to force a response
288 * if the peer is up and reachable:
289 * either an ACK if the connection is still alive,
290 * or an RST if the peer has closed the connection
291 * due to timeout or reboot.
292 * Using sequence number tp->snd_una-1
293 * causes the transmitted zero-length segment
294 * to lie outside the receive window;
295 * by the protocol spec, this requires the
296 * correspondent TCP to respond.
297 */
298 tcpstat.tcps_keepprobe++;
299 #ifdef TCP_COMPAT_42
300 /*
301 * The keepalive packet must have nonzero length
302 * to get a 4.2 host to respond.
303 */
304 tcp_respond(tp, &tp->t_template, (struct mbuf *)NULL,
305 tp->rcv_nxt - 1, tp->snd_una - 1, 0);
306 #else
307 tcp_respond(tp, &tp->t_template, (struct mbuf *)NULL,
308 tp->rcv_nxt, tp->snd_una - 1, 0);
309 #endif
310 tp->t_timer[TCPT_KEEP] = tcp_keepintvl;
311 } else
312 tp->t_timer[TCPT_KEEP] = tcp_keepidle;
313 break;
314
315 dropit:
316 tcpstat.tcps_keepdrops++;
317 tp = tcp_drop(tp, 0); /* ETIMEDOUT); */
318 break;
319 }
320
321 return (tp);
322 }