]> git.saurik.com Git - apple/xnu.git/blame - bsd/netinet/tcp_subr.c
xnu-344.21.73.tar.gz
[apple/xnu.git] / bsd / netinet / tcp_subr.c
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
d7e50217 6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
1c79356b 7 *
d7e50217
A
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1c79356b
A
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
d7e50217
A
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
1c79356b
A
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25/*
26 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
27 * The Regents of the University of California. All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 * 1. Redistributions of source code must retain the above copyright
33 * notice, this list of conditions and the following disclaimer.
34 * 2. Redistributions in binary form must reproduce the above copyright
35 * notice, this list of conditions and the following disclaimer in the
36 * documentation and/or other materials provided with the distribution.
37 * 3. All advertising materials mentioning features or use of this software
38 * must display the following acknowledgement:
39 * This product includes software developed by the University of
40 * California, Berkeley and its contributors.
41 * 4. Neither the name of the University nor the names of its contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
44 *
45 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 * SUCH DAMAGE.
56 *
57 * @(#)tcp_subr.c 8.2 (Berkeley) 5/24/95
9bccf70c 58 * $FreeBSD: src/sys/netinet/tcp_subr.c,v 1.73.2.22 2001/08/22 00:59:12 silby Exp $
1c79356b
A
59 */
60
1c79356b
A
61
62#include <sys/param.h>
63#include <sys/systm.h>
9bccf70c 64#include <sys/callout.h>
1c79356b
A
65#include <sys/kernel.h>
66#include <sys/sysctl.h>
67#include <sys/malloc.h>
68#include <sys/mbuf.h>
9bccf70c 69#if INET6
1c79356b 70#include <sys/domain.h>
9bccf70c
A
71#endif
72#include <sys/proc.h>
1c79356b
A
73#include <sys/socket.h>
74#include <sys/socketvar.h>
75#include <sys/protosw.h>
9bccf70c 76#include <sys/random.h>
1c79356b
A
77#include <sys/syslog.h>
78
79
1c79356b
A
80
81#include <net/route.h>
82#include <net/if.h>
83
84#define _IP_VHL
85#include <netinet/in.h>
86#include <netinet/in_systm.h>
87#include <netinet/ip.h>
9bccf70c
A
88#if INET6
89#include <netinet/ip6.h>
90#endif
1c79356b 91#include <netinet/in_pcb.h>
9bccf70c
A
92#if INET6
93#include <netinet6/in6_pcb.h>
94#endif
1c79356b
A
95#include <netinet/in_var.h>
96#include <netinet/ip_var.h>
97#if INET6
1c79356b 98#include <netinet6/ip6_var.h>
1c79356b
A
99#endif
100#include <netinet/tcp.h>
101#include <netinet/tcp_fsm.h>
102#include <netinet/tcp_seq.h>
103#include <netinet/tcp_timer.h>
104#include <netinet/tcp_var.h>
9bccf70c
A
105#if INET6
106#include <netinet6/tcp6_var.h>
107#endif
1c79356b
A
108#include <netinet/tcpip.h>
109#if TCPDEBUG
110#include <netinet/tcp_debug.h>
111#endif
112#include <netinet6/ip6protosw.h>
113
114#if IPSEC
115#include <netinet6/ipsec.h>
9bccf70c
A
116#if INET6
117#include <netinet6/ipsec6.h>
118#endif
1c79356b
A
119#endif /*IPSEC*/
120
9bccf70c 121#include <sys/md5.h>
1c79356b
A
122#include <sys/kdebug.h>
123
124#define DBG_FNC_TCP_CLOSE NETDBG_CODE(DBG_NETTCP, ((5 << 8) | 2))
125
126
9bccf70c
A
127/* temporary: for testing */
128#if IPSEC
129extern int ipsec_bypass;
130#endif
131
1c79356b 132int tcp_mssdflt = TCP_MSS;
9bccf70c
A
133SYSCTL_INT(_net_inet_tcp, TCPCTL_MSSDFLT, mssdflt, CTLFLAG_RW,
134 &tcp_mssdflt , 0, "Default TCP Maximum Segment Size");
1c79356b 135
9bccf70c
A
136#if INET6
137int tcp_v6mssdflt = TCP6_MSS;
1c79356b 138SYSCTL_INT(_net_inet_tcp, TCPCTL_V6MSSDFLT, v6mssdflt,
9bccf70c
A
139 CTLFLAG_RW, &tcp_v6mssdflt , 0,
140 "Default TCP Maximum Segment Size for IPv6");
141#endif
1c79356b
A
142
143static int tcp_do_rfc1323 = 1;
9bccf70c
A
144SYSCTL_INT(_net_inet_tcp, TCPCTL_DO_RFC1323, rfc1323, CTLFLAG_RW,
145 &tcp_do_rfc1323 , 0, "Enable rfc1323 (high performance TCP) extensions");
1c79356b
A
146
147static int tcp_do_rfc1644 = 0;
9bccf70c
A
148SYSCTL_INT(_net_inet_tcp, TCPCTL_DO_RFC1644, rfc1644, CTLFLAG_RW,
149 &tcp_do_rfc1644 , 0, "Enable rfc1644 (TTCP) extensions");
1c79356b 150
9bccf70c
A
151static int tcp_tcbhashsize = 0;
152SYSCTL_INT(_net_inet_tcp, OID_AUTO, tcbhashsize, CTLFLAG_RD,
153 &tcp_tcbhashsize, 0, "Size of TCP control-block hashtable");
1c79356b 154
9bccf70c
A
155static int do_tcpdrain = 1;
156SYSCTL_INT(_net_inet_tcp, OID_AUTO, do_tcpdrain, CTLFLAG_RW, &do_tcpdrain, 0,
157 "Enable tcp_drain routine for extra help when low on mbufs");
1c79356b 158
9bccf70c
A
159SYSCTL_INT(_net_inet_tcp, OID_AUTO, pcbcount, CTLFLAG_RD,
160 &tcbinfo.ipi_count, 0, "Number of active PCBs");
1c79356b 161
9bccf70c
A
162static int icmp_may_rst = 1;
163SYSCTL_INT(_net_inet_tcp, OID_AUTO, icmp_may_rst, CTLFLAG_RW, &icmp_may_rst, 0,
164 "Certain ICMP unreachable messages may abort connections in SYN_SENT");
1c79356b 165
9bccf70c
A
166static int tcp_strict_rfc1948 = 0;
167SYSCTL_INT(_net_inet_tcp, OID_AUTO, strict_rfc1948, CTLFLAG_RW,
168 &tcp_strict_rfc1948, 0, "Determines if RFC1948 is followed exactly");
169
170static int tcp_isn_reseed_interval = 0;
171SYSCTL_INT(_net_inet_tcp, OID_AUTO, isn_reseed_interval, CTLFLAG_RW,
172 &tcp_isn_reseed_interval, 0, "Seconds between reseeding of ISN secret");
173
174static void tcp_cleartaocache __P((void));
175static void tcp_notify __P((struct inpcb *, int));
1c79356b
A
176
177/*
178 * Target size of TCP PCB hash tables. Must be a power of two.
179 *
180 * Note that this can be overridden by the kernel environment
181 * variable net.inet.tcp.tcbhashsize
182 */
183#ifndef TCBHASHSIZE
184#define TCBHASHSIZE 4096
185#endif
186
187/*
188 * This is the actual shape of what we allocate using the zone
189 * allocator. Doing it this way allows us to protect both structures
190 * using the same generation count, and also eliminates the overhead
191 * of allocating tcpcbs separately. By hiding the structure here,
192 * we avoid changing most of the rest of the code (although it needs
193 * to be changed, eventually, for greater efficiency).
194 */
195#define ALIGNMENT 32
196#define ALIGNM1 (ALIGNMENT - 1)
197struct inp_tp {
198 union {
199 struct inpcb inp;
200 char align[(sizeof(struct inpcb) + ALIGNM1) & ~ALIGNM1];
201 } inp_tp_u;
202 struct tcpcb tcb;
9bccf70c
A
203#ifndef __APPLE__
204 struct callout inp_tp_rexmt, inp_tp_persist, inp_tp_keep, inp_tp_2msl;
205 struct callout inp_tp_delack;
206#endif
1c79356b
A
207};
208#undef ALIGNMENT
209#undef ALIGNM1
210
211static struct tcpcb dummy_tcb;
212
213
214extern struct inpcbhead time_wait_slots[];
215extern int cur_tw_slot;
216extern u_long *delack_bitmask;
217
218
219int get_inpcb_str_size()
220{
221 return sizeof(struct inpcb);
222}
223
224
225int get_tcp_str_size()
226{
227 return sizeof(struct tcpcb);
228}
229
230int tcp_freeq __P((struct tcpcb *tp));
231
232
233/*
234 * Tcp initialization
235 */
236void
237tcp_init()
238{
9bccf70c
A
239 int hashsize = TCBHASHSIZE;
240 vm_size_t str_size;
241 int i;
242
1c79356b
A
243 tcp_ccgen = 1;
244 tcp_cleartaocache();
9bccf70c
A
245
246 tcp_delacktime = TCPTV_DELACK;
247 tcp_keepinit = TCPTV_KEEP_INIT;
248 tcp_keepidle = TCPTV_KEEP_IDLE;
249 tcp_keepintvl = TCPTV_KEEPINTVL;
250 tcp_maxpersistidle = TCPTV_KEEP_IDLE;
251 tcp_msl = TCPTV_MSL;
d7e50217
A
252 read_random(&tcp_now, sizeof(tcp_now));
253 tcp_now = tcp_now & 0x7fffffffffffffff; /* Starts tcp internal 500ms clock at a random value */
254
9bccf70c 255
1c79356b
A
256 LIST_INIT(&tcb);
257 tcbinfo.listhead = &tcb;
9bccf70c
A
258#ifndef __APPLE__
259 TUNABLE_INT_FETCH("net.inet.tcp.tcbhashsize", &hashsize);
260#endif
1c79356b
A
261 if (!powerof2(hashsize)) {
262 printf("WARNING: TCB hash size not a power of 2\n");
263 hashsize = 512; /* safe default */
264 }
9bccf70c 265 tcp_tcbhashsize = hashsize;
1c79356b
A
266 tcbinfo.hashsize = hashsize;
267 tcbinfo.hashbase = hashinit(hashsize, M_PCB, &tcbinfo.hashmask);
268 tcbinfo.porthashbase = hashinit(hashsize, M_PCB,
269 &tcbinfo.porthashmask);
9bccf70c 270#ifdef __APPLE__
1c79356b 271 str_size = (vm_size_t) sizeof(struct inp_tp);
9bccf70c
A
272 tcbinfo.ipi_zone = (void *) zinit(str_size, 120000*str_size, 8192, "tcpcb");
273#else
274 tcbinfo.ipi_zone = zinit("tcpcb", sizeof(struct inp_tp), maxsockets,
275 ZONE_INTERRUPT, 0);
1c79356b
A
276#endif
277#if INET6
9bccf70c 278#define TCP_MINPROTOHDR (sizeof(struct ip6_hdr) + sizeof(struct tcphdr))
1c79356b 279#else /* INET6 */
9bccf70c 280#define TCP_MINPROTOHDR (sizeof(struct tcpiphdr))
1c79356b 281#endif /* INET6 */
9bccf70c
A
282 if (max_protohdr < TCP_MINPROTOHDR)
283 max_protohdr = TCP_MINPROTOHDR;
284 if (max_linkhdr + TCP_MINPROTOHDR > MHLEN)
1c79356b 285 panic("tcp_init");
9bccf70c 286#undef TCP_MINPROTOHDR
1c79356b
A
287 tcbinfo.last_pcb = 0;
288 dummy_tcb.t_state = TCP_NSTATES;
289 dummy_tcb.t_flags = 0;
290 tcbinfo.dummy_cb = (caddr_t) &dummy_tcb;
291 in_pcb_nat_init(&tcbinfo, AF_INET, IPPROTO_TCP, SOCK_STREAM);
292
0b4e3aa0 293 delack_bitmask = _MALLOC((4 * hashsize)/32, M_PCB, M_WAITOK);
1c79356b
A
294 if (delack_bitmask == 0)
295 panic("Delack Memory");
296
297 for (i=0; i < (tcbinfo.hashsize / 32); i++)
298 delack_bitmask[i] = 0;
299
300 for (i=0; i < N_TIME_WAIT_SLOTS; i++) {
301 LIST_INIT(&time_wait_slots[i]);
302 }
9bccf70c
A
303}
304
305/*
306 * Fill in the IP and TCP headers for an outgoing packet, given the tcpcb.
307 * tcp_template used to store this data in mbufs, but we now recopy it out
308 * of the tcpcb each time to conserve mbufs.
309 */
310void
311tcp_fillheaders(tp, ip_ptr, tcp_ptr)
312 struct tcpcb *tp;
313 void *ip_ptr;
314 void *tcp_ptr;
315{
316 struct inpcb *inp = tp->t_inpcb;
317 struct tcphdr *tcp_hdr = (struct tcphdr *)tcp_ptr;
318
319#if INET6
320 if ((inp->inp_vflag & INP_IPV6) != 0) {
321 struct ip6_hdr *ip6;
322
323 ip6 = (struct ip6_hdr *)ip_ptr;
324 ip6->ip6_flow = (ip6->ip6_flow & ~IPV6_FLOWINFO_MASK) |
325 (inp->in6p_flowinfo & IPV6_FLOWINFO_MASK);
326 ip6->ip6_vfc = (ip6->ip6_vfc & ~IPV6_VERSION_MASK) |
327 (IPV6_VERSION & IPV6_VERSION_MASK);
328 ip6->ip6_nxt = IPPROTO_TCP;
329 ip6->ip6_plen = sizeof(struct tcphdr);
330 ip6->ip6_src = inp->in6p_laddr;
331 ip6->ip6_dst = inp->in6p_faddr;
332 tcp_hdr->th_sum = 0;
333 } else
334#endif
335 {
336 struct ip *ip = (struct ip *) ip_ptr;
337
338 ip->ip_vhl = IP_VHL_BORING;
339 ip->ip_tos = 0;
340 ip->ip_len = 0;
341 ip->ip_id = 0;
342 ip->ip_off = 0;
343 ip->ip_ttl = 0;
344 ip->ip_sum = 0;
345 ip->ip_p = IPPROTO_TCP;
346 ip->ip_src = inp->inp_laddr;
347 ip->ip_dst = inp->inp_faddr;
348 tcp_hdr->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr,
349 htons(sizeof(struct tcphdr) + IPPROTO_TCP));
350 }
351
352 tcp_hdr->th_sport = inp->inp_lport;
353 tcp_hdr->th_dport = inp->inp_fport;
354 tcp_hdr->th_seq = 0;
355 tcp_hdr->th_ack = 0;
356 tcp_hdr->th_x2 = 0;
357 tcp_hdr->th_off = 5;
358 tcp_hdr->th_flags = 0;
359 tcp_hdr->th_win = 0;
360 tcp_hdr->th_urp = 0;
1c79356b
A
361}
362
363/*
364 * Create template to be used to send tcp packets on a connection.
9bccf70c
A
365 * Allocates an mbuf and fills in a skeletal tcp/ip header. The only
366 * use for this function is in keepalives, which use tcp_respond.
1c79356b
A
367 */
368struct tcptemp *
9bccf70c 369tcp_maketemplate(tp)
1c79356b
A
370 struct tcpcb *tp;
371{
9bccf70c
A
372 struct mbuf *m;
373 struct tcptemp *n;
1c79356b 374
9bccf70c
A
375 m = m_get(M_DONTWAIT, MT_HEADER);
376 if (m == NULL)
377 return (0);
378 m->m_len = sizeof(struct tcptemp);
379 n = mtod(m, struct tcptemp *);
0b4e3aa0 380
9bccf70c 381 tcp_fillheaders(tp, (void *)&n->tt_ipgen, (void *)&n->tt_t);
1c79356b
A
382 return (n);
383}
384
385/*
386 * Send a single message to the TCP at address specified by
387 * the given TCP/IP header. If m == 0, then we make a copy
388 * of the tcpiphdr at ti and send directly to the addressed host.
389 * This is used to force keep alive messages out using the TCP
9bccf70c
A
390 * template for a connection. If flags are given then we send
391 * a message back to the TCP which originated the * segment ti,
392 * and discard the mbuf containing it and any other attached mbufs.
1c79356b
A
393 *
394 * In any case the ack and sequence number of the transmitted
395 * segment are as specified by the parameters.
396 *
397 * NOTE: If m != NULL, then ti must point to *inside* the mbuf.
398 */
399void
9bccf70c 400tcp_respond(tp, ipgen, th, m, ack, seq, flags)
1c79356b 401 struct tcpcb *tp;
9bccf70c 402 void *ipgen;
1c79356b
A
403 register struct tcphdr *th;
404 register struct mbuf *m;
405 tcp_seq ack, seq;
406 int flags;
1c79356b
A
407{
408 register int tlen;
409 int win = 0;
410 struct route *ro = 0;
411 struct route sro;
9bccf70c 412 struct ip *ip;
1c79356b
A
413 struct tcphdr *nth;
414#if INET6
415 struct route_in6 *ro6 = 0;
416 struct route_in6 sro6;
9bccf70c
A
417 struct ip6_hdr *ip6;
418 int isipv6;
1c79356b 419#endif /* INET6 */
9bccf70c
A
420 int ipflags = 0;
421
422#if INET6
423 isipv6 = IP_VHL_V(((struct ip *)ipgen)->ip_vhl) == 6;
424 ip6 = ipgen;
425#endif /* INET6 */
426 ip = ipgen;
1c79356b
A
427
428 if (tp) {
9bccf70c 429 if (!(flags & TH_RST)) {
1c79356b 430 win = sbspace(&tp->t_inpcb->inp_socket->so_rcv);
9bccf70c
A
431 if (win > (long)TCP_MAXWIN << tp->rcv_scale)
432 win = (long)TCP_MAXWIN << tp->rcv_scale;
433 }
1c79356b
A
434#if INET6
435 if (isipv6)
436 ro6 = &tp->t_inpcb->in6p_route;
437 else
438#endif /* INET6 */
439 ro = &tp->t_inpcb->inp_route;
440 } else {
441#if INET6
442 if (isipv6) {
443 ro6 = &sro6;
444 bzero(ro6, sizeof *ro6);
9bccf70c 445 } else
1c79356b 446#endif /* INET6 */
9bccf70c
A
447 {
448 ro = &sro;
449 bzero(ro, sizeof *ro);
1c79356b 450 }
1c79356b
A
451 }
452 if (m == 0) {
453 m = m_gethdr(M_DONTWAIT, MT_HEADER);
454 if (m == NULL)
455 return;
1c79356b 456 tlen = 0;
1c79356b
A
457 m->m_data += max_linkhdr;
458#if INET6
459 if (isipv6) {
9bccf70c 460 bcopy((caddr_t)ip6, mtod(m, caddr_t),
1c79356b 461 sizeof(struct ip6_hdr));
9bccf70c
A
462 ip6 = mtod(m, struct ip6_hdr *);
463 nth = (struct tcphdr *)(ip6 + 1);
464 } else
1c79356b 465#endif /* INET6 */
9bccf70c
A
466 {
467 bcopy((caddr_t)ip, mtod(m, caddr_t), sizeof(struct ip));
468 ip = mtod(m, struct ip *);
469 nth = (struct tcphdr *)(ip + 1);
1c79356b 470 }
1c79356b
A
471 bcopy((caddr_t)th, (caddr_t)nth, sizeof(struct tcphdr));
472 flags = TH_ACK;
473 } else {
474 m_freem(m->m_next);
475 m->m_next = 0;
9bccf70c 476 m->m_data = (caddr_t)ipgen;
1c79356b
A
477 /* m_len is set later */
478 tlen = 0;
479#define xchg(a,b,type) { type t; t=a; a=b; b=t; }
480#if INET6
481 if (isipv6) {
9bccf70c 482 xchg(ip6->ip6_dst, ip6->ip6_src, struct in6_addr);
1c79356b 483 nth = (struct tcphdr *)(ip6 + 1);
9bccf70c 484 } else
1c79356b 485#endif /* INET6 */
9bccf70c
A
486 {
487 xchg(ip->ip_dst.s_addr, ip->ip_src.s_addr, n_long);
488 nth = (struct tcphdr *)(ip + 1);
489 }
490 if (th != nth) {
491 /*
492 * this is usually a case when an extension header
493 * exists between the IPv6 header and the
494 * TCP header.
495 */
496 nth->th_sport = th->th_sport;
497 nth->th_dport = th->th_dport;
1c79356b 498 }
1c79356b
A
499 xchg(nth->th_dport, nth->th_sport, n_short);
500#undef xchg
501 }
9bccf70c
A
502#if INET6
503 if (isipv6) {
504 ip6->ip6_plen = htons((u_short)(sizeof (struct tcphdr) +
505 tlen));
506 tlen += sizeof (struct ip6_hdr) + sizeof (struct tcphdr);
507 } else
508#endif
509 {
510 tlen += sizeof (struct tcpiphdr);
511 ip->ip_len = tlen;
512 ip->ip_ttl = ip_defttl;
513 }
514 m->m_len = tlen;
515 m->m_pkthdr.len = tlen;
516 m->m_pkthdr.rcvif = (struct ifnet *) 0;
1c79356b
A
517 nth->th_seq = htonl(seq);
518 nth->th_ack = htonl(ack);
519 nth->th_x2 = 0;
520 nth->th_off = sizeof (struct tcphdr) >> 2;
521 nth->th_flags = flags;
522 if (tp)
523 nth->th_win = htons((u_short) (win >> tp->rcv_scale));
524 else
525 nth->th_win = htons((u_short)win);
526 nth->th_urp = 0;
1c79356b
A
527#if INET6
528 if (isipv6) {
9bccf70c
A
529 nth->th_sum = 0;
530 nth->th_sum = in6_cksum(m, IPPROTO_TCP,
531 sizeof(struct ip6_hdr),
532 tlen - sizeof(struct ip6_hdr));
1c79356b
A
533 ip6->ip6_hlim = in6_selecthlim(tp ? tp->t_inpcb : NULL,
534 ro6 && ro6->ro_rt ?
535 ro6->ro_rt->rt_ifp :
536 NULL);
9bccf70c 537 } else
1c79356b 538#endif /* INET6 */
9bccf70c
A
539 {
540 nth->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr,
541 htons((u_short)(tlen - sizeof(struct ip) + ip->ip_p)));
542 m->m_pkthdr.csum_flags = CSUM_TCP;
543 m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum);
1c79356b 544 }
1c79356b
A
545#if TCPDEBUG
546 if (tp == NULL || (tp->t_inpcb->inp_socket->so_options & SO_DEBUG))
9bccf70c 547 tcp_trace(TA_OUTPUT, 0, tp, mtod(m, void *), th, 0);
1c79356b
A
548#endif
549#if IPSEC
9bccf70c
A
550 if (ipsec_bypass == 0 && ipsec_setsocket(m, tp ? tp->t_inpcb->inp_socket : NULL) != 0) {
551 m_freem(m);
552 return;
553 }
554#endif
1c79356b
A
555#if INET6
556 if (isipv6) {
9bccf70c
A
557 (void)ip6_output(m, NULL, ro6, ipflags, NULL, NULL);
558 if (ro6 == &sro6 && ro6->ro_rt) {
559 rtfree(ro6->ro_rt);
560 ro6->ro_rt = NULL;
561 }
562 } else
1c79356b 563#endif /* INET6 */
9bccf70c
A
564 {
565 (void) ip_output(m, NULL, ro, ipflags, NULL);
566 if (ro == &sro && ro->ro_rt) {
567 rtfree(ro->ro_rt);
568 ro->ro_rt = NULL;
569 }
1c79356b 570 }
1c79356b
A
571}
572
573/*
574 * Create a new TCP control block, making an
575 * empty reassembly queue and hooking it to the argument
576 * protocol control block. The `inp' parameter must have
577 * come from the zone allocator set up in tcp_init().
578 */
579struct tcpcb *
580tcp_newtcpcb(inp)
581 struct inpcb *inp;
582{
583 struct inp_tp *it;
584 register struct tcpcb *tp;
585 register struct socket *so = inp->inp_socket;
586#if INET6
9bccf70c 587 int isipv6 = (inp->inp_vflag & INP_IPV6) != 0;
1c79356b
A
588#endif /* INET6 */
589
1c79356b
A
590 if (so->cached_in_sock_layer == 0) {
591 it = (struct inp_tp *)inp;
592 tp = &it->tcb;
593 }
594 else
595 tp = (struct tcpcb *) inp->inp_saved_ppcb;
596
597 bzero((char *) tp, sizeof(struct tcpcb));
9bccf70c
A
598 LIST_INIT(&tp->t_segq);
599 tp->t_maxseg = tp->t_maxopd =
1c79356b 600#if INET6
9bccf70c 601 isipv6 ? tcp_v6mssdflt :
1c79356b 602#endif /* INET6 */
9bccf70c
A
603 tcp_mssdflt;
604
605#ifndef __APPLE__
606 /* Set up our timeouts. */
607 callout_init(tp->tt_rexmt = &it->inp_tp_rexmt);
608 callout_init(tp->tt_persist = &it->inp_tp_persist);
609 callout_init(tp->tt_keep = &it->inp_tp_keep);
610 callout_init(tp->tt_2msl = &it->inp_tp_2msl);
611 callout_init(tp->tt_delack = &it->inp_tp_delack);
612#endif
1c79356b
A
613
614 if (tcp_do_rfc1323)
615 tp->t_flags = (TF_REQ_SCALE|TF_REQ_TSTMP);
616 if (tcp_do_rfc1644)
617 tp->t_flags |= TF_REQ_CC;
618 tp->t_inpcb = inp; /* XXX */
619 /*
620 * Init srtt to TCPTV_SRTTBASE (0), so we can tell that we have no
621 * rtt estimate. Set rttvar so that srtt + 4 * rttvar gives
622 * reasonable initial retransmit time.
623 */
624 tp->t_srtt = TCPTV_SRTTBASE;
625 tp->t_rttvar = ((TCPTV_RTOBASE - TCPTV_SRTTBASE) << TCP_RTTVAR_SHIFT) / 4;
626 tp->t_rttmin = TCPTV_MIN;
627 tp->t_rxtcur = TCPTV_RTOBASE;
628 tp->snd_cwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT;
629 tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT;
9bccf70c 630 /*
1c79356b
A
631 * IPv4 TTL initialization is necessary for an IPv6 socket as well,
632 * because the socket may be bound to an IPv6 wildcard address,
633 * which may match an IPv4-mapped IPv6 address.
1c79356b
A
634 */
635 inp->inp_ip_ttl = ip_defttl;
636 inp->inp_ppcb = (caddr_t)tp;
637 return (tp); /* XXX */
638}
639
640/*
641 * Drop a TCP connection, reporting
642 * the specified error. If connection is synchronized,
643 * then send a RST to peer.
644 */
645struct tcpcb *
646tcp_drop(tp, errno)
647 register struct tcpcb *tp;
648 int errno;
649{
650 struct socket *so = tp->t_inpcb->inp_socket;
651
9bccf70c 652#ifdef __APPLE__
1c79356b
A
653 switch (tp->t_state)
654 {
655 case TCPS_ESTABLISHED:
656 case TCPS_FIN_WAIT_1:
657 case TCPS_CLOSING:
658 case TCPS_CLOSE_WAIT:
659 case TCPS_LAST_ACK:
1c79356b
A
660 break;
661 }
9bccf70c
A
662#endif
663
1c79356b
A
664 if (TCPS_HAVERCVDSYN(tp->t_state)) {
665 tp->t_state = TCPS_CLOSED;
666 (void) tcp_output(tp);
667 tcpstat.tcps_drops++;
668 } else
669 tcpstat.tcps_conndrops++;
670 if (errno == ETIMEDOUT && tp->t_softerror)
671 errno = tp->t_softerror;
672 so->so_error = errno;
673 return (tcp_close(tp));
674}
675
676/*
677 * Close a TCP control block:
678 * discard all space held by the tcp
679 * discard internet protocol block
680 * wake up any sleepers
681 */
682struct tcpcb *
683tcp_close(tp)
684 register struct tcpcb *tp;
685{
9bccf70c 686 register struct tseg_qent *q;
1c79356b
A
687 struct inpcb *inp = tp->t_inpcb;
688 struct socket *so = inp->inp_socket;
689#if INET6
9bccf70c 690 int isipv6 = (inp->inp_vflag & INP_IPV6) != 0;
1c79356b
A
691#endif /* INET6 */
692 register struct rtentry *rt;
693 int dosavessthresh;
694
9bccf70c
A
695#ifndef __APPLE__
696 /*
697 * Make sure that all of our timers are stopped before we
698 * delete the PCB.
699 */
700 callout_stop(tp->tt_rexmt);
701 callout_stop(tp->tt_persist);
702 callout_stop(tp->tt_keep);
703 callout_stop(tp->tt_2msl);
704 callout_stop(tp->tt_delack);
705#endif
1c79356b
A
706
707 KERNEL_DEBUG(DBG_FNC_TCP_CLOSE | DBG_FUNC_START, tp,0,0,0,0);
708 switch (tp->t_state)
709 {
710 case TCPS_ESTABLISHED:
711 case TCPS_FIN_WAIT_1:
712 case TCPS_CLOSING:
713 case TCPS_CLOSE_WAIT:
714 case TCPS_LAST_ACK:
1c79356b
A
715 break;
716 }
717
718
719 /*
720 * If we got enough samples through the srtt filter,
721 * save the rtt and rttvar in the routing entry.
722 * 'Enough' is arbitrarily defined as the 16 samples.
723 * 16 samples is enough for the srtt filter to converge
724 * to within 5% of the correct value; fewer samples and
725 * we could save a very bogus rtt.
726 *
727 * Don't update the default route's characteristics and don't
728 * update anything that the user "locked".
729 */
730 if (tp->t_rttupdated >= 16) {
731 register u_long i = 0;
732#if INET6
733 if (isipv6) {
734 struct sockaddr_in6 *sin6;
735
736 if ((rt = inp->in6p_route.ro_rt) == NULL)
737 goto no_valid_rt;
738 sin6 = (struct sockaddr_in6 *)rt_key(rt);
739 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
740 goto no_valid_rt;
741 }
742 else
743#endif /* INET6 */
744 if ((rt = inp->inp_route.ro_rt) == NULL ||
745 ((struct sockaddr_in *)rt_key(rt))->sin_addr.s_addr
746 == INADDR_ANY)
747 goto no_valid_rt;
748
749 if ((rt->rt_rmx.rmx_locks & RTV_RTT) == 0) {
750 i = tp->t_srtt *
751 (RTM_RTTUNIT / (PR_SLOWHZ * TCP_RTT_SCALE));
752 if (rt->rt_rmx.rmx_rtt && i)
753 /*
754 * filter this update to half the old & half
755 * the new values, converting scale.
756 * See route.h and tcp_var.h for a
757 * description of the scaling constants.
758 */
759 rt->rt_rmx.rmx_rtt =
760 (rt->rt_rmx.rmx_rtt + i) / 2;
761 else
762 rt->rt_rmx.rmx_rtt = i;
763 tcpstat.tcps_cachedrtt++;
764 }
765 if ((rt->rt_rmx.rmx_locks & RTV_RTTVAR) == 0) {
766 i = tp->t_rttvar *
767 (RTM_RTTUNIT / (PR_SLOWHZ * TCP_RTTVAR_SCALE));
768 if (rt->rt_rmx.rmx_rttvar && i)
769 rt->rt_rmx.rmx_rttvar =
770 (rt->rt_rmx.rmx_rttvar + i) / 2;
771 else
772 rt->rt_rmx.rmx_rttvar = i;
773 tcpstat.tcps_cachedrttvar++;
774 }
775 /*
776 * The old comment here said:
777 * update the pipelimit (ssthresh) if it has been updated
778 * already or if a pipesize was specified & the threshhold
779 * got below half the pipesize. I.e., wait for bad news
780 * before we start updating, then update on both good
781 * and bad news.
782 *
783 * But we want to save the ssthresh even if no pipesize is
784 * specified explicitly in the route, because such
785 * connections still have an implicit pipesize specified
786 * by the global tcp_sendspace. In the absence of a reliable
787 * way to calculate the pipesize, it will have to do.
788 */
789 i = tp->snd_ssthresh;
790 if (rt->rt_rmx.rmx_sendpipe != 0)
791 dosavessthresh = (i < rt->rt_rmx.rmx_sendpipe / 2);
792 else
793 dosavessthresh = (i < so->so_snd.sb_hiwat / 2);
794 if (((rt->rt_rmx.rmx_locks & RTV_SSTHRESH) == 0 &&
795 i != 0 && rt->rt_rmx.rmx_ssthresh != 0)
796 || dosavessthresh) {
797 /*
798 * convert the limit from user data bytes to
799 * packets then to packet data bytes.
800 */
801 i = (i + tp->t_maxseg / 2) / tp->t_maxseg;
802 if (i < 2)
803 i = 2;
804 i *= (u_long)(tp->t_maxseg +
805#if INET6
9bccf70c
A
806 (isipv6 ? sizeof (struct ip6_hdr) +
807 sizeof (struct tcphdr) :
808#endif
809 sizeof (struct tcpiphdr)
810#if INET6
811 )
812#endif
813 );
1c79356b
A
814 if (rt->rt_rmx.rmx_ssthresh)
815 rt->rt_rmx.rmx_ssthresh =
816 (rt->rt_rmx.rmx_ssthresh + i) / 2;
817 else
818 rt->rt_rmx.rmx_ssthresh = i;
819 tcpstat.tcps_cachedssthresh++;
820 }
821 }
9bccf70c
A
822 rt = inp->inp_route.ro_rt;
823 if (rt) {
824 /*
825 * mark route for deletion if no information is
826 * cached.
827 */
828 if ((tp->t_flags & TF_LQ_OVERFLOW) &&
829 ((rt->rt_rmx.rmx_locks & RTV_RTT) == 0)){
830 if (rt->rt_rmx.rmx_rtt == 0)
831 rt->rt_flags |= RTF_DELCLONE;
832 }
833 }
1c79356b
A
834 no_valid_rt:
835 /* free the reassembly queue, if any */
836 (void) tcp_freeq(tp);
837
9bccf70c 838#ifdef __APPLE__
1c79356b
A
839 if (so->cached_in_sock_layer)
840 inp->inp_saved_ppcb = (caddr_t) tp;
9bccf70c 841#endif
1c79356b
A
842
843 inp->inp_ppcb = NULL;
844 soisdisconnected(so);
845#if INET6
9bccf70c 846 if (INP_CHECK_SOCKAF(so, AF_INET6))
1c79356b
A
847 in6_pcbdetach(inp);
848 else
849#endif /* INET6 */
850 in_pcbdetach(inp);
851 tcpstat.tcps_closed++;
852 KERNEL_DEBUG(DBG_FNC_TCP_CLOSE | DBG_FUNC_END, tcpstat.tcps_closed,0,0,0,0);
853 return ((struct tcpcb *)0);
854}
855
856int
857tcp_freeq(tp)
858 struct tcpcb *tp;
859{
9bccf70c
A
860
861 register struct tseg_qent *q;
1c79356b
A
862 int rv = 0;
863
9bccf70c
A
864 while((q = LIST_FIRST(&tp->t_segq)) != NULL) {
865 LIST_REMOVE(q, tqe_q);
866 m_freem(q->tqe_m);
867 FREE(q, M_TSEGQ);
1c79356b
A
868 rv = 1;
869 }
870 return (rv);
871}
872
873void
874tcp_drain()
875{
9bccf70c
A
876 if (do_tcpdrain)
877 {
878 struct inpcb *inpb;
879 struct tcpcb *tcpb;
880 struct tseg_qent *te;
881
882 /*
883 * Walk the tcpbs, if existing, and flush the reassembly queue,
884 * if there is one...
885 * XXX: The "Net/3" implementation doesn't imply that the TCP
886 * reassembly queue should be flushed, but in a situation
887 * where we're really low on mbufs, this is potentially
888 * usefull.
889 */
890 for (inpb = LIST_FIRST(tcbinfo.listhead); inpb;
891 inpb = LIST_NEXT(inpb, inp_list)) {
892 if ((tcpb = intotcpcb(inpb))) {
893 while ((te = LIST_FIRST(&tcpb->t_segq))
894 != NULL) {
895 LIST_REMOVE(te, tqe_q);
896 m_freem(te->tqe_m);
897 FREE(te, M_TSEGQ);
898 }
899 }
900 }
1c79356b 901
9bccf70c 902 }
1c79356b
A
903}
904
905/*
906 * Notify a tcp user of an asynchronous error;
907 * store error as soft error, but wake up user
908 * (for now, won't do anything until can select for soft error).
9bccf70c
A
909 *
910 * Do not wake up user since there currently is no mechanism for
911 * reporting soft errors (yet - a kqueue filter may be added).
1c79356b
A
912 */
913static void
914tcp_notify(inp, error)
915 struct inpcb *inp;
916 int error;
917{
9bccf70c 918 struct tcpcb *tp = (struct tcpcb *)inp->inp_ppcb;
1c79356b
A
919
920 /*
921 * Ignore some errors if we are hooked up.
922 * If connection hasn't completed, has retransmitted several times,
923 * and receives a second error, give up now. This is better
924 * than waiting a long time to establish a connection that
925 * can never complete.
926 */
927 if (tp->t_state == TCPS_ESTABLISHED &&
928 (error == EHOSTUNREACH || error == ENETUNREACH ||
929 error == EHOSTDOWN)) {
930 return;
931 } else if (tp->t_state < TCPS_ESTABLISHED && tp->t_rxtshift > 3 &&
932 tp->t_softerror)
9bccf70c 933 tcp_drop(tp, error);
1c79356b
A
934 else
935 tp->t_softerror = error;
9bccf70c 936#if 0
1c79356b
A
937 wakeup((caddr_t) &so->so_timeo);
938 sorwakeup(so);
939 sowwakeup(so);
9bccf70c 940#endif
1c79356b
A
941}
942
1c79356b
A
943static int
944tcp_pcblist SYSCTL_HANDLER_ARGS
945{
946 int error, i, n, s;
947 struct inpcb *inp, **inp_list;
948 inp_gen_t gencnt;
949 struct xinpgen xig;
950
951 /*
952 * The process of preparing the TCB list is too time-consuming and
953 * resource-intensive to repeat twice on every request.
954 */
955 if (req->oldptr == 0) {
956 n = tcbinfo.ipi_count;
957 req->oldidx = 2 * (sizeof xig)
958 + (n + n/8) * sizeof(struct xtcpcb);
959 return 0;
960 }
961
962 if (req->newptr != 0)
963 return EPERM;
964
965 /*
966 * OK, now we're committed to doing something.
967 */
968 s = splnet();
969 gencnt = tcbinfo.ipi_gencnt;
970 n = tcbinfo.ipi_count;
971 splx(s);
972
973 xig.xig_len = sizeof xig;
974 xig.xig_count = n;
975 xig.xig_gen = gencnt;
976 xig.xig_sogen = so_gencnt;
977 error = SYSCTL_OUT(req, &xig, sizeof xig);
978 if (error)
979 return error;
0b4e3aa0
A
980 /*
981 * We are done if there is no pcb
982 */
983 if (n == 0)
984 return 0;
1c79356b
A
985
986 inp_list = _MALLOC(n * sizeof *inp_list, M_TEMP, M_WAITOK);
987 if (inp_list == 0)
988 return ENOMEM;
989
990 s = splnet();
9bccf70c
A
991 for (inp = LIST_FIRST(tcbinfo.listhead), i = 0; inp && i < n;
992 inp = LIST_NEXT(inp, inp_list)) {
993#ifdef __APPLE__
1c79356b 994 if (inp->inp_gencnt <= gencnt)
9bccf70c
A
995#else
996 if (inp->inp_gencnt <= gencnt && !prison_xinpcb(req->p, inp))
997#endif
1c79356b
A
998 inp_list[i++] = inp;
999 }
1000 splx(s);
1001 n = i;
1002
1003 error = 0;
1004 for (i = 0; i < n; i++) {
1005 inp = inp_list[i];
1006 if (inp->inp_gencnt <= gencnt) {
1007 struct xtcpcb xt;
9bccf70c 1008 caddr_t inp_ppcb;
1c79356b
A
1009 xt.xt_len = sizeof xt;
1010 /* XXX should avoid extra copy */
1011 bcopy(inp, &xt.xt_inp, sizeof *inp);
9bccf70c
A
1012 inp_ppcb = inp->inp_ppcb;
1013 if (inp_ppcb != NULL)
1014 bcopy(inp_ppcb, &xt.xt_tp, sizeof xt.xt_tp);
1015 else
1016 bzero((char *) &xt.xt_tp, sizeof xt.xt_tp);
1c79356b
A
1017 if (inp->inp_socket)
1018 sotoxsocket(inp->inp_socket, &xt.xt_socket);
1019 error = SYSCTL_OUT(req, &xt, sizeof xt);
1020 }
1021 }
1022 if (!error) {
1023 /*
1024 * Give the user an updated idea of our state.
1025 * If the generation differs from what we told
1026 * her before, she knows that something happened
1027 * while we were processing this request, and it
1028 * might be necessary to retry.
1029 */
1030 s = splnet();
1031 xig.xig_gen = tcbinfo.ipi_gencnt;
1032 xig.xig_sogen = so_gencnt;
1033 xig.xig_count = tcbinfo.ipi_count;
1034 splx(s);
1035 error = SYSCTL_OUT(req, &xig, sizeof xig);
1036 }
1037 FREE(inp_list, M_TEMP);
1038 return error;
1039}
1040
1c79356b
A
1041SYSCTL_PROC(_net_inet_tcp, TCPCTL_PCBLIST, pcblist, CTLFLAG_RD, 0, 0,
1042 tcp_pcblist, "S,xtcpcb", "List of active TCP connections");
1043
9bccf70c
A
1044#ifndef __APPLE__
1045static int
1046tcp_getcred(SYSCTL_HANDLER_ARGS)
1047{
1048 struct sockaddr_in addrs[2];
1049 struct inpcb *inp;
1050 int error, s;
1051
1052 error = suser(req->p);
1053 if (error)
1054 return (error);
1055 error = SYSCTL_IN(req, addrs, sizeof(addrs));
1056 if (error)
1057 return (error);
1058 s = splnet();
1059 inp = in_pcblookup_hash(&tcbinfo, addrs[1].sin_addr, addrs[1].sin_port,
1060 addrs[0].sin_addr, addrs[0].sin_port, 0, NULL);
1061 if (inp == NULL || inp->inp_socket == NULL) {
1062 error = ENOENT;
1063 goto out;
1064 }
1065 error = SYSCTL_OUT(req, inp->inp_socket->so_cred, sizeof(struct ucred));
1066out:
1067 splx(s);
1068 return (error);
1069}
1070
1071SYSCTL_PROC(_net_inet_tcp, OID_AUTO, getcred, CTLTYPE_OPAQUE|CTLFLAG_RW,
1072 0, 0, tcp_getcred, "S,ucred", "Get the ucred of a TCP connection");
1073
1074#if INET6
1075static int
1076tcp6_getcred(SYSCTL_HANDLER_ARGS)
1077{
1078 struct sockaddr_in6 addrs[2];
1079 struct inpcb *inp;
1080 int error, s, mapped = 0;
1081
1082 error = suser(req->p);
1083 if (error)
1084 return (error);
1085 error = SYSCTL_IN(req, addrs, sizeof(addrs));
1086 if (error)
1087 return (error);
1088 if (IN6_IS_ADDR_V4MAPPED(&addrs[0].sin6_addr)) {
1089 if (IN6_IS_ADDR_V4MAPPED(&addrs[1].sin6_addr))
1090 mapped = 1;
1091 else
1092 return (EINVAL);
1093 }
1094 s = splnet();
1095 if (mapped == 1)
1096 inp = in_pcblookup_hash(&tcbinfo,
1097 *(struct in_addr *)&addrs[1].sin6_addr.s6_addr[12],
1098 addrs[1].sin6_port,
1099 *(struct in_addr *)&addrs[0].sin6_addr.s6_addr[12],
1100 addrs[0].sin6_port,
1101 0, NULL);
1102 else
1103 inp = in6_pcblookup_hash(&tcbinfo, &addrs[1].sin6_addr,
1104 addrs[1].sin6_port,
1105 &addrs[0].sin6_addr, addrs[0].sin6_port,
1106 0, NULL);
1107 if (inp == NULL || inp->inp_socket == NULL) {
1108 error = ENOENT;
1109 goto out;
1110 }
1111 error = SYSCTL_OUT(req, inp->inp_socket->so_cred,
1112 sizeof(struct ucred));
1113out:
1114 splx(s);
1115 return (error);
1116}
1117
1118SYSCTL_PROC(_net_inet6_tcp6, OID_AUTO, getcred, CTLTYPE_OPAQUE|CTLFLAG_RW,
1119 0, 0,
1120 tcp6_getcred, "S,ucred", "Get the ucred of a TCP6 connection");
1121#endif
1122#endif /* __APPLE__*/
1123
1c79356b
A
1124void
1125tcp_ctlinput(cmd, sa, vip)
1126 int cmd;
1127 struct sockaddr *sa;
1128 void *vip;
1129{
9bccf70c
A
1130 struct ip *ip = vip;
1131 struct tcphdr *th;
1132 struct in_addr faddr;
1133 struct inpcb *inp;
1134 struct tcpcb *tp;
1c79356b 1135 void (*notify) __P((struct inpcb *, int)) = tcp_notify;
9bccf70c
A
1136 tcp_seq icmp_seq;
1137 int s;
1138
1139 faddr = ((struct sockaddr_in *)sa)->sin_addr;
1140 if (sa->sa_family != AF_INET || faddr.s_addr == INADDR_ANY)
1141 return;
1c79356b
A
1142
1143 if (cmd == PRC_QUENCH)
1144 notify = tcp_quench;
9bccf70c
A
1145 else if (icmp_may_rst && (cmd == PRC_UNREACH_ADMIN_PROHIB ||
1146 cmd == PRC_UNREACH_PORT) && ip)
1147 notify = tcp_drop_syn_sent;
1c79356b
A
1148 else if (cmd == PRC_MSGSIZE)
1149 notify = tcp_mtudisc;
9bccf70c
A
1150 else if (PRC_IS_REDIRECT(cmd)) {
1151 ip = 0;
1152 notify = in_rtchange;
1153 } else if (cmd == PRC_HOSTDEAD)
1154 ip = 0;
1155 else if ((unsigned)cmd > PRC_NCMDS || inetctlerrmap[cmd] == 0)
1c79356b
A
1156 return;
1157 if (ip) {
9bccf70c 1158 s = splnet();
1c79356b
A
1159 th = (struct tcphdr *)((caddr_t)ip
1160 + (IP_VHL_HL(ip->ip_vhl) << 2));
9bccf70c
A
1161 inp = in_pcblookup_hash(&tcbinfo, faddr, th->th_dport,
1162 ip->ip_src, th->th_sport, 0, NULL);
1163 if (inp != NULL && inp->inp_socket != NULL) {
1164 icmp_seq = htonl(th->th_seq);
1165 tp = intotcpcb(inp);
1166 if (SEQ_GEQ(icmp_seq, tp->snd_una) &&
1167 SEQ_LT(icmp_seq, tp->snd_max))
1168 (*notify)(inp, inetctlerrmap[cmd]);
1169 }
1170 splx(s);
1c79356b 1171 } else
9bccf70c 1172 in_pcbnotifyall(&tcb, faddr, inetctlerrmap[cmd], notify);
1c79356b
A
1173}
1174
1175#if INET6
1176void
1177tcp6_ctlinput(cmd, sa, d)
1178 int cmd;
1179 struct sockaddr *sa;
1180 void *d;
1181{
1c79356b
A
1182 struct tcphdr th;
1183 void (*notify) __P((struct inpcb *, int)) = tcp_notify;
1c79356b
A
1184 struct ip6_hdr *ip6;
1185 struct mbuf *m;
9bccf70c
A
1186 struct ip6ctlparam *ip6cp = NULL;
1187 const struct sockaddr_in6 *sa6_src = NULL;
1188 int off;
1189 struct tcp_portonly {
1190 u_int16_t th_sport;
1191 u_int16_t th_dport;
1192 } *thp;
1c79356b
A
1193
1194 if (sa->sa_family != AF_INET6 ||
1195 sa->sa_len != sizeof(struct sockaddr_in6))
1196 return;
1197
1198 if (cmd == PRC_QUENCH)
1199 notify = tcp_quench;
1200 else if (cmd == PRC_MSGSIZE)
1201 notify = tcp_mtudisc;
1202 else if (!PRC_IS_REDIRECT(cmd) &&
1203 ((unsigned)cmd > PRC_NCMDS || inet6ctlerrmap[cmd] == 0))
1204 return;
1205
1206 /* if the parameter is from icmp6, decode it. */
1207 if (d != NULL) {
9bccf70c 1208 ip6cp = (struct ip6ctlparam *)d;
1c79356b
A
1209 m = ip6cp->ip6c_m;
1210 ip6 = ip6cp->ip6c_ip6;
1211 off = ip6cp->ip6c_off;
9bccf70c 1212 sa6_src = ip6cp->ip6c_src;
1c79356b
A
1213 } else {
1214 m = NULL;
1215 ip6 = NULL;
9bccf70c
A
1216 off = 0; /* fool gcc */
1217 sa6_src = &sa6_any;
1c79356b
A
1218 }
1219
1c79356b
A
1220 if (ip6) {
1221 /*
1222 * XXX: We assume that when IPV6 is non NULL,
1223 * M and OFF are valid.
1224 */
1c79356b 1225
9bccf70c
A
1226 /* check if we can safely examine src and dst ports */
1227 if (m->m_pkthdr.len < off + sizeof(*thp))
1228 return;
1c79356b 1229
9bccf70c
A
1230 bzero(&th, sizeof(th));
1231 m_copydata(m, off, sizeof(*thp), (caddr_t)&th);
1c79356b 1232
9bccf70c
A
1233 in6_pcbnotify(&tcb, sa, th.th_dport,
1234 (struct sockaddr *)ip6cp->ip6c_src,
1235 th.th_sport, cmd, notify);
1c79356b 1236 } else
9bccf70c 1237 in6_pcbnotify(&tcb, sa, 0, (struct sockaddr *)sa6_src,
1c79356b
A
1238 0, cmd, notify);
1239}
1240#endif /* INET6 */
1241
0b4e3aa0 1242
9bccf70c
A
1243/*
1244 * Following is where TCP initial sequence number generation occurs.
1245 *
1246 * There are two places where we must use initial sequence numbers:
1247 * 1. In SYN-ACK packets.
1248 * 2. In SYN packets.
1249 *
1250 * The ISNs in SYN-ACK packets have no monotonicity requirement,
1251 * and should be as unpredictable as possible to avoid the possibility
1252 * of spoofing and/or connection hijacking. To satisfy this
1253 * requirement, SYN-ACK ISNs are generated via the arc4random()
1254 * function. If exact RFC 1948 compliance is requested via sysctl,
1255 * these ISNs will be generated just like those in SYN packets.
1256 *
1257 * The ISNs in SYN packets must be monotonic; TIME_WAIT recycling
1258 * depends on this property. In addition, these ISNs should be
1259 * unguessable so as to prevent connection hijacking. To satisfy
1260 * the requirements of this situation, the algorithm outlined in
1261 * RFC 1948 is used to generate sequence numbers.
1262 *
1263 * For more information on the theory of operation, please see
1264 * RFC 1948.
1265 *
1266 * Implementation details:
1267 *
1268 * Time is based off the system timer, and is corrected so that it
1269 * increases by one megabyte per second. This allows for proper
1270 * recycling on high speed LANs while still leaving over an hour
1271 * before rollover.
1272 *
1273 * Two sysctls control the generation of ISNs:
1274 *
1275 * net.inet.tcp.isn_reseed_interval controls the number of seconds
1276 * between seeding of isn_secret. This is normally set to zero,
1277 * as reseeding should not be necessary.
1278 *
1279 * net.inet.tcp.strict_rfc1948 controls whether RFC 1948 is followed
1280 * strictly. When strict compliance is requested, reseeding is
1281 * disabled and SYN-ACKs will be generated in the same manner as
1282 * SYNs. Strict mode is disabled by default.
1283 *
1284 */
0b4e3aa0 1285
9bccf70c 1286#define ISN_BYTES_PER_SECOND 1048576
0b4e3aa0 1287
9bccf70c
A
1288u_char isn_secret[32];
1289int isn_last_reseed;
1290MD5_CTX isn_ctx;
0b4e3aa0
A
1291
1292tcp_seq
9bccf70c
A
1293tcp_new_isn(tp)
1294 struct tcpcb *tp;
0b4e3aa0 1295{
9bccf70c
A
1296 u_int32_t md5_buffer[4];
1297 tcp_seq new_isn;
1298 struct timeval time;
1299
1300 /* Use arc4random for SYN-ACKs when not in exact RFC1948 mode. */
1301 if (((tp->t_state == TCPS_LISTEN) || (tp->t_state == TCPS_TIME_WAIT))
1302 && tcp_strict_rfc1948 == 0)
1303#ifdef __APPLE__
1304 return random();
1305#else
1306 return arc4random();
1307#endif
0b4e3aa0 1308
9bccf70c
A
1309 /* Seed if this is the first use, reseed if requested. */
1310 if ((isn_last_reseed == 0) ||
1311 ((tcp_strict_rfc1948 == 0) && (tcp_isn_reseed_interval > 0) &&
1312 (((u_int)isn_last_reseed + (u_int)tcp_isn_reseed_interval*hz)
1313 < (u_int)time.tv_sec))) {
1314#ifdef __APPLE__
1315 read_random(&isn_secret, sizeof(isn_secret));
1316#else
1317 read_random_unlimited(&isn_secret, sizeof(isn_secret));
1318#endif
1319 isn_last_reseed = time.tv_sec;
1320 }
1321
1322 /* Compute the md5 hash and return the ISN. */
1323 MD5Init(&isn_ctx);
1324 MD5Update(&isn_ctx, (u_char *) &tp->t_inpcb->inp_fport, sizeof(u_short));
1325 MD5Update(&isn_ctx, (u_char *) &tp->t_inpcb->inp_lport, sizeof(u_short));
1326#if INET6
1327 if ((tp->t_inpcb->inp_vflag & INP_IPV6) != 0) {
1328 MD5Update(&isn_ctx, (u_char *) &tp->t_inpcb->in6p_faddr,
1329 sizeof(struct in6_addr));
1330 MD5Update(&isn_ctx, (u_char *) &tp->t_inpcb->in6p_laddr,
1331 sizeof(struct in6_addr));
1332 } else
1333#endif
1334 {
1335 MD5Update(&isn_ctx, (u_char *) &tp->t_inpcb->inp_faddr,
1336 sizeof(struct in_addr));
1337 MD5Update(&isn_ctx, (u_char *) &tp->t_inpcb->inp_laddr,
1338 sizeof(struct in_addr));
1339 }
1340 MD5Update(&isn_ctx, (u_char *) &isn_secret, sizeof(isn_secret));
1341 MD5Final((u_char *) &md5_buffer, &isn_ctx);
1342 new_isn = (tcp_seq) md5_buffer[0];
1343 new_isn += time.tv_sec * (ISN_BYTES_PER_SECOND / hz);
1344 return new_isn;
0b4e3aa0
A
1345}
1346
1c79356b
A
1347/*
1348 * When a source quench is received, close congestion window
1349 * to one segment. We will gradually open it again as we proceed.
1350 */
1351void
1352tcp_quench(inp, errno)
1353 struct inpcb *inp;
1354 int errno;
1355{
1356 struct tcpcb *tp = intotcpcb(inp);
1357
1358 if (tp)
1359 tp->snd_cwnd = tp->t_maxseg;
1360}
1361
9bccf70c
A
1362/*
1363 * When a specific ICMP unreachable message is received and the
1364 * connection state is SYN-SENT, drop the connection. This behavior
1365 * is controlled by the icmp_may_rst sysctl.
1366 */
1367void
1368tcp_drop_syn_sent(inp, errno)
1369 struct inpcb *inp;
1370 int errno;
1371{
1372 struct tcpcb *tp = intotcpcb(inp);
1373
1374 if (tp && tp->t_state == TCPS_SYN_SENT)
1375 tcp_drop(tp, errno);
1376}
1377
1c79356b
A
1378/*
1379 * When `need fragmentation' ICMP is received, update our idea of the MSS
1380 * based on the new value in the route. Also nudge TCP to send something,
1381 * since we know the packet we just sent was dropped.
1382 * This duplicates some code in the tcp_mss() function in tcp_input.c.
1383 */
1384void
1385tcp_mtudisc(inp, errno)
1386 struct inpcb *inp;
1387 int errno;
1388{
1389 struct tcpcb *tp = intotcpcb(inp);
1390 struct rtentry *rt;
1391 struct rmxp_tao *taop;
1392 struct socket *so = inp->inp_socket;
1393 int offered;
1394 int mss;
1395#if INET6
9bccf70c 1396 int isipv6 = (tp->t_inpcb->inp_vflag & INP_IPV6) != 0;
1c79356b
A
1397#endif /* INET6 */
1398
1399 if (tp) {
1400#if INET6
1401 if (isipv6)
1402 rt = tcp_rtlookup6(inp);
1403 else
1404#endif /* INET6 */
1405 rt = tcp_rtlookup(inp);
1406 if (!rt || !rt->rt_rmx.rmx_mtu) {
1407 tp->t_maxopd = tp->t_maxseg =
1408#if INET6
1409 isipv6 ? tcp_v6mssdflt :
1410#endif /* INET6 */
1411 tcp_mssdflt;
1412 return;
1413 }
1414 taop = rmx_taop(rt->rt_rmx);
1415 offered = taop->tao_mssopt;
1416 mss = rt->rt_rmx.rmx_mtu -
1417#if INET6
1418 (isipv6 ?
9bccf70c 1419 sizeof(struct ip6_hdr) + sizeof(struct tcphdr) :
1c79356b
A
1420#endif /* INET6 */
1421 sizeof(struct tcpiphdr)
1422#if INET6
1423 )
1424#endif /* INET6 */
1425 ;
1426
1427 if (offered)
1428 mss = min(mss, offered);
1429 /*
1430 * XXX - The above conditional probably violates the TCP
1431 * spec. The problem is that, since we don't know the
1432 * other end's MSS, we are supposed to use a conservative
1433 * default. But, if we do that, then MTU discovery will
1434 * never actually take place, because the conservative
1435 * default is much less than the MTUs typically seen
1436 * on the Internet today. For the moment, we'll sweep
1437 * this under the carpet.
1438 *
1439 * The conservative default might not actually be a problem
1440 * if the only case this occurs is when sending an initial
1441 * SYN with options and data to a host we've never talked
1442 * to before. Then, they will reply with an MSS value which
1443 * will get recorded and the new parameters should get
1444 * recomputed. For Further Study.
1445 */
1446 if (tp->t_maxopd <= mss)
1447 return;
1448 tp->t_maxopd = mss;
1449
1450 if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP &&
1451 (tp->t_flags & TF_RCVD_TSTMP) == TF_RCVD_TSTMP)
1452 mss -= TCPOLEN_TSTAMP_APPA;
1453 if ((tp->t_flags & (TF_REQ_CC|TF_NOOPT)) == TF_REQ_CC &&
1454 (tp->t_flags & TF_RCVD_CC) == TF_RCVD_CC)
1455 mss -= TCPOLEN_CC_APPA;
1456#if (MCLBYTES & (MCLBYTES - 1)) == 0
1457 if (mss > MCLBYTES)
1458 mss &= ~(MCLBYTES-1);
1459#else
1460 if (mss > MCLBYTES)
1461 mss = mss / MCLBYTES * MCLBYTES;
1462#endif
1463 if (so->so_snd.sb_hiwat < mss)
1464 mss = so->so_snd.sb_hiwat;
1465
1466 tp->t_maxseg = mss;
1467
1468 tcpstat.tcps_mturesent++;
9bccf70c 1469 tp->t_rtttime = 0;
1c79356b
A
1470 tp->snd_nxt = tp->snd_una;
1471 tcp_output(tp);
1472 }
1473}
1474
1475/*
1476 * Look-up the routing entry to the peer of this inpcb. If no route
1477 * is found and it cannot be allocated the return NULL. This routine
1478 * is called by TCP routines that access the rmx structure and by tcp_mss
1479 * to get the interface MTU.
1480 */
1481struct rtentry *
1482tcp_rtlookup(inp)
1483 struct inpcb *inp;
1484{
1485 struct route *ro;
1486 struct rtentry *rt;
1487
1488 ro = &inp->inp_route;
0b4e3aa0
A
1489 if (ro == NULL)
1490 return (NULL);
1c79356b
A
1491 rt = ro->ro_rt;
1492 if (rt == NULL || !(rt->rt_flags & RTF_UP)) {
1493 /* No route yet, so try to acquire one */
1494 if (inp->inp_faddr.s_addr != INADDR_ANY) {
1495 ro->ro_dst.sa_family = AF_INET;
9bccf70c 1496 ro->ro_dst.sa_len = sizeof(struct sockaddr_in);
1c79356b
A
1497 ((struct sockaddr_in *) &ro->ro_dst)->sin_addr =
1498 inp->inp_faddr;
1499 rtalloc(ro);
1500 rt = ro->ro_rt;
1501 }
1502 }
1503 return rt;
1504}
1505
1506#if INET6
1507struct rtentry *
1508tcp_rtlookup6(inp)
1509 struct inpcb *inp;
1510{
1511 struct route_in6 *ro6;
1512 struct rtentry *rt;
1513
1514 ro6 = &inp->in6p_route;
1515 rt = ro6->ro_rt;
1516 if (rt == NULL || !(rt->rt_flags & RTF_UP)) {
1517 /* No route yet, so try to acquire one */
1518 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
9bccf70c
A
1519 struct sockaddr_in6 *dst6;
1520
1521 dst6 = (struct sockaddr_in6 *)&ro6->ro_dst;
1522 dst6->sin6_family = AF_INET6;
1523 dst6->sin6_len = sizeof(*dst6);
1524 dst6->sin6_addr = inp->in6p_faddr;
1c79356b
A
1525 rtalloc((struct route *)ro6);
1526 rt = ro6->ro_rt;
1527 }
1528 }
1529 return rt;
1530}
1531#endif /* INET6 */
1532
1533#if IPSEC
1534/* compute ESP/AH header size for TCP, including outer IP header. */
1535size_t
9bccf70c 1536ipsec_hdrsiz_tcp(tp)
1c79356b 1537 struct tcpcb *tp;
1c79356b
A
1538{
1539 struct inpcb *inp;
1540 struct mbuf *m;
1541 size_t hdrsiz;
1542 struct ip *ip;
1543#if INET6
1544 struct ip6_hdr *ip6 = NULL;
1545#endif /* INET6 */
1546 struct tcphdr *th;
1547
9bccf70c 1548 if ((tp == NULL) || ((inp = tp->t_inpcb) == NULL))
1c79356b
A
1549 return 0;
1550 MGETHDR(m, M_DONTWAIT, MT_DATA);
1551 if (!m)
1552 return 0;
9bccf70c 1553
1c79356b 1554#if INET6
9bccf70c 1555 if ((inp->inp_vflag & INP_IPV6) != 0) {
1c79356b
A
1556 ip6 = mtod(m, struct ip6_hdr *);
1557 th = (struct tcphdr *)(ip6 + 1);
9bccf70c
A
1558 m->m_pkthdr.len = m->m_len =
1559 sizeof(struct ip6_hdr) + sizeof(struct tcphdr);
1560 tcp_fillheaders(tp, ip6, th);
1561 hdrsiz = ipsec6_hdrsiz(m, IPSEC_DIR_OUTBOUND, inp);
1562 } else
1c79356b 1563#endif /* INET6 */
9bccf70c 1564 {
1c79356b
A
1565 ip = mtod(m, struct ip *);
1566 th = (struct tcphdr *)(ip + 1);
1567 m->m_pkthdr.len = m->m_len = sizeof(struct tcpiphdr);
9bccf70c 1568 tcp_fillheaders(tp, ip, th);
1c79356b 1569 hdrsiz = ipsec4_hdrsiz(m, IPSEC_DIR_OUTBOUND, inp);
9bccf70c 1570 }
1c79356b
A
1571
1572 m_free(m);
1573 return hdrsiz;
1574}
1575#endif /*IPSEC*/
1576
1577/*
1578 * Return a pointer to the cached information about the remote host.
1579 * The cached information is stored in the protocol specific part of
1580 * the route metrics.
1581 */
1582struct rmxp_tao *
1583tcp_gettaocache(inp)
1584 struct inpcb *inp;
1585{
1c79356b
A
1586 struct rtentry *rt;
1587
1588#if INET6
9bccf70c 1589 if ((inp->inp_vflag & INP_IPV6) != 0)
1c79356b
A
1590 rt = tcp_rtlookup6(inp);
1591 else
1592#endif /* INET6 */
1593 rt = tcp_rtlookup(inp);
1594
1595 /* Make sure this is a host route and is up. */
1596 if (rt == NULL ||
1597 (rt->rt_flags & (RTF_UP|RTF_HOST)) != (RTF_UP|RTF_HOST))
1598 return NULL;
1599
1600 return rmx_taop(rt->rt_rmx);
1601}
1602
1603/*
1604 * Clear all the TAO cache entries, called from tcp_init.
1605 *
1606 * XXX
1607 * This routine is just an empty one, because we assume that the routing
1608 * routing tables are initialized at the same time when TCP, so there is
1609 * nothing in the cache left over.
1610 */
1611static void
1612tcp_cleartaocache()
1613{
1614}