]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/netinet/tcp_usrreq.c
This commit was generated by cvs2svn to compensate for changes in r94880,
[FreeBSD/FreeBSD.git] / sys / netinet / tcp_usrreq.c
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
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. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by the University of
16  *      California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
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  * $FreeBSD$
35  */
36
37 #include "opt_ipsec.h"
38 #include "opt_inet6.h"
39 #include "opt_tcpdebug.h"
40
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/kernel.h>
44 #include <sys/sysctl.h>
45 #include <sys/mbuf.h>
46 #ifdef INET6
47 #include <sys/domain.h>
48 #endif /* INET6 */
49 #include <sys/socket.h>
50 #include <sys/socketvar.h>
51 #include <sys/protosw.h>
52 #include <sys/proc.h>
53 #include <sys/jail.h>
54
55 #include <net/if.h>
56 #include <net/route.h>
57
58 #include <netinet/in.h>
59 #include <netinet/in_systm.h>
60 #ifdef INET6
61 #include <netinet/ip6.h>
62 #endif
63 #include <netinet/in_pcb.h>
64 #ifdef INET6
65 #include <netinet6/in6_pcb.h>
66 #endif
67 #include <netinet/in_var.h>
68 #include <netinet/ip_var.h>
69 #ifdef INET6
70 #include <netinet6/ip6_var.h>
71 #endif
72 #include <netinet/tcp.h>
73 #include <netinet/tcp_fsm.h>
74 #include <netinet/tcp_seq.h>
75 #include <netinet/tcp_timer.h>
76 #include <netinet/tcp_var.h>
77 #include <netinet/tcpip.h>
78 #ifdef TCPDEBUG
79 #include <netinet/tcp_debug.h>
80 #endif
81
82 #ifdef IPSEC
83 #include <netinet6/ipsec.h>
84 #endif /*IPSEC*/
85
86 /*
87  * TCP protocol interface to socket abstraction.
88  */
89 extern  char *tcpstates[];      /* XXX ??? */
90
91 static int      tcp_attach(struct socket *, struct thread *td);
92 static int      tcp_connect(struct tcpcb *, struct sockaddr *,
93                     struct thread *td);
94 #ifdef INET6
95 static int      tcp6_connect(struct tcpcb *, struct sockaddr *,
96                     struct thread *td);
97 #endif /* INET6 */
98 static struct tcpcb *
99                 tcp_disconnect(struct tcpcb *);
100 static struct tcpcb *
101                 tcp_usrclosed(struct tcpcb *);
102
103 #ifdef TCPDEBUG
104 #define TCPDEBUG0       int ostate = 0
105 #define TCPDEBUG1()     ostate = tp ? tp->t_state : 0
106 #define TCPDEBUG2(req)  if (tp && (so->so_options & SO_DEBUG)) \
107                                 tcp_trace(TA_USER, ostate, tp, 0, 0, req)
108 #else
109 #define TCPDEBUG0
110 #define TCPDEBUG1()
111 #define TCPDEBUG2(req)
112 #endif
113
114 /*
115  * TCP attaches to socket via pru_attach(), reserving space,
116  * and an internet control block.
117  */
118 static int
119 tcp_usr_attach(struct socket *so, int proto, struct thread *td)
120 {
121         int s = splnet();
122         int error;
123         struct inpcb *inp = sotoinpcb(so);
124         struct tcpcb *tp = 0;
125         TCPDEBUG0;
126
127         TCPDEBUG1();
128         if (inp) {
129                 error = EISCONN;
130                 goto out;
131         }
132
133         error = tcp_attach(so, td);
134         if (error)
135                 goto out;
136
137         if ((so->so_options & SO_LINGER) && so->so_linger == 0)
138                 so->so_linger = TCP_LINGERTIME;
139         tp = sototcpcb(so);
140 out:
141         TCPDEBUG2(PRU_ATTACH);
142         splx(s);
143         return error;
144 }
145
146 /*
147  * pru_detach() detaches the TCP protocol from the socket.
148  * If the protocol state is non-embryonic, then can't
149  * do this directly: have to initiate a pru_disconnect(),
150  * which may finish later; embryonic TCB's can just
151  * be discarded here.
152  */
153 static int
154 tcp_usr_detach(struct socket *so)
155 {
156         int s = splnet();
157         int error = 0;
158         struct inpcb *inp = sotoinpcb(so);
159         struct tcpcb *tp;
160         TCPDEBUG0;
161
162         if (inp == 0) {
163                 splx(s);
164                 return EINVAL;  /* XXX */
165         }
166         tp = intotcpcb(inp);
167         TCPDEBUG1();
168         tp = tcp_disconnect(tp);
169
170         TCPDEBUG2(PRU_DETACH);
171         splx(s);
172         return error;
173 }
174
175 #define COMMON_START()  TCPDEBUG0; \
176                         do { \
177                                      if (inp == 0) { \
178                                              splx(s); \
179                                              return EINVAL; \
180                                      } \
181                                      tp = intotcpcb(inp); \
182                                      TCPDEBUG1(); \
183                      } while(0)
184                              
185 #define COMMON_END(req) out: TCPDEBUG2(req); splx(s); return error; goto out
186
187
188 /*
189  * Give the socket an address.
190  */
191 static int
192 tcp_usr_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
193 {
194         int s = splnet();
195         int error = 0;
196         struct inpcb *inp = sotoinpcb(so);
197         struct tcpcb *tp;
198         struct sockaddr_in *sinp;
199
200         COMMON_START();
201
202         /*
203          * Must check for multicast addresses and disallow binding
204          * to them.
205          */
206         sinp = (struct sockaddr_in *)nam;
207         if (sinp->sin_family == AF_INET &&
208             IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) {
209                 error = EAFNOSUPPORT;
210                 goto out;
211         }
212         error = in_pcbbind(inp, nam, td);
213         if (error)
214                 goto out;
215         COMMON_END(PRU_BIND);
216
217 }
218
219 #ifdef INET6
220 static int
221 tcp6_usr_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
222 {
223         int s = splnet();
224         int error = 0;
225         struct inpcb *inp = sotoinpcb(so);
226         struct tcpcb *tp;
227         struct sockaddr_in6 *sin6p;
228
229         COMMON_START();
230
231         /*
232          * Must check for multicast addresses and disallow binding
233          * to them.
234          */
235         sin6p = (struct sockaddr_in6 *)nam;
236         if (sin6p->sin6_family == AF_INET6 &&
237             IN6_IS_ADDR_MULTICAST(&sin6p->sin6_addr)) {
238                 error = EAFNOSUPPORT;
239                 goto out;
240         }
241         inp->inp_vflag &= ~INP_IPV4;
242         inp->inp_vflag |= INP_IPV6;
243         if (ip6_mapped_addr_on && (inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
244                 if (IN6_IS_ADDR_UNSPECIFIED(&sin6p->sin6_addr))
245                         inp->inp_vflag |= INP_IPV4;
246                 else if (IN6_IS_ADDR_V4MAPPED(&sin6p->sin6_addr)) {
247                         struct sockaddr_in sin;
248
249                         in6_sin6_2_sin(&sin, sin6p);
250                         inp->inp_vflag |= INP_IPV4;
251                         inp->inp_vflag &= ~INP_IPV6;
252                         error = in_pcbbind(inp, (struct sockaddr *)&sin, td);
253                         goto out;
254                 }
255         }
256         error = in6_pcbbind(inp, nam, td);
257         if (error)
258                 goto out;
259         COMMON_END(PRU_BIND);
260 }
261 #endif /* INET6 */
262
263 /*
264  * Prepare to accept connections.
265  */
266 static int
267 tcp_usr_listen(struct socket *so, struct thread *td)
268 {
269         int s = splnet();
270         int error = 0;
271         struct inpcb *inp = sotoinpcb(so);
272         struct tcpcb *tp;
273
274         COMMON_START();
275         if (inp->inp_lport == 0)
276                 error = in_pcbbind(inp, (struct sockaddr *)0, td);
277         if (error == 0)
278                 tp->t_state = TCPS_LISTEN;
279         COMMON_END(PRU_LISTEN);
280 }
281
282 #ifdef INET6
283 static int
284 tcp6_usr_listen(struct socket *so, struct thread *td)
285 {
286         int s = splnet();
287         int error = 0;
288         struct inpcb *inp = sotoinpcb(so);
289         struct tcpcb *tp;
290
291         COMMON_START();
292         if (inp->inp_lport == 0) {
293                 inp->inp_vflag &= ~INP_IPV4;
294                 if (ip6_mapped_addr_on &&
295                     (inp->inp_flags & IN6P_IPV6_V6ONLY) == 0)
296                         inp->inp_vflag |= INP_IPV4;
297                 error = in6_pcbbind(inp, (struct sockaddr *)0, td);
298         }
299         if (error == 0)
300                 tp->t_state = TCPS_LISTEN;
301         COMMON_END(PRU_LISTEN);
302 }
303 #endif /* INET6 */
304
305 /*
306  * Initiate connection to peer.
307  * Create a template for use in transmissions on this connection.
308  * Enter SYN_SENT state, and mark socket as connecting.
309  * Start keep-alive timer, and seed output sequence space.
310  * Send initial segment on connection.
311  */
312 static int
313 tcp_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
314 {
315         int s = splnet();
316         int error = 0;
317         struct inpcb *inp = sotoinpcb(so);
318         struct tcpcb *tp;
319         struct sockaddr_in *sinp;
320
321         COMMON_START();
322
323         /*
324          * Must disallow TCP ``connections'' to multicast addresses.
325          */
326         sinp = (struct sockaddr_in *)nam;
327         if (sinp->sin_family == AF_INET
328             && IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) {
329                 error = EAFNOSUPPORT;
330                 goto out;
331         }
332
333         if (td && jailed(td->td_ucred))
334                 prison_remote_ip(td->td_ucred, 0, &sinp->sin_addr.s_addr);
335
336         if ((error = tcp_connect(tp, nam, td)) != 0)
337                 goto out;
338         error = tcp_output(tp);
339         COMMON_END(PRU_CONNECT);
340 }
341
342 #ifdef INET6
343 static int
344 tcp6_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
345 {
346         int s = splnet();
347         int error = 0;
348         struct inpcb *inp = sotoinpcb(so);
349         struct tcpcb *tp;
350         struct sockaddr_in6 *sin6p;
351
352         COMMON_START();
353
354         /*
355          * Must disallow TCP ``connections'' to multicast addresses.
356          */
357         sin6p = (struct sockaddr_in6 *)nam;
358         if (sin6p->sin6_family == AF_INET6
359             && IN6_IS_ADDR_MULTICAST(&sin6p->sin6_addr)) {
360                 error = EAFNOSUPPORT;
361                 goto out;
362         }
363
364         if (IN6_IS_ADDR_V4MAPPED(&sin6p->sin6_addr)) {
365                 struct sockaddr_in sin;
366
367                 if (!ip6_mapped_addr_on ||
368                     (inp->inp_flags & IN6P_IPV6_V6ONLY))
369                         return(EINVAL);
370
371                 in6_sin6_2_sin(&sin, sin6p);
372                 inp->inp_vflag |= INP_IPV4;
373                 inp->inp_vflag &= ~INP_IPV6;
374                 if ((error = tcp_connect(tp, (struct sockaddr *)&sin, td)) != 0)
375                         goto out;
376                 error = tcp_output(tp);
377                 goto out;
378         }
379         inp->inp_vflag &= ~INP_IPV4;
380         inp->inp_vflag |= INP_IPV6;
381         inp->inp_inc.inc_isipv6 = 1;
382         if ((error = tcp6_connect(tp, nam, td)) != 0)
383                 goto out;
384         error = tcp_output(tp);
385         COMMON_END(PRU_CONNECT);
386 }
387 #endif /* INET6 */
388
389 /*
390  * Initiate disconnect from peer.
391  * If connection never passed embryonic stage, just drop;
392  * else if don't need to let data drain, then can just drop anyways,
393  * else have to begin TCP shutdown process: mark socket disconnecting,
394  * drain unread data, state switch to reflect user close, and
395  * send segment (e.g. FIN) to peer.  Socket will be really disconnected
396  * when peer sends FIN and acks ours.
397  *
398  * SHOULD IMPLEMENT LATER PRU_CONNECT VIA REALLOC TCPCB.
399  */
400 static int
401 tcp_usr_disconnect(struct socket *so)
402 {
403         int s = splnet();
404         int error = 0;
405         struct inpcb *inp = sotoinpcb(so);
406         struct tcpcb *tp;
407
408         COMMON_START();
409         tp = tcp_disconnect(tp);
410         COMMON_END(PRU_DISCONNECT);
411 }
412
413 /*
414  * Accept a connection.  Essentially all the work is
415  * done at higher levels; just return the address
416  * of the peer, storing through addr.
417  */
418 static int
419 tcp_usr_accept(struct socket *so, struct sockaddr **nam)
420 {
421         int s = splnet();
422         int error = 0;
423         struct inpcb *inp = sotoinpcb(so);
424         struct tcpcb *tp = NULL;
425         TCPDEBUG0;
426
427         if (so->so_state & SS_ISDISCONNECTED) {
428                 error = ECONNABORTED;
429                 goto out;
430         }
431         if (inp == 0) {
432                 splx(s);
433                 return (EINVAL);
434         }
435         tp = intotcpcb(inp);
436         TCPDEBUG1();
437         in_setpeeraddr(so, nam);
438         COMMON_END(PRU_ACCEPT);
439 }
440
441 #ifdef INET6
442 static int
443 tcp6_usr_accept(struct socket *so, struct sockaddr **nam)
444 {
445         int s = splnet();
446         int error = 0;
447         struct inpcb *inp = sotoinpcb(so);
448         struct tcpcb *tp = NULL;
449         TCPDEBUG0;
450
451         if (so->so_state & SS_ISDISCONNECTED) {
452                 error = ECONNABORTED;
453                 goto out;
454         }
455         if (inp == 0) {
456                 splx(s);
457                 return (EINVAL);
458         }
459         tp = intotcpcb(inp);
460         TCPDEBUG1();
461         in6_mapped_peeraddr(so, nam);
462         COMMON_END(PRU_ACCEPT);
463 }
464 #endif /* INET6 */
465 /*
466  * Mark the connection as being incapable of further output.
467  */
468 static int
469 tcp_usr_shutdown(struct socket *so)
470 {
471         int s = splnet();
472         int error = 0;
473         struct inpcb *inp = sotoinpcb(so);
474         struct tcpcb *tp;
475
476         COMMON_START();
477         socantsendmore(so);
478         tp = tcp_usrclosed(tp);
479         if (tp)
480                 error = tcp_output(tp);
481         COMMON_END(PRU_SHUTDOWN);
482 }
483
484 /*
485  * After a receive, possibly send window update to peer.
486  */
487 static int
488 tcp_usr_rcvd(struct socket *so, int flags)
489 {
490         int s = splnet();
491         int error = 0;
492         struct inpcb *inp = sotoinpcb(so);
493         struct tcpcb *tp;
494
495         COMMON_START();
496         tcp_output(tp);
497         COMMON_END(PRU_RCVD);
498 }
499
500 /*
501  * Do a send by putting data in output queue and updating urgent
502  * marker if URG set.  Possibly send more data.  Unlike the other
503  * pru_*() routines, the mbuf chains are our responsibility.  We
504  * must either enqueue them or free them.  The other pru_* routines
505  * generally are caller-frees.
506  */
507 static int
508 tcp_usr_send(struct socket *so, int flags, struct mbuf *m, 
509              struct sockaddr *nam, struct mbuf *control, struct thread *td)
510 {
511         int s = splnet();
512         int error = 0;
513         struct inpcb *inp = sotoinpcb(so);
514         struct tcpcb *tp;
515 #ifdef INET6
516         int isipv6;
517 #endif
518         TCPDEBUG0;
519
520         if (inp == NULL) {
521                 /*
522                  * OOPS! we lost a race, the TCP session got reset after
523                  * we checked SS_CANTSENDMORE, eg: while doing uiomove or a
524                  * network interrupt in the non-splnet() section of sosend().
525                  */
526                 if (m)
527                         m_freem(m);
528                 if (control)
529                         m_freem(control);
530                 error = ECONNRESET;     /* XXX EPIPE? */
531                 tp = NULL;
532                 TCPDEBUG1();
533                 goto out;
534         }
535 #ifdef INET6
536         isipv6 = nam && nam->sa_family == AF_INET6;
537 #endif /* INET6 */
538         tp = intotcpcb(inp);
539         TCPDEBUG1();
540         if (control) {
541                 /* TCP doesn't do control messages (rights, creds, etc) */
542                 if (control->m_len) {
543                         m_freem(control);
544                         if (m)
545                                 m_freem(m);
546                         error = EINVAL;
547                         goto out;
548                 }
549                 m_freem(control);       /* empty control, just free it */
550         }
551         if(!(flags & PRUS_OOB)) {
552                 sbappend(&so->so_snd, m);
553                 if (nam && tp->t_state < TCPS_SYN_SENT) {
554                         /*
555                          * Do implied connect if not yet connected,
556                          * initialize window to default value, and
557                          * initialize maxseg/maxopd using peer's cached
558                          * MSS.
559                          */
560 #ifdef INET6
561                         if (isipv6)
562                                 error = tcp6_connect(tp, nam, td);
563                         else
564 #endif /* INET6 */
565                         error = tcp_connect(tp, nam, td);
566                         if (error)
567                                 goto out;
568                         tp->snd_wnd = TTCP_CLIENT_SND_WND;
569                         tcp_mss(tp, -1);
570                 }
571
572                 if (flags & PRUS_EOF) {
573                         /*
574                          * Close the send side of the connection after
575                          * the data is sent.
576                          */
577                         socantsendmore(so);
578                         tp = tcp_usrclosed(tp);
579                 }
580                 if (tp != NULL) {
581                         if (flags & PRUS_MORETOCOME)
582                                 tp->t_flags |= TF_MORETOCOME;
583                         error = tcp_output(tp);
584                         if (flags & PRUS_MORETOCOME)
585                                 tp->t_flags &= ~TF_MORETOCOME;
586                 }
587         } else {
588                 if (sbspace(&so->so_snd) < -512) {
589                         m_freem(m);
590                         error = ENOBUFS;
591                         goto out;
592                 }
593                 /*
594                  * According to RFC961 (Assigned Protocols),
595                  * the urgent pointer points to the last octet
596                  * of urgent data.  We continue, however,
597                  * to consider it to indicate the first octet
598                  * of data past the urgent section.
599                  * Otherwise, snd_up should be one lower.
600                  */
601                 sbappend(&so->so_snd, m);
602                 if (nam && tp->t_state < TCPS_SYN_SENT) {
603                         /*
604                          * Do implied connect if not yet connected,
605                          * initialize window to default value, and
606                          * initialize maxseg/maxopd using peer's cached
607                          * MSS.
608                          */
609 #ifdef INET6
610                         if (isipv6)
611                                 error = tcp6_connect(tp, nam, td);
612                         else
613 #endif /* INET6 */
614                         error = tcp_connect(tp, nam, td);
615                         if (error)
616                                 goto out;
617                         tp->snd_wnd = TTCP_CLIENT_SND_WND;
618                         tcp_mss(tp, -1);
619                 }
620                 tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
621                 tp->t_force = 1;
622                 error = tcp_output(tp);
623                 tp->t_force = 0;
624         }
625         COMMON_END((flags & PRUS_OOB) ? PRU_SENDOOB : 
626                    ((flags & PRUS_EOF) ? PRU_SEND_EOF : PRU_SEND));
627 }
628
629 /*
630  * Abort the TCP.
631  */
632 static int
633 tcp_usr_abort(struct socket *so)
634 {
635         int s = splnet();
636         int error = 0;
637         struct inpcb *inp = sotoinpcb(so);
638         struct tcpcb *tp;
639
640         COMMON_START();
641         tp = tcp_drop(tp, ECONNABORTED);
642         COMMON_END(PRU_ABORT);
643 }
644
645 /*
646  * Receive out-of-band data.
647  */
648 static int
649 tcp_usr_rcvoob(struct socket *so, struct mbuf *m, int flags)
650 {
651         int s = splnet();
652         int error = 0;
653         struct inpcb *inp = sotoinpcb(so);
654         struct tcpcb *tp;
655
656         COMMON_START();
657         if ((so->so_oobmark == 0 &&
658              (so->so_state & SS_RCVATMARK) == 0) ||
659             so->so_options & SO_OOBINLINE ||
660             tp->t_oobflags & TCPOOB_HADDATA) {
661                 error = EINVAL;
662                 goto out;
663         }
664         if ((tp->t_oobflags & TCPOOB_HAVEDATA) == 0) {
665                 error = EWOULDBLOCK;
666                 goto out;
667         }
668         m->m_len = 1;
669         *mtod(m, caddr_t) = tp->t_iobc;
670         if ((flags & MSG_PEEK) == 0)
671                 tp->t_oobflags ^= (TCPOOB_HAVEDATA | TCPOOB_HADDATA);
672         COMMON_END(PRU_RCVOOB);
673 }
674
675 /* xxx - should be const */
676 struct pr_usrreqs tcp_usrreqs = {
677         tcp_usr_abort, tcp_usr_accept, tcp_usr_attach, tcp_usr_bind,
678         tcp_usr_connect, pru_connect2_notsupp, in_control, tcp_usr_detach,
679         tcp_usr_disconnect, tcp_usr_listen, in_setpeeraddr, tcp_usr_rcvd,
680         tcp_usr_rcvoob, tcp_usr_send, pru_sense_null, tcp_usr_shutdown,
681         in_setsockaddr, sosend, soreceive, sopoll
682 };
683
684 #ifdef INET6
685 struct pr_usrreqs tcp6_usrreqs = {
686         tcp_usr_abort, tcp6_usr_accept, tcp_usr_attach, tcp6_usr_bind,
687         tcp6_usr_connect, pru_connect2_notsupp, in6_control, tcp_usr_detach,
688         tcp_usr_disconnect, tcp6_usr_listen, in6_mapped_peeraddr, tcp_usr_rcvd,
689         tcp_usr_rcvoob, tcp_usr_send, pru_sense_null, tcp_usr_shutdown,
690         in6_mapped_sockaddr, sosend, soreceive, sopoll
691 };
692 #endif /* INET6 */
693
694 /*
695  * Common subroutine to open a TCP connection to remote host specified
696  * by struct sockaddr_in in mbuf *nam.  Call in_pcbbind to assign a local
697  * port number if needed.  Call in_pcbladdr to do the routing and to choose
698  * a local host address (interface).  If there is an existing incarnation
699  * of the same connection in TIME-WAIT state and if the remote host was
700  * sending CC options and if the connection duration was < MSL, then
701  * truncate the previous TIME-WAIT state and proceed.
702  * Initialize connection parameters and enter SYN-SENT state.
703  */
704 static int
705 tcp_connect(tp, nam, td)
706         register struct tcpcb *tp;
707         struct sockaddr *nam;
708         struct thread *td;
709 {
710         struct inpcb *inp = tp->t_inpcb, *oinp;
711         struct socket *so = inp->inp_socket;
712         struct tcpcb *otp;
713         struct sockaddr_in *sin = (struct sockaddr_in *)nam;
714         struct sockaddr_in *ifaddr;
715         struct rmxp_tao *taop;
716         struct rmxp_tao tao_noncached;
717         int error;
718
719         if (inp->inp_lport == 0) {
720                 error = in_pcbbind(inp, (struct sockaddr *)0, td);
721                 if (error)
722                         return error;
723         }
724
725         /*
726          * Cannot simply call in_pcbconnect, because there might be an
727          * earlier incarnation of this same connection still in
728          * TIME_WAIT state, creating an ADDRINUSE error.
729          */
730         error = in_pcbladdr(inp, nam, &ifaddr);
731         if (error)
732                 return error;
733         oinp = in_pcblookup_hash(inp->inp_pcbinfo,
734             sin->sin_addr, sin->sin_port,
735             inp->inp_laddr.s_addr != INADDR_ANY ? inp->inp_laddr
736                                                 : ifaddr->sin_addr,
737             inp->inp_lport,  0, NULL);
738         if (oinp) {
739                 if (oinp != inp && (otp = intotcpcb(oinp)) != NULL &&
740                 otp->t_state == TCPS_TIME_WAIT &&
741                     (ticks - otp->t_starttime) < tcp_msl &&
742                     (otp->t_flags & TF_RCVD_CC))
743                         otp = tcp_close(otp);
744                 else
745                         return EADDRINUSE;
746         }
747         if (inp->inp_laddr.s_addr == INADDR_ANY)
748                 inp->inp_laddr = ifaddr->sin_addr;
749         inp->inp_faddr = sin->sin_addr;
750         inp->inp_fport = sin->sin_port;
751         in_pcbrehash(inp);
752
753         /* Compute window scaling to request.  */
754         while (tp->request_r_scale < TCP_MAX_WINSHIFT &&
755             (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat)
756                 tp->request_r_scale++;
757
758         soisconnecting(so);
759         tcpstat.tcps_connattempt++;
760         tp->t_state = TCPS_SYN_SENT;
761         callout_reset(tp->tt_keep, tcp_keepinit, tcp_timer_keep, tp);
762         tp->iss = tcp_new_isn(tp);
763         tcp_sendseqinit(tp);
764
765         /*
766          * Generate a CC value for this connection and
767          * check whether CC or CCnew should be used.
768          */
769         if ((taop = tcp_gettaocache(&tp->t_inpcb->inp_inc)) == NULL) {
770                 taop = &tao_noncached;
771                 bzero(taop, sizeof(*taop));
772         }
773
774         tp->cc_send = CC_INC(tcp_ccgen);
775         if (taop->tao_ccsent != 0 &&
776             CC_GEQ(tp->cc_send, taop->tao_ccsent)) {
777                 taop->tao_ccsent = tp->cc_send;
778         } else {
779                 taop->tao_ccsent = 0;
780                 tp->t_flags |= TF_SENDCCNEW;
781         }
782
783         return 0;
784 }
785
786 #ifdef INET6
787 static int
788 tcp6_connect(tp, nam, td)
789         register struct tcpcb *tp;
790         struct sockaddr *nam;
791         struct thread *td;
792 {
793         struct inpcb *inp = tp->t_inpcb, *oinp;
794         struct socket *so = inp->inp_socket;
795         struct tcpcb *otp;
796         struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam;
797         struct in6_addr *addr6;
798         struct rmxp_tao *taop;
799         struct rmxp_tao tao_noncached;
800         int error;
801
802         if (inp->inp_lport == 0) {
803                 error = in6_pcbbind(inp, (struct sockaddr *)0, td);
804                 if (error)
805                         return error;
806         }
807
808         /*
809          * Cannot simply call in_pcbconnect, because there might be an
810          * earlier incarnation of this same connection still in
811          * TIME_WAIT state, creating an ADDRINUSE error.
812          */
813         error = in6_pcbladdr(inp, nam, &addr6);
814         if (error)
815                 return error;
816         oinp = in6_pcblookup_hash(inp->inp_pcbinfo,
817                                   &sin6->sin6_addr, sin6->sin6_port,
818                                   IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)
819                                   ? addr6
820                                   : &inp->in6p_laddr,
821                                   inp->inp_lport,  0, NULL);
822         if (oinp) {
823                 if (oinp != inp && (otp = intotcpcb(oinp)) != NULL &&
824                     otp->t_state == TCPS_TIME_WAIT &&
825                     (ticks - otp->t_starttime) < tcp_msl &&
826                     (otp->t_flags & TF_RCVD_CC))
827                         otp = tcp_close(otp);
828                 else
829                         return EADDRINUSE;
830         }
831         if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
832                 inp->in6p_laddr = *addr6;
833         inp->in6p_faddr = sin6->sin6_addr;
834         inp->inp_fport = sin6->sin6_port;
835         if ((sin6->sin6_flowinfo & IPV6_FLOWINFO_MASK) != NULL)
836                 inp->in6p_flowinfo = sin6->sin6_flowinfo;
837         in_pcbrehash(inp);
838
839         /* Compute window scaling to request.  */
840         while (tp->request_r_scale < TCP_MAX_WINSHIFT &&
841             (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat)
842                 tp->request_r_scale++;
843
844         soisconnecting(so);
845         tcpstat.tcps_connattempt++;
846         tp->t_state = TCPS_SYN_SENT;
847         callout_reset(tp->tt_keep, tcp_keepinit, tcp_timer_keep, tp);
848         tp->iss = tcp_new_isn(tp);
849         tcp_sendseqinit(tp);
850
851         /*
852          * Generate a CC value for this connection and
853          * check whether CC or CCnew should be used.
854          */
855         if ((taop = tcp_gettaocache(&tp->t_inpcb->inp_inc)) == NULL) {
856                 taop = &tao_noncached;
857                 bzero(taop, sizeof(*taop));
858         }
859
860         tp->cc_send = CC_INC(tcp_ccgen);
861         if (taop->tao_ccsent != 0 &&
862             CC_GEQ(tp->cc_send, taop->tao_ccsent)) {
863                 taop->tao_ccsent = tp->cc_send;
864         } else {
865                 taop->tao_ccsent = 0;
866                 tp->t_flags |= TF_SENDCCNEW;
867         }
868
869         return 0;
870 }
871 #endif /* INET6 */
872
873 /*
874  * The new sockopt interface makes it possible for us to block in the
875  * copyin/out step (if we take a page fault).  Taking a page fault at
876  * splnet() is probably a Bad Thing.  (Since sockets and pcbs both now
877  * use TSM, there probably isn't any need for this function to run at
878  * splnet() any more.  This needs more examination.)
879  */
880 int
881 tcp_ctloutput(so, sopt)
882         struct socket *so;
883         struct sockopt *sopt;
884 {
885         int     error, opt, optval, s;
886         struct  inpcb *inp;
887         struct  tcpcb *tp;
888
889         error = 0;
890         s = splnet();           /* XXX */
891         inp = sotoinpcb(so);
892         if (inp == NULL) {
893                 splx(s);
894                 return (ECONNRESET);
895         }
896         if (sopt->sopt_level != IPPROTO_TCP) {
897 #ifdef INET6
898                 if (INP_CHECK_SOCKAF(so, AF_INET6))
899                         error = ip6_ctloutput(so, sopt);
900                 else
901 #endif /* INET6 */
902                 error = ip_ctloutput(so, sopt);
903                 splx(s);
904                 return (error);
905         }
906         tp = intotcpcb(inp);
907
908         switch (sopt->sopt_dir) {
909         case SOPT_SET:
910                 switch (sopt->sopt_name) {
911                 case TCP_NODELAY:
912                 case TCP_NOOPT:
913                         error = sooptcopyin(sopt, &optval, sizeof optval,
914                                             sizeof optval);
915                         if (error)
916                                 break;
917
918                         switch (sopt->sopt_name) {
919                         case TCP_NODELAY:
920                                 opt = TF_NODELAY;
921                                 break;
922                         case TCP_NOOPT:
923                                 opt = TF_NOOPT;
924                                 break;
925                         default:
926                                 opt = 0; /* dead code to fool gcc */
927                                 break;
928                         }
929
930                         if (optval)
931                                 tp->t_flags |= opt;
932                         else
933                                 tp->t_flags &= ~opt;
934                         break;
935
936                 case TCP_NOPUSH:
937                         error = sooptcopyin(sopt, &optval, sizeof optval,
938                                             sizeof optval);
939                         if (error)
940                                 break;
941
942                         if (optval)
943                                 tp->t_flags |= TF_NOPUSH;
944                         else {
945                                 tp->t_flags &= ~TF_NOPUSH;
946                                 error = tcp_output(tp);
947                         }
948                         break;
949
950                 case TCP_MAXSEG:
951                         error = sooptcopyin(sopt, &optval, sizeof optval,
952                                             sizeof optval);
953                         if (error)
954                                 break;
955
956                         if (optval > 0 && optval <= tp->t_maxseg)
957                                 tp->t_maxseg = optval;
958                         else
959                                 error = EINVAL;
960                         break;
961
962                 default:
963                         error = ENOPROTOOPT;
964                         break;
965                 }
966                 break;
967
968         case SOPT_GET:
969                 switch (sopt->sopt_name) {
970                 case TCP_NODELAY:
971                         optval = tp->t_flags & TF_NODELAY;
972                         break;
973                 case TCP_MAXSEG:
974                         optval = tp->t_maxseg;
975                         break;
976                 case TCP_NOOPT:
977                         optval = tp->t_flags & TF_NOOPT;
978                         break;
979                 case TCP_NOPUSH:
980                         optval = tp->t_flags & TF_NOPUSH;
981                         break;
982                 default:
983                         error = ENOPROTOOPT;
984                         break;
985                 }
986                 if (error == 0)
987                         error = sooptcopyout(sopt, &optval, sizeof optval);
988                 break;
989         }
990         splx(s);
991         return (error);
992 }
993
994 /*
995  * tcp_sendspace and tcp_recvspace are the default send and receive window
996  * sizes, respectively.  These are obsolescent (this information should
997  * be set by the route).
998  */
999 u_long  tcp_sendspace = 1024*32;
1000 SYSCTL_INT(_net_inet_tcp, TCPCTL_SENDSPACE, sendspace, CTLFLAG_RW, 
1001     &tcp_sendspace , 0, "Maximum outgoing TCP datagram size");
1002 u_long  tcp_recvspace = 1024*64;
1003 SYSCTL_INT(_net_inet_tcp, TCPCTL_RECVSPACE, recvspace, CTLFLAG_RW, 
1004     &tcp_recvspace , 0, "Maximum incoming TCP datagram size");
1005
1006 /*
1007  * Attach TCP protocol to socket, allocating
1008  * internet protocol control block, tcp control block,
1009  * bufer space, and entering LISTEN state if to accept connections.
1010  */
1011 static int
1012 tcp_attach(so, td)
1013         struct socket *so;
1014         struct thread *td;
1015 {
1016         register struct tcpcb *tp;
1017         struct inpcb *inp;
1018         int error;
1019 #ifdef INET6
1020         int isipv6 = INP_CHECK_SOCKAF(so, AF_INET6) != NULL;
1021 #endif
1022
1023         if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
1024                 error = soreserve(so, tcp_sendspace, tcp_recvspace);
1025                 if (error)
1026                         return (error);
1027         }
1028         error = in_pcballoc(so, &tcbinfo, td);
1029         if (error)
1030                 return (error);
1031         inp = sotoinpcb(so);
1032 #ifdef INET6
1033         if (isipv6) {
1034                 inp->inp_vflag |= INP_IPV6;
1035                 inp->in6p_hops = -1;    /* use kernel default */
1036         }
1037         else
1038 #endif
1039         inp->inp_vflag |= INP_IPV4;
1040         tp = tcp_newtcpcb(inp);
1041         if (tp == 0) {
1042                 int nofd = so->so_state & SS_NOFDREF;   /* XXX */
1043
1044                 so->so_state &= ~SS_NOFDREF;    /* don't free the socket yet */
1045 #ifdef INET6
1046                 if (isipv6)
1047                         in6_pcbdetach(inp);
1048                 else
1049 #endif
1050                 in_pcbdetach(inp);
1051                 so->so_state |= nofd;
1052                 return (ENOBUFS);
1053         }
1054         tp->t_state = TCPS_CLOSED;
1055         return (0);
1056 }
1057
1058 /*
1059  * Initiate (or continue) disconnect.
1060  * If embryonic state, just send reset (once).
1061  * If in ``let data drain'' option and linger null, just drop.
1062  * Otherwise (hard), mark socket disconnecting and drop
1063  * current input data; switch states based on user close, and
1064  * send segment to peer (with FIN).
1065  */
1066 static struct tcpcb *
1067 tcp_disconnect(tp)
1068         register struct tcpcb *tp;
1069 {
1070         struct socket *so = tp->t_inpcb->inp_socket;
1071
1072         if (tp->t_state < TCPS_ESTABLISHED)
1073                 tp = tcp_close(tp);
1074         else if ((so->so_options & SO_LINGER) && so->so_linger == 0)
1075                 tp = tcp_drop(tp, 0);
1076         else {
1077                 soisdisconnecting(so);
1078                 sbflush(&so->so_rcv);
1079                 tp = tcp_usrclosed(tp);
1080                 if (tp)
1081                         (void) tcp_output(tp);
1082         }
1083         return (tp);
1084 }
1085
1086 /*
1087  * User issued close, and wish to trail through shutdown states:
1088  * if never received SYN, just forget it.  If got a SYN from peer,
1089  * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN.
1090  * If already got a FIN from peer, then almost done; go to LAST_ACK
1091  * state.  In all other cases, have already sent FIN to peer (e.g.
1092  * after PRU_SHUTDOWN), and just have to play tedious game waiting
1093  * for peer to send FIN or not respond to keep-alives, etc.
1094  * We can let the user exit from the close as soon as the FIN is acked.
1095  */
1096 static struct tcpcb *
1097 tcp_usrclosed(tp)
1098         register struct tcpcb *tp;
1099 {
1100
1101         switch (tp->t_state) {
1102
1103         case TCPS_CLOSED:
1104         case TCPS_LISTEN:
1105                 tp->t_state = TCPS_CLOSED;
1106                 tp = tcp_close(tp);
1107                 break;
1108
1109         case TCPS_SYN_SENT:
1110         case TCPS_SYN_RECEIVED:
1111                 tp->t_flags |= TF_NEEDFIN;
1112                 break;
1113
1114         case TCPS_ESTABLISHED:
1115                 tp->t_state = TCPS_FIN_WAIT_1;
1116                 break;
1117
1118         case TCPS_CLOSE_WAIT:
1119                 tp->t_state = TCPS_LAST_ACK;
1120                 break;
1121         }
1122         if (tp && tp->t_state >= TCPS_FIN_WAIT_2) {
1123                 soisdisconnected(tp->t_inpcb->inp_socket);
1124                 /* To prevent the connection hanging in FIN_WAIT_2 forever. */
1125                 if (tp->t_state == TCPS_FIN_WAIT_2)
1126                         callout_reset(tp->tt_2msl, tcp_maxidle,
1127                                       tcp_timer_2msl, tp);
1128         }
1129         return (tp);
1130 }
1131