Deleted Added
sdiff udiff text old ( 27845 ) new ( 28270 )
full compact
1/*
2 * Copyright (c) 1982, 1986, 1988, 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

--- 17 unchanged lines hidden (view full) ---

26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * From: @(#)tcp_usrreq.c 8.2 (Berkeley) 1/3/94
34 * $Id: tcp_usrreq.c,v 1.32 1997/08/02 14:32:58 bde Exp $
35 */
36
37#include <sys/param.h>
38#include <sys/systm.h>
39#include <sys/kernel.h>
40#include <sys/sysctl.h>
41#include <sys/mbuf.h>
42#include <sys/socket.h>

--- 19 unchanged lines hidden (view full) ---

62#endif
63
64/*
65 * TCP protocol interface to socket abstraction.
66 */
67extern char *tcpstates[]; /* XXX ??? */
68
69static int tcp_attach __P((struct socket *, struct proc *));
70static int tcp_connect __P((struct tcpcb *, struct sockaddr *,
71 struct proc *));
72static struct tcpcb *
73 tcp_disconnect __P((struct tcpcb *));
74static struct tcpcb *
75 tcp_usrclosed __P((struct tcpcb *));
76
77#ifdef TCPDEBUG
78#define TCPDEBUG0 int ostate

--- 55 unchanged lines hidden (view full) ---

134 TCPDEBUG0;
135
136 if (inp == 0) {
137 splx(s);
138 return EINVAL; /* XXX */
139 }
140 tp = intotcpcb(inp);
141 TCPDEBUG1();
142 tp = tcp_disconnect(tp);
143
144 TCPDEBUG2(PRU_DETACH);
145 splx(s);
146 return error;
147}
148
149#define COMMON_START() TCPDEBUG0; \
150 do { \

--- 7 unchanged lines hidden (view full) ---

158
159#define COMMON_END(req) out: TCPDEBUG2(req); splx(s); return error; goto out
160
161
162/*
163 * Give the socket an address.
164 */
165static int
166tcp_usr_bind(struct socket *so, struct sockaddr *nam, struct proc *p)
167{
168 int s = splnet();
169 int error = 0;
170 struct inpcb *inp = sotoinpcb(so);
171 struct tcpcb *tp;
172 struct sockaddr_in *sinp;
173
174 COMMON_START();
175
176 /*
177 * Must check for multicast addresses and disallow binding
178 * to them.
179 */
180 sinp = (struct sockaddr_in *)nam;
181 if (sinp->sin_family == AF_INET &&
182 IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) {
183 error = EAFNOSUPPORT;
184 goto out;
185 }
186 error = in_pcbbind(inp, nam, p);
187 if (error)
188 goto out;

--- 9 unchanged lines hidden (view full) ---

198{
199 int s = splnet();
200 int error = 0;
201 struct inpcb *inp = sotoinpcb(so);
202 struct tcpcb *tp;
203
204 COMMON_START();
205 if (inp->inp_lport == 0)
206 error = in_pcbbind(inp, (struct sockaddr *)0, p);
207 if (error == 0)
208 tp->t_state = TCPS_LISTEN;
209 COMMON_END(PRU_LISTEN);
210}
211
212/*
213 * Initiate connection to peer.
214 * Create a template for use in transmissions on this connection.
215 * Enter SYN_SENT state, and mark socket as connecting.
216 * Start keep-alive timer, and seed output sequence space.
217 * Send initial segment on connection.
218 */
219static int
220tcp_usr_connect(struct socket *so, struct sockaddr *nam, struct proc *p)
221{
222 int s = splnet();
223 int error = 0;
224 struct inpcb *inp = sotoinpcb(so);
225 struct tcpcb *tp;
226 struct sockaddr_in *sinp;
227
228 COMMON_START();
229
230 /*
231 * Must disallow TCP ``connections'' to multicast addresses.
232 */
233 sinp = (struct sockaddr_in *)nam;
234 if (sinp->sin_family == AF_INET
235 && IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) {
236 error = EAFNOSUPPORT;
237 goto out;
238 }
239
240 if ((error = tcp_connect(tp, nam, p)) != 0)
241 goto out;

--- 26 unchanged lines hidden (view full) ---

268}
269
270/*
271 * Accept a connection. Essentially all the work is
272 * done at higher levels; just return the address
273 * of the peer, storing through addr.
274 */
275static int
276tcp_usr_accept(struct socket *so, struct sockaddr **nam)
277{
278 int s = splnet();
279 int error = 0;
280 struct inpcb *inp = sotoinpcb(so);
281 struct tcpcb *tp;
282
283 COMMON_START();
284 in_setpeeraddr(so, nam);

--- 35 unchanged lines hidden (view full) ---

320 COMMON_END(PRU_RCVD);
321}
322
323/*
324 * Do a send by putting data in output queue and updating urgent
325 * marker if URG set. Possibly send more data.
326 */
327static int
328tcp_usr_send(struct socket *so, int flags, struct mbuf *m,
329 struct sockaddr *nam, struct mbuf *control, struct proc *p)
330{
331 int s = splnet();
332 int error = 0;
333 struct inpcb *inp = sotoinpcb(so);
334 struct tcpcb *tp;
335
336 COMMON_START();
337 if (control && control->m_len) {

--- 129 unchanged lines hidden (view full) ---

467 * of the same connection in TIME-WAIT state and if the remote host was
468 * sending CC options and if the connection duration was < MSL, then
469 * truncate the previous TIME-WAIT state and proceed.
470 * Initialize connection parameters and enter SYN-SENT state.
471 */
472static int
473tcp_connect(tp, nam, p)
474 register struct tcpcb *tp;
475 struct sockaddr *nam;
476 struct proc *p;
477{
478 struct inpcb *inp = tp->t_inpcb, *oinp;
479 struct socket *so = inp->inp_socket;
480 struct tcpcb *otp;
481 struct sockaddr_in *sin = (struct sockaddr_in *)nam;
482 struct sockaddr_in *ifaddr;
483 int error;
484 struct rmxp_tao *taop;
485 struct rmxp_tao tao_noncached;
486
487 if (inp->inp_lport == 0) {
488 error = in_pcbbind(inp, (struct sockaddr *)0, p);
489 if (error)
490 return error;
491 }
492
493 /*
494 * Cannot simply call in_pcbconnect, because there might be an
495 * earlier incarnation of this same connection still in
496 * TIME_WAIT state, creating an ADDRINUSE error.

--- 288 unchanged lines hidden ---