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