annotate packages/net/tcpip/current/src/sys/netinet/tcp_input.c @ 97:ced4577552cd ecos-sw-2000-06-06

Merge from eCos master repository on 2000-06-06-08:44:00-BST
author jlarmour
date Tue, 06 Jun 2000 08:39:36 +0000
parents
children e0c0827131d1
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
97
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1 //==========================================================================
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2 //
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
3 // sys/netinet/tcp_input.c
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
4 //
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
5 //
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
6 //
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
7 //==========================================================================
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
8 //####COPYRIGHTBEGIN####
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
9 //
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
10 // -------------------------------------------
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
11 // The contents of this file are subject to the Red Hat eCos Public License
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
12 // Version 1.1 (the "License"); you may not use this file except in
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
13 // compliance with the License. You may obtain a copy of the License at
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
14 // http://www.redhat.com/
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
15 //
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
16 // Software distributed under the License is distributed on an "AS IS"
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
17 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
18 // License for the specific language governing rights and limitations under
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
19 // the License.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
20 //
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
21 // The Original Code is eCos - Embedded Configurable Operating System,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
22 // released September 30, 1998.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
23 //
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
24 // The Initial Developer of the Original Code is Red Hat.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
25 // Portions created by Red Hat are
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
26 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
27 // All Rights Reserved.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
28 // -------------------------------------------
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
29 //
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
30 //####COPYRIGHTEND####
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
31 //####BSDCOPYRIGHTBEGIN####
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
32 //
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
33 // -------------------------------------------
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
34 //
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
35 // Portions of this software may have been derived from OpenBSD or other sources,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
36 // and are covered by the appropriate copyright disclaimers included herein.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
37 //
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
38 // -------------------------------------------
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
39 //
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
40 //####BSDCOPYRIGHTEND####
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
41 //==========================================================================
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
42 //#####DESCRIPTIONBEGIN####
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
43 //
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
44 // Author(s): gthomas
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
45 // Contributors: gthomas
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
46 // Date: 2000-01-10
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
47 // Purpose:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
48 // Description:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
49 //
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
50 //
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
51 //####DESCRIPTIONEND####
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
52 //
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
53 //==========================================================================
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
54
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
55
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
56 /* $OpenBSD: tcp_input.c,v 1.54 1999/12/15 16:37:20 provos Exp $ */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
57 /* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
58
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
59 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
60 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
61 * The Regents of the University of California. All rights reserved.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
62 *
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
63 * Redistribution and use in source and binary forms, with or without
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
64 * modification, are permitted provided that the following conditions
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
65 * are met:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
66 * 1. Redistributions of source code must retain the above copyright
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
67 * notice, this list of conditions and the following disclaimer.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
68 * 2. Redistributions in binary form must reproduce the above copyright
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
69 * notice, this list of conditions and the following disclaimer in the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
70 * documentation and/or other materials provided with the distribution.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
71 * 3. All advertising materials mentioning features or use of this software
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
72 * must display the following acknowledgement:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
73 * This product includes software developed by the University of
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
74 * California, Berkeley and its contributors.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
75 * 4. Neither the name of the University nor the names of its contributors
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
76 * may be used to endorse or promote products derived from this software
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
77 * without specific prior written permission.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
78 *
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
79 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
80 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
81 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
82 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
83 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
84 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
85 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
86 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
87 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
88 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
89 * SUCH DAMAGE.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
90 *
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
91 * @(#)tcp_input.c 8.5 (Berkeley) 4/10/94
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
92 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
93
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
94 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
95 %%% portions-copyright-nrl-95
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
96 Portions of this software are Copyright 1995-1998 by Randall Atkinson,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
97 Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
98 Reserved. All rights under this copyright have been assigned to the US
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
99 Naval Research Laboratory (NRL). The NRL Copyright Notice and License
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
100 Agreement Version 1.1 (January 17, 1995) applies to these portions of the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
101 software.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
102 You should have received a copy of the license with this software. If you
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
103 didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
104 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
105
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
106 #ifndef TUBA_INCLUDE
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
107 #include <sys/param.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
108 #ifndef __ECOS
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
109 #include <sys/systm.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
110 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
111 #include <sys/malloc.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
112 #include <sys/mbuf.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
113 #include <sys/protosw.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
114 #include <sys/socket.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
115 #include <sys/socketvar.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
116 #include <sys/errno.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
117
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
118 #include <net/if.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
119 #include <net/route.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
120
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
121 #include <netinet/in.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
122 #include <netinet/in_systm.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
123 #include <netinet/ip.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
124 #include <netinet/in_pcb.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
125 #include <netinet/ip_var.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
126 #include <netinet/tcp.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
127 #include <netinet/tcp_fsm.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
128 #include <netinet/tcp_seq.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
129 #include <netinet/tcp_timer.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
130 #include <netinet/tcp_var.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
131 #include <netinet/tcpip.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
132 #include <netinet/tcp_debug.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
133 #ifndef __ECOS
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
134 #include <dev/rndvar.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
135 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
136 #include <machine/stdarg.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
137 #ifndef __ECOS
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
138 #include <sys/md5k.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
139 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
140
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
141 #ifdef IPSEC
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
142 #include <netinet/ip_ipsp.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
143 #endif /* IPSEC */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
144
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
145 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
146 #ifndef INET
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
147 #include <netinet/in.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
148 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
149 #include <sys/domain.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
150 #include <netinet6/in6_var.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
151 #include <netinet/ip6.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
152 #include <netinet6/ip6_var.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
153 #include <netinet6/tcpipv6.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
154 #include <netinet/icmp6.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
155 #include <netinet6/nd6.h>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
156
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
157 #ifndef CREATE_IPV6_MAPPED
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
158 #define CREATE_IPV6_MAPPED(a6, a4) \
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
159 do { \
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
160 bzero(&(a6), sizeof(a6)); \
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
161 (a6).s6_addr[10] = (a6).s6_addr[11] = 0xff; \
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
162 *(u_int32_t *)&(a6).s6_addr[12] = (a4); \
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
163 } while (0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
164 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
165
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
166 struct tcpiphdr tcp_saveti;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
167 struct tcpipv6hdr tcp_saveti6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
168
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
169 /* for the packet header length in the mbuf */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
170 #define M_PH_LEN(m) (((struct mbuf *)(m))->m_pkthdr.len)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
171 #define M_V6_LEN(m) (M_PH_LEN(m) - sizeof(struct ip6_hdr))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
172 #define M_V4_LEN(m) (M_PH_LEN(m) - sizeof(struct ip))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
173 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
174
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
175 int tcprexmtthresh = 3;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
176 struct tcpiphdr tcp_saveti;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
177 int tcptv_keep_init = TCPTV_KEEP_INIT;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
178
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
179 extern u_long sb_max;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
180
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
181 #endif /* TUBA_INCLUDE */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
182 #define TCP_PAWS_IDLE (24 * 24 * 60 * 60 * PR_SLOWHZ)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
183
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
184 /* for modulo comparisons of timestamps */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
185 #define TSTMP_LT(a,b) ((int)((a)-(b)) < 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
186 #define TSTMP_GEQ(a,b) ((int)((a)-(b)) >= 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
187
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
188 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
189 * Neighbor Discovery, Neighbor Unreachability Detection Upper layer hint.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
190 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
191 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
192 #define ND6_HINT(tp) \
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
193 do { \
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
194 if (tp && tp->t_inpcb && (tp->t_inpcb->inp_flags & INP_IPV6) \
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
195 && !(tp->t_inpcb->inp_flags & INP_IPV6_MAPPED) \
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
196 && tp->t_inpcb->inp_route6.ro_rt) { \
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
197 nd6_nud_hint(tp->t_inpcb->inp_route6.ro_rt, NULL); \
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
198 } \
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
199 } while (0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
200 #else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
201 #define ND6_HINT(tp)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
202 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
203
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
204 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
205 * Insert segment ti into reassembly queue of tcp with
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
206 * control block tp. Return TH_FIN if reassembly now includes
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
207 * a segment with FIN. The macro form does the common case inline
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
208 * (segment is the next to be received on an established connection,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
209 * and the queue is empty), avoiding linkage into and removal
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
210 * from the queue and repetition of various conversions.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
211 * Set DELACK for segments received in order, but ack immediately
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
212 * when segments are out of order (so fast retransmit can work).
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
213 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
214
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
215 #ifndef TUBA_INCLUDE
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
216
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
217 int
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
218 tcp_reass(tp, th, m, tlen)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
219 register struct tcpcb *tp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
220 register struct tcphdr *th;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
221 struct mbuf *m;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
222 int *tlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
223 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
224 register struct ipqent *p, *q, *nq, *tiqe;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
225 struct socket *so = tp->t_inpcb->inp_socket;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
226 int flags;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
227
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
228 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
229 * Call with th==0 after become established to
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
230 * force pre-ESTABLISHED data up to user socket.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
231 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
232 if (th == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
233 goto present;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
234
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
235 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
236 * Allocate a new queue entry, before we throw away any data.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
237 * If we can't, just drop the packet. XXX
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
238 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
239 MALLOC(tiqe, struct ipqent *, sizeof (struct ipqent), M_IPQ, M_NOWAIT);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
240 if (tiqe == NULL) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
241 tcpstat.tcps_rcvmemdrop++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
242 m_freem(m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
243 return (0);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
244 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
245
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
246 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
247 * Find a segment which begins after this one does.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
248 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
249 for (p = NULL, q = tp->segq.lh_first; q != NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
250 p = q, q = q->ipqe_q.le_next)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
251 if (SEQ_GT(q->ipqe_tcp->th_seq, th->th_seq))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
252 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
253
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
254 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
255 * If there is a preceding segment, it may provide some of
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
256 * our data already. If so, drop the data from the incoming
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
257 * segment. If it provides all of our data, drop us.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
258 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
259 if (p != NULL) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
260 register struct tcphdr *phdr = p->ipqe_tcp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
261 register int i;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
262
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
263 /* conversion to int (in i) handles seq wraparound */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
264 i = phdr->th_seq + phdr->th_reseqlen - th->th_seq;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
265 if (i > 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
266 if (i >= *tlen) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
267 tcpstat.tcps_rcvduppack++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
268 tcpstat.tcps_rcvdupbyte += *tlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
269 m_freem(m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
270 FREE(tiqe, M_IPQ);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
271 return (0);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
272 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
273 m_adj(m, i);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
274 *tlen -= i;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
275 th->th_seq += i;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
276 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
277 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
278 tcpstat.tcps_rcvoopack++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
279 tcpstat.tcps_rcvoobyte += *tlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
280
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
281 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
282 * While we overlap succeeding segments trim them or,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
283 * if they are completely covered, dequeue them.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
284 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
285 for (; q != NULL; q = nq) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
286 register struct tcphdr *qhdr = q->ipqe_tcp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
287 register int i = (th->th_seq + *tlen) - qhdr->th_seq;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
288
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
289 if (i <= 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
290 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
291 if (i < qhdr->th_reseqlen) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
292 qhdr->th_seq += i;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
293 qhdr->th_reseqlen -= i;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
294 m_adj(q->ipqe_m, i);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
295 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
296 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
297 nq = q->ipqe_q.le_next;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
298 m_freem(q->ipqe_m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
299 LIST_REMOVE(q, ipqe_q);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
300 FREE(q, M_IPQ);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
301 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
302
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
303 /* Insert the new fragment queue entry into place. */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
304 tiqe->ipqe_m = m;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
305 th->th_reseqlen = *tlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
306 tiqe->ipqe_tcp = th;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
307 if (p == NULL) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
308 LIST_INSERT_HEAD(&tp->segq, tiqe, ipqe_q);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
309 } else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
310 LIST_INSERT_AFTER(p, tiqe, ipqe_q);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
311 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
312
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
313 present:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
314 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
315 * Present data to user, advancing rcv_nxt through
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
316 * completed sequence space.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
317 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
318 if (TCPS_HAVEESTABLISHED(tp->t_state) == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
319 return (0);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
320 q = tp->segq.lh_first;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
321 if (q == NULL || q->ipqe_tcp->th_seq != tp->rcv_nxt)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
322 return (0);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
323 if (tp->t_state == TCPS_SYN_RECEIVED && q->ipqe_tcp->th_reseqlen)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
324 return (0);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
325 do {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
326 tp->rcv_nxt += q->ipqe_tcp->th_reseqlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
327 flags = q->ipqe_tcp->th_flags & TH_FIN;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
328
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
329 nq = q->ipqe_q.le_next;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
330 LIST_REMOVE(q, ipqe_q);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
331 ND6_HINT(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
332 if (so->so_state & SS_CANTRCVMORE)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
333 m_freem(q->ipqe_m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
334 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
335 sbappend(&so->so_rcv, q->ipqe_m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
336 FREE(q, M_IPQ);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
337 q = nq;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
338 } while (q != NULL && q->ipqe_tcp->th_seq == tp->rcv_nxt);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
339 sorwakeup(so);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
340 return (flags);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
341 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
342
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
343 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
344 * First check for a port-specific bomb. We do not want to drop half-opens
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
345 * for other ports if this is the only port being bombed. We only check
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
346 * the bottom 40 half open connections, to avoid wasting too much time.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
347 *
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
348 * Or, otherwise it is more likely a generic syn bomb, so delete the oldest
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
349 * half-open connection.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
350 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
351 void
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
352 tcpdropoldhalfopen(avoidtp, port)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
353 struct tcpcb *avoidtp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
354 u_int16_t port;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
355 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
356 register struct inpcb *inp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
357 register struct tcpcb *tp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
358 int ncheck = 40;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
359 int s;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
360
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
361 s = splnet();
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
362 inp = tcbtable.inpt_queue.cqh_first;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
363 if (inp) /* XXX */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
364 for (; inp != (struct inpcb *)&tcbtable.inpt_queue && --ncheck;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
365 inp = inp->inp_queue.cqe_prev) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
366 if ((tp = (struct tcpcb *)inp->inp_ppcb) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
367 tp != avoidtp &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
368 tp->t_state == TCPS_SYN_RECEIVED &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
369 port == inp->inp_lport) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
370 tcp_close(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
371 goto done;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
372 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
373 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
374
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
375 inp = tcbtable.inpt_queue.cqh_first;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
376 if (inp) /* XXX */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
377 for (; inp != (struct inpcb *)&tcbtable.inpt_queue;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
378 inp = inp->inp_queue.cqe_prev) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
379 if ((tp = (struct tcpcb *)inp->inp_ppcb) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
380 tp != avoidtp &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
381 tp->t_state == TCPS_SYN_RECEIVED) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
382 tcp_close(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
383 goto done;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
384 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
385 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
386 done:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
387 splx(s);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
388 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
389
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
390 #if defined(INET6) && !defined(TCP6)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
391 int
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
392 tcp6_input(mp, offp, proto)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
393 struct mbuf **mp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
394 int *offp, proto;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
395 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
396 struct mbuf *m = *mp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
397
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
398 #if defined(NFAITH) && 0 < NFAITH
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
399 if (m->m_pkthdr.rcvif) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
400 if (m->m_pkthdr.rcvif->if_type == IFT_FAITH) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
401 /* XXX send icmp6 host/port unreach? */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
402 m_freem(m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
403 return IPPROTO_DONE;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
404 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
405 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
406 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
407
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
408 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
409 * draft-itojun-ipv6-tcp-to-anycast
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
410 * better place to put this in?
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
411 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
412 if (m->m_flags & M_ANYCAST6) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
413 if (m->m_len >= sizeof(struct ip6_hdr)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
414 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
415 icmp6_error(m, ICMP6_DST_UNREACH,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
416 ICMP6_DST_UNREACH_ADDR,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
417 (caddr_t)&ip6->ip6_dst - (caddr_t)ip6);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
418 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
419 m_freem(m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
420 return IPPROTO_DONE;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
421 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
422
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
423 tcp_input(m, *offp, proto);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
424 return IPPROTO_DONE;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
425 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
426 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
427
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
428 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
429 * TCP input routine, follows pages 65-76 of the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
430 * protocol specification dated September, 1981 very closely.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
431 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
432 void
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
433 #if __STDC__
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
434 tcp_input(struct mbuf *m, ...)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
435 #else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
436 tcp_input(m, va_alist)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
437 register struct mbuf *m;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
438 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
439 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
440 register struct tcpiphdr *ti;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
441 register struct inpcb *inp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
442 caddr_t optp = NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
443 int optlen = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
444 int len, tlen, off;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
445 register struct tcpcb *tp = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
446 register int tiflags;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
447 struct socket *so = NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
448 int todrop, acked, ourfinisacked, needoutput = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
449 int hdroptlen = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
450 short ostate = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
451 struct in_addr laddr;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
452 int dropsocket = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
453 int iss = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
454 u_long tiwin;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
455 u_int32_t ts_val, ts_ecr;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
456 int ts_present = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
457 int iphlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
458 va_list ap;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
459 register struct tcphdr *th;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
460 #ifdef IPSEC
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
461 struct tdb *tdb = NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
462 #endif /* IPSEC */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
463 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
464 struct in6_addr laddr6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
465 unsigned short is_ipv6; /* Type of incoming datagram. */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
466 struct ip6_hdr *ipv6 = NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
467 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
468
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
469 va_start(ap, m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
470 iphlen = va_arg(ap, int);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
471 va_end(ap);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
472
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
473 tcpstat.tcps_rcvtotal++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
474
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
475 #ifdef IPSEC
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
476 /* Save the last SA which was used to process the mbuf */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
477 if ((m->m_flags & (M_CONF|M_AUTH)) && m->m_pkthdr.tdbi) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
478 struct tdb_ident *tdbi = m->m_pkthdr.tdbi;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
479 /* XXX gettdb() should really be called at spltdb(). */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
480 /* XXX this is splsoftnet(), currently they are the same. */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
481 tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
482 free(m->m_pkthdr.tdbi, M_TEMP);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
483 m->m_pkthdr.tdbi = NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
484 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
485 #endif /* IPSEC */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
486 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
487 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
488 * Before we do ANYTHING, we have to figure out if it's TCP/IPv6 or
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
489 * TCP/IPv4.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
490 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
491 is_ipv6 = mtod(m, struct ip *)->ip_v == 6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
492 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
493
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
494 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
495 * Get IP and TCP header together in first mbuf.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
496 * Note: IP leaves IP header in first mbuf.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
497 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
498 #ifndef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
499 ti = mtod(m, struct tcpiphdr *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
500 #else /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
501 if (!is_ipv6)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
502 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
503 if (iphlen > sizeof (struct ip)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
504 #if 0 /*XXX*/
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
505 ip_stripoptions(m, (struct mbuf *)0);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
506 #else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
507 #ifdef __ECOS
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
508 diag_printf("extension headers are not allowed\n");
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
509 #else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
510 printf("extension headers are not allowed\n");
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
511 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
512 m_freem(m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
513 return;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
514 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
515 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
516 if (m->m_len < iphlen + sizeof(struct tcphdr)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
517 if ((m = m_pullup2(m, iphlen + sizeof(struct tcphdr))) == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
518 tcpstat.tcps_rcvshort++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
519 return;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
520 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
521 #ifndef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
522 ti = mtod(m, struct tcpiphdr *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
523 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
524 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
525
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
526 tlen = m->m_pkthdr.len - iphlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
527
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
528 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
529 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
530 * After that, do initial segment processing which is still very
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
531 * dependent on what IP version you're using.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
532 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
533
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
534 if (is_ipv6) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
535 #ifdef DIAGNOSTIC
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
536 if (iphlen < sizeof(struct ip6_hdr)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
537 m_freem(m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
538 return;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
539 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
540 #endif /* DIAGNOSTIC */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
541
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
542 /* strip off any options */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
543 if (iphlen > sizeof(struct ip6_hdr)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
544 #if 0 /*XXX*/
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
545 ipv6_stripoptions(m, iphlen);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
546 #else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
547 #ifdef __ECOS
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
548 diag_printf("extension headers are not allowed\n");
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
549 #else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
550 printf("extension headers are not allowed\n");
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
551 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
552 m_freem(m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
553 return;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
554 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
555 iphlen = sizeof(struct ip6_hdr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
556 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
557
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
558 ti = NULL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
559 ipv6 = mtod(m, struct ip6_hdr *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
560
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
561 if (in6_cksum(m, IPPROTO_TCP, sizeof(struct ip6_hdr), tlen)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
562 tcpstat.tcps_rcvbadsum++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
563 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
564 } /* endif in6_cksum */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
565 } else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
566 ti = mtod(m, struct tcpiphdr *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
567 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
568
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
569 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
570 * Checksum extended TCP header and data.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
571 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
572 #ifndef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
573 tlen = ((struct ip *)ti)->ip_len;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
574 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
575 len = sizeof (struct ip) + tlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
576 bzero(ti->ti_x1, sizeof ti->ti_x1);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
577 ti->ti_len = (u_int16_t)tlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
578 HTONS(ti->ti_len);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
579 if ((ti->ti_sum = in_cksum(m, len)) != 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
580 tcpstat.tcps_rcvbadsum++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
581 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
582 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
583 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
584 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
585 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
586 #endif /* TUBA_INCLUDE */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
587
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
588 th = (struct tcphdr *)(mtod(m, caddr_t) + iphlen);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
589
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
590 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
591 * Check that TCP offset makes sense,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
592 * pull out TCP options and adjust length. XXX
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
593 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
594 off = th->th_off << 2;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
595 if (off < sizeof (struct tcphdr) || off > tlen) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
596 tcpstat.tcps_rcvbadoff++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
597 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
598 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
599 tlen -= off;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
600 if (off > sizeof (struct tcphdr)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
601 if (m->m_len < iphlen + off) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
602 if ((m = m_pullup2(m, iphlen + off)) == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
603 tcpstat.tcps_rcvshort++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
604 return;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
605 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
606 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
607 if (is_ipv6)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
608 ipv6 = mtod(m, struct ip6_hdr *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
609 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
610 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
611 ti = mtod(m, struct tcpiphdr *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
612 th = (struct tcphdr *)(mtod(m, caddr_t) + iphlen);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
613 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
614 optlen = off - sizeof (struct tcphdr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
615 optp = mtod(m, caddr_t) + iphlen + sizeof(struct tcphdr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
616 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
617 * Do quick retrieval of timestamp options ("options
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
618 * prediction?"). If timestamp is the only option and it's
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
619 * formatted as recommended in RFC 1323 appendix A, we
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
620 * quickly get the values now and not bother calling
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
621 * tcp_dooptions(), etc.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
622 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
623 if ((optlen == TCPOLEN_TSTAMP_APPA ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
624 (optlen > TCPOLEN_TSTAMP_APPA &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
625 optp[TCPOLEN_TSTAMP_APPA] == TCPOPT_EOL)) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
626 *(u_int32_t *)optp == htonl(TCPOPT_TSTAMP_HDR) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
627 (th->th_flags & TH_SYN) == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
628 ts_present = 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
629 ts_val = ntohl(*(u_int32_t *)(optp + 4));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
630 ts_ecr = ntohl(*(u_int32_t *)(optp + 8));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
631 optp = NULL; /* we've parsed the options */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
632 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
633 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
634 tiflags = th->th_flags;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
635
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
636 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
637 * Convert TCP protocol specific fields to host format.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
638 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
639 NTOHL(th->th_seq);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
640 NTOHL(th->th_ack);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
641 NTOHS(th->th_win);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
642 NTOHS(th->th_urp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
643
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
644 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
645 * Locate pcb for segment.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
646 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
647 findpcb:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
648 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
649 if (is_ipv6) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
650 inp = in6_pcbhashlookup(&tcbtable, &ipv6->ip6_src, th->th_sport,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
651 &ipv6->ip6_dst, th->th_dport);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
652 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
653 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
654 inp = in_pcbhashlookup(&tcbtable, ti->ti_src, ti->ti_sport,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
655 ti->ti_dst, ti->ti_dport);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
656 if (inp == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
657 ++tcpstat.tcps_pcbhashmiss;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
658 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
659 if (is_ipv6)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
660 inp = in_pcblookup(&tcbtable, &ipv6->ip6_src,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
661 th->th_sport, &ipv6->ip6_dst, th->th_dport,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
662 INPLOOKUP_WILDCARD | INPLOOKUP_IPV6);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
663 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
664 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
665 inp = in_pcblookup(&tcbtable, &ti->ti_src, ti->ti_sport,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
666 &ti->ti_dst, ti->ti_dport, INPLOOKUP_WILDCARD);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
667 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
668 * If the state is CLOSED (i.e., TCB does not exist) then
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
669 * all data in the incoming segment is discarded.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
670 * If the TCB exists but is in CLOSED state, it is embryonic,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
671 * but should either do a listen or a connect soon.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
672 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
673 if (inp == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
674 ++tcpstat.tcps_noport;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
675 goto dropwithreset;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
676 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
677 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
678
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
679 tp = intotcpcb(inp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
680 if (tp == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
681 goto dropwithreset;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
682 if (tp->t_state == TCPS_CLOSED)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
683 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
684
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
685 /* Unscale the window into a 32-bit value. */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
686 if ((tiflags & TH_SYN) == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
687 tiwin = th->th_win << tp->snd_scale;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
688 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
689 tiwin = th->th_win;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
690
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
691 so = inp->inp_socket;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
692 if (so->so_options & (SO_DEBUG|SO_ACCEPTCONN)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
693 if (so->so_options & SO_DEBUG) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
694 ostate = tp->t_state;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
695 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
696 if (is_ipv6)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
697 tcp_saveti6 = *(mtod(m, struct tcpipv6hdr *));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
698 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
699 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
700 tcp_saveti = *ti;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
701 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
702 if (so->so_options & SO_ACCEPTCONN) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
703 struct socket *so1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
704
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
705 so1 = sonewconn(so, 0);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
706 if (so1 == NULL) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
707 tcpdropoldhalfopen(tp, th->th_dport);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
708 so1 = sonewconn(so, 0);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
709 if (so1 == NULL)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
710 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
711 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
712 so = so1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
713 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
714 * This is ugly, but ....
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
715 *
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
716 * Mark socket as temporary until we're
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
717 * committed to keeping it. The code at
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
718 * ``drop'' and ``dropwithreset'' check the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
719 * flag dropsocket to see if the temporary
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
720 * socket created here should be discarded.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
721 * We mark the socket as discardable until
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
722 * we're committed to it below in TCPS_LISTEN.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
723 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
724 dropsocket++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
725 #ifdef IPSEC
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
726 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
727 * We need to copy the required security levels
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
728 * from the old pcb.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
729 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
730 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
731 struct inpcb *newinp = (struct inpcb *)so->so_pcb;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
732 bcopy(inp->inp_seclevel, newinp->inp_seclevel,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
733 sizeof(inp->inp_seclevel));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
734 newinp->inp_secrequire = inp->inp_secrequire;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
735 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
736 #endif /* IPSEC */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
737 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
738 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
739 * inp still has the OLD in_pcb stuff, set the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
740 * v6-related flags on the new guy, too. This is
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
741 * done particularly for the case where an AF_INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
742 * socket is bound only to a port, and a v4 connection
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
743 * comes in on that port.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
744 * we also copy the flowinfo from the original pcb
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
745 * to the new one.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
746 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
747 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
748 int flags = inp->inp_flags;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
749 struct inpcb *oldinpcb = inp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
750
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
751 inp = (struct inpcb *)so->so_pcb;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
752 inp->inp_flags |= (flags & (INP_IPV6 | INP_IPV6_UNDEC
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
753 | INP_IPV6_MAPPED));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
754 if ((inp->inp_flags & INP_IPV6) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
755 !(inp->inp_flags & INP_IPV6_MAPPED)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
756 inp->inp_ipv6.ip6_hlim =
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
757 oldinpcb->inp_ipv6.ip6_hlim;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
758 inp->inp_ipv6.ip6_flow =
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
759 oldinpcb->inp_ipv6.ip6_flow;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
760 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
761 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
762 #else /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
763 inp = (struct inpcb *)so->so_pcb;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
764 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
765 inp->inp_lport = th->th_dport;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
766 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
767 if (is_ipv6) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
768 inp->inp_laddr6 = ipv6->ip6_dst;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
769 inp->inp_fflowinfo = htonl(0x0fffffff) &
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
770 ipv6->ip6_flow;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
771
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
772 /*inp->inp_options = ip6_srcroute();*/ /* soon. */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
773 /* still need to tweak outbound options
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
774 processing to include this mbuf in
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
775 the right place and put the correct
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
776 NextHdr values in the right places.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
777 XXX rja */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
778 } else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
779 if (inp->inp_flags & INP_IPV6) {/* v4 to v6 socket */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
780 CREATE_IPV6_MAPPED(inp->inp_laddr6,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
781 ti->ti_dst.s_addr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
782 } else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
783 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
784 inp->inp_laddr = ti->ti_dst;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
785 inp->inp_options = ip_srcroute();
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
786 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
787 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
788 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
789 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
790 in_pcbrehash(inp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
791 tp = intotcpcb(inp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
792 tp->t_state = TCPS_LISTEN;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
793
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
794 /* Compute proper scaling value from buffer space
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
795 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
796 while (tp->request_r_scale < TCP_MAX_WINSHIFT &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
797 TCP_MAXWIN << tp->request_r_scale < so->so_rcv.sb_hiwat)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
798 tp->request_r_scale++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
799 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
800 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
801
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
802 #ifdef IPSEC
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
803 /* Check if this socket requires security for incoming packets */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
804 if ((inp->inp_seclevel[SL_AUTH] >= IPSEC_LEVEL_REQUIRE &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
805 !(m->m_flags & M_AUTH)) ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
806 (inp->inp_seclevel[SL_ESP_TRANS] >= IPSEC_LEVEL_REQUIRE &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
807 !(m->m_flags & M_CONF))) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
808 #ifdef notyet
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
809 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
810 if (is_ipv6)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
811 icmp6_error(m, ICMPV6_BLAH, ICMPV6_BLAH, 0);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
812 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
813 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
814 icmp_error(m, ICMP_BLAH, ICMP_BLAH, 0, 0);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
815 #endif /* notyet */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
816 tcpstat.tcps_rcvnosec++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
817 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
818 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
819 /* Use tdb_bind_out for this inp's outbound communication */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
820 if (tdb)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
821 tdb_add_inp(tdb, inp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
822 #endif /*IPSEC */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
823
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
824 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
825 * Segment received on connection.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
826 * Reset idle time and keep-alive timer.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
827 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
828 tp->t_idle = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
829 if (tp->t_state != TCPS_SYN_RECEIVED)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
830 tp->t_timer[TCPT_KEEP] = tcp_keepidle;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
831
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
832 #ifdef TCP_SACK
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
833 if (!tp->sack_disable)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
834 tcp_del_sackholes(tp, th); /* Delete stale SACK holes */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
835 #endif /* TCP_SACK */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
836
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
837 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
838 * Process options if not in LISTEN state,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
839 * else do it below (after getting remote address).
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
840 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
841 if (optp && tp->t_state != TCPS_LISTEN)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
842 tcp_dooptions(tp, optp, optlen, th,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
843 &ts_present, &ts_val, &ts_ecr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
844
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
845 #ifdef TCP_SACK
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
846 if (!tp->sack_disable) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
847 tp->rcv_laststart = th->th_seq; /* last rec'vd segment*/
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
848 tp->rcv_lastend = th->th_seq + tlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
849 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
850 #endif /* TCP_SACK */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
851 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
852 * Header prediction: check for the two common cases
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
853 * of a uni-directional data xfer. If the packet has
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
854 * no control flags, is in-sequence, the window didn't
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
855 * change and we're not retransmitting, it's a
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
856 * candidate. If the length is zero and the ack moved
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
857 * forward, we're the sender side of the xfer. Just
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
858 * free the data acked & wake any higher level process
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
859 * that was blocked waiting for space. If the length
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
860 * is non-zero and the ack didn't move, we're the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
861 * receiver side. If we're getting packets in-order
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
862 * (the reassembly queue is empty), add the data to
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
863 * the socket buffer and note that we need a delayed ack.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
864 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
865 if (tp->t_state == TCPS_ESTABLISHED &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
866 (tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) == TH_ACK &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
867 (!ts_present || TSTMP_GEQ(ts_val, tp->ts_recent)) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
868 th->th_seq == tp->rcv_nxt &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
869 tiwin && tiwin == tp->snd_wnd &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
870 tp->snd_nxt == tp->snd_max) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
871
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
872 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
873 * If last ACK falls within this segment's sequence numbers,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
874 * record the timestamp.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
875 * Fix from Braden, see Stevens p. 870
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
876 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
877 if (ts_present && SEQ_LEQ(th->th_seq, tp->last_ack_sent)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
878 tp->ts_recent_age = tcp_now;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
879 tp->ts_recent = ts_val;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
880 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
881
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
882 if (tlen == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
883 if (SEQ_GT(th->th_ack, tp->snd_una) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
884 SEQ_LEQ(th->th_ack, tp->snd_max) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
885 tp->snd_cwnd >= tp->snd_wnd &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
886 tp->t_dupacks == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
887 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
888 * this is a pure ack for outstanding data.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
889 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
890 ++tcpstat.tcps_predack;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
891 if (ts_present)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
892 tcp_xmit_timer(tp, tcp_now-ts_ecr+1);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
893 else if (tp->t_rtt &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
894 SEQ_GT(th->th_ack, tp->t_rtseq))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
895 tcp_xmit_timer(tp, tp->t_rtt);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
896 acked = th->th_ack - tp->snd_una;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
897 tcpstat.tcps_rcvackpack++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
898 tcpstat.tcps_rcvackbyte += acked;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
899 ND6_HINT(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
900 sbdrop(&so->so_snd, acked);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
901 tp->snd_una = th->th_ack;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
902 #if defined(TCP_SACK) || defined(TCP_NEWRENO)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
903 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
904 * We want snd_last to track snd_una so
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
905 * as to avoid sequence wraparound problems
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
906 * for very large transfers.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
907 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
908 tp->snd_last = tp->snd_una;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
909 #endif /* TCP_SACK or TCP_NEWRENO */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
910 #if defined(TCP_SACK) && defined(TCP_FACK)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
911 tp->snd_fack = tp->snd_una;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
912 tp->retran_data = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
913 #endif /* TCP_FACK */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
914 m_freem(m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
915
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
916 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
917 * If all outstanding data are acked, stop
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
918 * retransmit timer, otherwise restart timer
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
919 * using current (possibly backed-off) value.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
920 * If process is waiting for space,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
921 * wakeup/selwakeup/signal. If data
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
922 * are ready to send, let tcp_output
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
923 * decide between more output or persist.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
924 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
925 if (tp->snd_una == tp->snd_max)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
926 tp->t_timer[TCPT_REXMT] = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
927 else if (tp->t_timer[TCPT_PERSIST] == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
928 tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
929
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
930 if (sb_notify(&so->so_snd))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
931 sowwakeup(so);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
932 if (so->so_snd.sb_cc)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
933 (void) tcp_output(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
934 return;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
935 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
936 } else if (th->th_ack == tp->snd_una &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
937 tp->segq.lh_first == NULL &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
938 tlen <= sbspace(&so->so_rcv)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
939 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
940 * This is a pure, in-sequence data packet
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
941 * with nothing on the reassembly queue and
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
942 * we have enough buffer space to take it.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
943 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
944 #ifdef TCP_SACK
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
945 /* Clean receiver SACK report if present */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
946 if (!tp->sack_disable && tp->rcv_numsacks)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
947 tcp_clean_sackreport(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
948 #endif /* TCP_SACK */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
949 ++tcpstat.tcps_preddat;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
950 tp->rcv_nxt += tlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
951 tcpstat.tcps_rcvpack++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
952 tcpstat.tcps_rcvbyte += tlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
953 ND6_HINT(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
954 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
955 * Drop TCP, IP headers and TCP options then add data
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
956 * to socket buffer.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
957 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
958 m_adj(m, iphlen + off);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
959 sbappend(&so->so_rcv, m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
960 sorwakeup(so);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
961 if (th->th_flags & TH_PUSH)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
962 tp->t_flags |= TF_ACKNOW;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
963 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
964 tp->t_flags |= TF_DELACK;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
965 return;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
966 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
967 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
968
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
969 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
970 * Compute mbuf offset to TCP data segment.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
971 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
972 hdroptlen = iphlen + off;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
973
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
974 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
975 * Calculate amount of space in receive window,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
976 * and then do TCP input processing.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
977 * Receive window is amount of space in rcv queue,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
978 * but not less than advertised window.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
979 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
980 { int win;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
981
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
982 win = sbspace(&so->so_rcv);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
983 if (win < 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
984 win = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
985 tp->rcv_wnd = imax(win, (int)(tp->rcv_adv - tp->rcv_nxt));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
986 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
987
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
988 switch (tp->t_state) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
989
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
990 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
991 * If the state is LISTEN then ignore segment if it contains an RST.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
992 * If the segment contains an ACK then it is bad and send a RST.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
993 * If it does not contain a SYN then it is not interesting; drop it.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
994 * If it is from this socket, drop it, it must be forged.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
995 * Don't bother responding if the destination was a broadcast.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
996 * Otherwise initialize tp->rcv_nxt, and tp->irs, select an initial
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
997 * tp->iss, and send a segment:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
998 * <SEQ=ISS><ACK=RCV_NXT><CTL=SYN,ACK>
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
999 * Also initialize tp->snd_nxt to tp->iss+1 and tp->snd_una to tp->iss.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1000 * Fill in remote peer address fields if not previously specified.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1001 * Enter SYN_RECEIVED state, and process any other fields of this
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1002 * segment in this state.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1003 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1004 case TCPS_LISTEN: {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1005 struct mbuf *am;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1006 register struct sockaddr_in *sin;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1007 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1008 register struct sockaddr_in6 *sin6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1009 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1010
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1011 if (tiflags & TH_RST)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1012 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1013 if (tiflags & TH_ACK)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1014 goto dropwithreset;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1015 if ((tiflags & TH_SYN) == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1016 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1017 if (th->th_dport == th->th_sport) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1018 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1019 if (is_ipv6) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1020 if (IN6_ARE_ADDR_EQUAL(&ipv6->ip6_src, &ipv6->ip6_dst))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1021 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1022 } else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1023 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1024 if (ti->ti_dst.s_addr == ti->ti_src.s_addr)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1025 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1026 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1027 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1028 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1029 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1030
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1031 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1032 * RFC1122 4.2.3.10, p. 104: discard bcast/mcast SYN
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1033 * in_broadcast() should never return true on a received
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1034 * packet with M_BCAST not set.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1035 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1036 if (m->m_flags & (M_BCAST|M_MCAST))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1037 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1038 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1039 if (is_ipv6) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1040 /* XXX What about IPv6 Anycasting ?? :-( rja */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1041 if (IN6_IS_ADDR_MULTICAST(&ipv6->ip6_dst))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1042 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1043 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1044 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1045 if (IN_MULTICAST(ti->ti_dst.s_addr))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1046 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1047 am = m_get(M_DONTWAIT, MT_SONAME); /* XXX */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1048 if (am == NULL)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1049 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1050 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1051 if (is_ipv6) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1052 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1053 * This is probably the place to set the tp->pf value.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1054 * (Don't forget to do it in the v4 code as well!)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1055 *
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1056 * Also, remember to blank out things like flowlabel, or
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1057 * set flowlabel for accepted sockets in v6.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1058 *
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1059 * FURTHERMORE, this is PROBABLY the place where the whole
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1060 * business of key munging is set up for passive
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1061 * connections.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1062 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1063 am->m_len = sizeof(struct sockaddr_in6);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1064 sin6 = mtod(am, struct sockaddr_in6 *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1065 sin6->sin6_family = AF_INET6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1066 sin6->sin6_len = sizeof(struct sockaddr_in6);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1067 sin6->sin6_addr = ipv6->ip6_src;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1068 sin6->sin6_port = th->th_sport;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1069 sin6->sin6_flowinfo = htonl(0x0fffffff) &
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1070 inp->inp_ipv6.ip6_flow;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1071 laddr6 = inp->inp_laddr6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1072 if (IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1073 inp->inp_laddr6 = ipv6->ip6_dst;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1074 /* This is a good optimization. */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1075 if (in6_pcbconnect(inp, am)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1076 inp->inp_laddr6 = laddr6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1077 (void) m_free(am);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1078 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1079 } /* endif in6_pcbconnect() */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1080 tp->pf = PF_INET6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1081 } else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1082 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1083 * Letting v4 incoming datagrams to reach valid
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1084 * PF_INET6 sockets causes some overhead here.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1085 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1086 if (inp->inp_flags & INP_IPV6) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1087 if (!(inp->inp_flags & (INP_IPV6_UNDEC|INP_IPV6_MAPPED))) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1088 (void) m_free(am);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1089 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1090 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1091
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1092 am->m_len = sizeof(struct sockaddr_in6);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1093
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1094 sin6 = mtod(am, struct sockaddr_in6 *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1095 sin6->sin6_family = AF_INET6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1096 sin6->sin6_len = sizeof(*sin6);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1097 CREATE_IPV6_MAPPED(sin6->sin6_addr, ti->ti_src.s_addr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1098 sin6->sin6_port = th->th_sport;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1099 sin6->sin6_flowinfo = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1100
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1101 laddr6 = inp->inp_laddr6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1102 if (inp->inp_laddr.s_addr == INADDR_ANY)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1103 CREATE_IPV6_MAPPED(inp->inp_laddr6, ti->ti_dst.s_addr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1104
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1105 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1106 * The pcb initially has the v6 default hoplimit
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1107 * set. We're sending v4 packets so we need to set
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1108 * the v4 ttl and tos.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1109 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1110 inp->inp_ip.ip_ttl = ip_defttl;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1111 inp->inp_ip.ip_tos = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1112
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1113 if (in6_pcbconnect(inp, am)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1114 inp->inp_laddr6 = laddr6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1115 (void) m_freem(am);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1116 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1117 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1118 tp->pf = PF_INET;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1119 } else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1120 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1121 am->m_len = sizeof (struct sockaddr_in);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1122 sin = mtod(am, struct sockaddr_in *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1123 sin->sin_family = AF_INET;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1124 sin->sin_len = sizeof(*sin);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1125 sin->sin_addr = ti->ti_src;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1126 sin->sin_port = ti->ti_sport;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1127 bzero((caddr_t)sin->sin_zero, sizeof(sin->sin_zero));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1128 laddr = inp->inp_laddr;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1129 if (inp->inp_laddr.s_addr == INADDR_ANY)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1130 inp->inp_laddr = ti->ti_dst;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1131 if (in_pcbconnect(inp, am)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1132 inp->inp_laddr = laddr;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1133 (void) m_free(am);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1134 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1135 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1136 (void) m_free(am);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1137 tp->pf = PF_INET;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1138 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1139 } /* if (inp->inp_flags & INP_IPV6) */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1140 } /* if (is_ipv6) */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1141 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1142 tp->t_template = tcp_template(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1143 if (tp->t_template == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1144 tp = tcp_drop(tp, ENOBUFS);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1145 dropsocket = 0; /* socket is already gone */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1146 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1147 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1148 if (optp)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1149 tcp_dooptions(tp, optp, optlen, th,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1150 &ts_present, &ts_val, &ts_ecr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1151 #ifdef TCP_SACK
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1152 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1153 * If peer did not send a SACK_PERMITTED option (i.e., if
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1154 * tcp_dooptions() did not set TF_SACK_PERMIT), set
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1155 * sack_disable to 1 if it is currently 0.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1156 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1157 if (!tp->sack_disable)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1158 if ((tp->t_flags & TF_SACK_PERMIT) == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1159 tp->sack_disable = 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1160 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1161
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1162 if (iss)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1163 tp->iss = iss;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1164 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1165 tp->iss = tcp_iss;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1166 #ifdef TCP_COMPAT_42
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1167 tcp_iss += TCP_ISSINCR/2;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1168 #else /* TCP_COMPAT_42 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1169 tcp_iss += arc4random() % TCP_ISSINCR + 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1170 #endif /* !TCP_COMPAT_42 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1171 tp->irs = th->th_seq;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1172 tcp_sendseqinit(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1173 #if defined (TCP_SACK) || defined (TCP_NEWRENO)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1174 tp->snd_last = tp->snd_una;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1175 #endif /* TCP_SACK || TCP_NEWRENO */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1176 #if defined(TCP_SACK) && defined(TCP_FACK)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1177 tp->snd_fack = tp->snd_una;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1178 tp->retran_data = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1179 tp->snd_awnd = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1180 #endif /* TCP_FACK */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1181 tcp_rcvseqinit(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1182 tp->t_flags |= TF_ACKNOW;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1183 tp->t_state = TCPS_SYN_RECEIVED;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1184 tp->t_timer[TCPT_KEEP] = tcptv_keep_init;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1185 dropsocket = 0; /* committed to socket */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1186 tcpstat.tcps_accepts++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1187 goto trimthenstep6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1188 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1189
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1190 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1191 * If the state is SYN_RECEIVED:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1192 * if seg contains SYN/ACK, send an RST.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1193 * if seg contains an ACK, but not for our SYN/ACK, send an RST
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1194 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1195
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1196 case TCPS_SYN_RECEIVED:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1197 if (tiflags & TH_ACK) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1198 if (tiflags & TH_SYN) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1199 tcpstat.tcps_badsyn++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1200 goto dropwithreset;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1201 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1202 if (SEQ_LEQ(th->th_ack, tp->snd_una) ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1203 SEQ_GT(th->th_ack, tp->snd_max))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1204 goto dropwithreset;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1205 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1206 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1207
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1208 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1209 * If the state is SYN_SENT:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1210 * if seg contains an ACK, but not for our SYN, drop the input.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1211 * if seg contains a RST, then drop the connection.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1212 * if seg does not contain SYN, then drop it.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1213 * Otherwise this is an acceptable SYN segment
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1214 * initialize tp->rcv_nxt and tp->irs
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1215 * if seg contains ack then advance tp->snd_una
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1216 * if SYN has been acked change to ESTABLISHED else SYN_RCVD state
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1217 * arrange for segment to be acked (eventually)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1218 * continue processing rest of data/controls, beginning with URG
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1219 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1220 case TCPS_SYN_SENT:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1221 if ((tiflags & TH_ACK) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1222 (SEQ_LEQ(th->th_ack, tp->iss) ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1223 SEQ_GT(th->th_ack, tp->snd_max)))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1224 goto dropwithreset;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1225 if (tiflags & TH_RST) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1226 if (tiflags & TH_ACK)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1227 tp = tcp_drop(tp, ECONNREFUSED);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1228 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1229 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1230 if ((tiflags & TH_SYN) == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1231 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1232 if (tiflags & TH_ACK) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1233 tp->snd_una = th->th_ack;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1234 if (SEQ_LT(tp->snd_nxt, tp->snd_una))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1235 tp->snd_nxt = tp->snd_una;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1236 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1237 tp->t_timer[TCPT_REXMT] = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1238 tp->irs = th->th_seq;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1239 tcp_rcvseqinit(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1240 tp->t_flags |= TF_ACKNOW;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1241 #ifdef TCP_SACK
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1242 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1243 * If we've sent a SACK_PERMITTED option, and the peer
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1244 * also replied with one, then TF_SACK_PERMIT should have
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1245 * been set in tcp_dooptions(). If it was not, disable SACKs.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1246 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1247 if (!tp->sack_disable)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1248 if ((tp->t_flags & TF_SACK_PERMIT) == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1249 tp->sack_disable = 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1250 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1251 if (tiflags & TH_ACK && SEQ_GT(tp->snd_una, tp->iss)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1252 tcpstat.tcps_connects++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1253 soisconnected(so);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1254 tp->t_state = TCPS_ESTABLISHED;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1255 /* Do window scaling on this connection? */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1256 if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) ==
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1257 (TF_RCVD_SCALE|TF_REQ_SCALE)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1258 tp->snd_scale = tp->requested_s_scale;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1259 tp->rcv_scale = tp->request_r_scale;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1260 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1261 (void) tcp_reass(tp, (struct tcphdr *)0,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1262 (struct mbuf *)0, &tlen);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1263 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1264 * if we didn't have to retransmit the SYN,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1265 * use its rtt as our initial srtt & rtt var.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1266 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1267 if (tp->t_rtt)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1268 tcp_xmit_timer(tp, tp->t_rtt);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1269 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1270 * Since new data was acked (the SYN), open the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1271 * congestion window by one MSS. We do this
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1272 * here, because we won't go through the normal
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1273 * ACK processing below. And since this is the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1274 * start of the connection, we know we are in
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1275 * the exponential phase of slow-start.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1276 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1277 tp->snd_cwnd += tp->t_maxseg;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1278 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1279 tp->t_state = TCPS_SYN_RECEIVED;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1280
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1281 trimthenstep6:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1282 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1283 * Advance ti->ti_seq to correspond to first data byte.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1284 * If data, trim to stay within window,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1285 * dropping FIN if necessary.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1286 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1287 th->th_seq++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1288 if (tlen > tp->rcv_wnd) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1289 todrop = tlen - tp->rcv_wnd;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1290 m_adj(m, -todrop);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1291 tlen = tp->rcv_wnd;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1292 tiflags &= ~TH_FIN;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1293 tcpstat.tcps_rcvpackafterwin++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1294 tcpstat.tcps_rcvbyteafterwin += todrop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1295 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1296 tp->snd_wl1 = th->th_seq - 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1297 tp->rcv_up = th->th_seq;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1298 goto step6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1299 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1300
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1301 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1302 * States other than LISTEN or SYN_SENT.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1303 * First check timestamp, if present.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1304 * Then check that at least some bytes of segment are within
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1305 * receive window. If segment begins before rcv_nxt,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1306 * drop leading data (and SYN); if nothing left, just ack.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1307 *
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1308 * RFC 1323 PAWS: If we have a timestamp reply on this segment
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1309 * and it's less than ts_recent, drop it.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1310 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1311 if (ts_present && (tiflags & TH_RST) == 0 && tp->ts_recent &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1312 TSTMP_LT(ts_val, tp->ts_recent)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1313
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1314 /* Check to see if ts_recent is over 24 days old. */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1315 if ((int)(tcp_now - tp->ts_recent_age) > TCP_PAWS_IDLE) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1316 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1317 * Invalidate ts_recent. If this segment updates
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1318 * ts_recent, the age will be reset later and ts_recent
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1319 * will get a valid value. If it does not, setting
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1320 * ts_recent to zero will at least satisfy the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1321 * requirement that zero be placed in the timestamp
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1322 * echo reply when ts_recent isn't valid. The
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1323 * age isn't reset until we get a valid ts_recent
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1324 * because we don't want out-of-order segments to be
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1325 * dropped when ts_recent is old.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1326 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1327 tp->ts_recent = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1328 } else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1329 tcpstat.tcps_rcvduppack++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1330 tcpstat.tcps_rcvdupbyte += tlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1331 tcpstat.tcps_pawsdrop++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1332 goto dropafterack;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1333 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1334 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1335
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1336 todrop = tp->rcv_nxt - th->th_seq;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1337 if (todrop > 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1338 if (tiflags & TH_SYN) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1339 tiflags &= ~TH_SYN;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1340 th->th_seq++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1341 if (th->th_urp > 1)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1342 th->th_urp--;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1343 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1344 tiflags &= ~TH_URG;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1345 todrop--;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1346 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1347 if (todrop >= tlen ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1348 (todrop == tlen && (tiflags & TH_FIN) == 0)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1349 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1350 * Any valid FIN must be to the left of the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1351 * window. At this point, FIN must be a
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1352 * duplicate or out-of-sequence, so drop it.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1353 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1354 tiflags &= ~TH_FIN;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1355 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1356 * Send ACK to resynchronize, and drop any data,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1357 * but keep on processing for RST or ACK.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1358 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1359 tp->t_flags |= TF_ACKNOW;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1360 tcpstat.tcps_rcvdupbyte += todrop = tlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1361 tcpstat.tcps_rcvduppack++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1362 } else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1363 tcpstat.tcps_rcvpartduppack++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1364 tcpstat.tcps_rcvpartdupbyte += todrop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1365 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1366 hdroptlen += todrop; /* drop from head afterwards */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1367 th->th_seq += todrop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1368 tlen -= todrop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1369 if (th->th_urp > todrop)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1370 th->th_urp -= todrop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1371 else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1372 tiflags &= ~TH_URG;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1373 th->th_urp = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1374 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1375 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1376
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1377 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1378 * If new data are received on a connection after the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1379 * user processes are gone, then RST the other end.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1380 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1381 if ((so->so_state & SS_NOFDREF) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1382 tp->t_state > TCPS_CLOSE_WAIT && tlen) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1383 tp = tcp_close(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1384 tcpstat.tcps_rcvafterclose++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1385 goto dropwithreset;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1386 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1387
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1388 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1389 * If segment ends after window, drop trailing data
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1390 * (and PUSH and FIN); if nothing left, just ACK.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1391 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1392 todrop = (th->th_seq + tlen) - (tp->rcv_nxt+tp->rcv_wnd);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1393 if (todrop > 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1394 tcpstat.tcps_rcvpackafterwin++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1395 if (todrop >= tlen) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1396 tcpstat.tcps_rcvbyteafterwin += tlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1397 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1398 * If a new connection request is received
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1399 * while in TIME_WAIT, drop the old connection
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1400 * and start over if the sequence numbers
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1401 * are above the previous ones.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1402 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1403 if (tiflags & TH_SYN &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1404 tp->t_state == TCPS_TIME_WAIT &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1405 SEQ_GT(th->th_seq, tp->rcv_nxt)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1406 iss = tp->snd_nxt + TCP_ISSINCR;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1407 tp = tcp_close(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1408 goto findpcb;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1409 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1410 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1411 * If window is closed can only take segments at
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1412 * window edge, and have to drop data and PUSH from
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1413 * incoming segments. Continue processing, but
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1414 * remember to ack. Otherwise, drop segment
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1415 * and ack.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1416 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1417 if (tp->rcv_wnd == 0 && th->th_seq == tp->rcv_nxt) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1418 tp->t_flags |= TF_ACKNOW;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1419 tcpstat.tcps_rcvwinprobe++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1420 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1421 goto dropafterack;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1422 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1423 tcpstat.tcps_rcvbyteafterwin += todrop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1424 m_adj(m, -todrop);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1425 tlen -= todrop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1426 tiflags &= ~(TH_PUSH|TH_FIN);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1427 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1428
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1429 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1430 * If last ACK falls within this segment's sequence numbers,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1431 * record its timestamp.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1432 * Fix from Braden, see Stevens p. 870
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1433 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1434 if (ts_present && TSTMP_GEQ(ts_val, tp->ts_recent) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1435 SEQ_LEQ(th->th_seq, tp->last_ack_sent)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1436 tp->ts_recent_age = tcp_now;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1437 tp->ts_recent = ts_val;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1438 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1439
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1440 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1441 * If the RST bit is set examine the state:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1442 * SYN_RECEIVED STATE:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1443 * If passive open, return to LISTEN state.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1444 * If active open, inform user that connection was refused.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1445 * ESTABLISHED, FIN_WAIT_1, FIN_WAIT2, CLOSE_WAIT STATES:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1446 * Inform user that connection was reset, and close tcb.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1447 * CLOSING, LAST_ACK, TIME_WAIT STATES
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1448 * Close the tcb.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1449 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1450 if (tiflags & TH_RST) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1451 #ifndef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1452 if (ti->ti_seq != tp->last_ack_sent)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1453 #else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1454 if (th->th_seq != tp->last_ack_sent)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1455 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1456 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1457
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1458 switch (tp->t_state) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1459 case TCPS_SYN_RECEIVED:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1460 so->so_error = ECONNREFUSED;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1461 goto close;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1462
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1463 case TCPS_ESTABLISHED:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1464 case TCPS_FIN_WAIT_1:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1465 case TCPS_FIN_WAIT_2:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1466 case TCPS_CLOSE_WAIT:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1467 so->so_error = ECONNRESET;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1468 close:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1469 tp->t_state = TCPS_CLOSED;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1470 tcpstat.tcps_drops++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1471 tp = tcp_close(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1472 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1473 case TCPS_CLOSING:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1474 case TCPS_LAST_ACK:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1475 case TCPS_TIME_WAIT:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1476 tp = tcp_close(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1477 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1478 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1479 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1480
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1481 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1482 * If a SYN is in the window, then this is an
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1483 * error and we send an RST and drop the connection.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1484 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1485 if (tiflags & TH_SYN) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1486 tp = tcp_drop(tp, ECONNRESET);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1487 goto dropwithreset;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1488 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1489
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1490 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1491 * If the ACK bit is off we drop the segment and return.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1492 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1493 if ((tiflags & TH_ACK) == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1494 if (tp->t_flags & TF_ACKNOW)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1495 goto dropafterack;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1496 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1497 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1498 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1499
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1500 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1501 * Ack processing.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1502 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1503 switch (tp->t_state) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1504
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1505 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1506 * In SYN_RECEIVED state, the ack ACKs our SYN, so enter
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1507 * ESTABLISHED state and continue processing.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1508 * The ACK was checked above.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1509 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1510 case TCPS_SYN_RECEIVED:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1511 tcpstat.tcps_connects++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1512 soisconnected(so);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1513 tp->t_state = TCPS_ESTABLISHED;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1514 /* Do window scaling? */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1515 if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) ==
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1516 (TF_RCVD_SCALE|TF_REQ_SCALE)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1517 tp->snd_scale = tp->requested_s_scale;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1518 tp->rcv_scale = tp->request_r_scale;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1519 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1520 (void) tcp_reass(tp, (struct tcphdr *)0, (struct mbuf *)0,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1521 &tlen);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1522 tp->snd_wl1 = th->th_seq - 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1523 /* fall into ... */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1524
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1525 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1526 * In ESTABLISHED state: drop duplicate ACKs; ACK out of range
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1527 * ACKs. If the ack is in the range
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1528 * tp->snd_una < ti->ti_ack <= tp->snd_max
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1529 * then advance tp->snd_una to ti->ti_ack and drop
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1530 * data from the retransmission queue. If this ACK reflects
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1531 * more up to date window information we update our window information.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1532 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1533 case TCPS_ESTABLISHED:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1534 case TCPS_FIN_WAIT_1:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1535 case TCPS_FIN_WAIT_2:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1536 case TCPS_CLOSE_WAIT:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1537 case TCPS_CLOSING:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1538 case TCPS_LAST_ACK:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1539 case TCPS_TIME_WAIT:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1540 if (SEQ_LEQ(th->th_ack, tp->snd_una)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1541 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1542 * Duplicate/old ACK processing.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1543 * Increments t_dupacks:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1544 * Pure duplicate (same seq/ack/window, no data)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1545 * Doesn't affect t_dupacks:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1546 * Data packets.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1547 * Normal window updates (window opens)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1548 * Resets t_dupacks:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1549 * New data ACKed.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1550 * Window shrinks
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1551 * Old ACK
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1552 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1553 if (tlen)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1554 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1555 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1556 * If we get an old ACK, there is probably packet
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1557 * reordering going on. Be conservative and reset
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1558 * t_dupacks so that we are less agressive in
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1559 * doing a fast retransmit.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1560 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1561 if (th->th_ack != tp->snd_una) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1562 tp->t_dupacks = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1563 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1564 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1565 if (tiwin == tp->snd_wnd) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1566 tcpstat.tcps_rcvdupack++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1567 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1568 * If we have outstanding data (other than
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1569 * a window probe), this is a completely
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1570 * duplicate ack (ie, window info didn't
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1571 * change), the ack is the biggest we've
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1572 * seen and we've seen exactly our rexmt
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1573 * threshhold of them, assume a packet
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1574 * has been dropped and retransmit it.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1575 * Kludge snd_nxt & the congestion
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1576 * window so we send only this one
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1577 * packet.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1578 *
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1579 * We know we're losing at the current
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1580 * window size so do congestion avoidance
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1581 * (set ssthresh to half the current window
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1582 * and pull our congestion window back to
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1583 * the new ssthresh).
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1584 *
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1585 * Dup acks mean that packets have left the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1586 * network (they're now cached at the receiver)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1587 * so bump cwnd by the amount in the receiver
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1588 * to keep a constant cwnd packets in the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1589 * network.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1590 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1591 if (tp->t_timer[TCPT_REXMT] == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1592 tp->t_dupacks = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1593 #if defined(TCP_SACK) && defined(TCP_FACK)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1594 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1595 * In FACK, can enter fast rec. if the receiver
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1596 * reports a reass. queue longer than 3 segs.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1597 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1598 else if (++tp->t_dupacks == tcprexmtthresh ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1599 ((SEQ_GT(tp->snd_fack, tcprexmtthresh *
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1600 tp->t_maxseg + tp->snd_una)) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1601 SEQ_GT(tp->snd_una, tp->snd_last))) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1602 #else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1603 else if (++tp->t_dupacks == tcprexmtthresh) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1604 #endif /* TCP_FACK */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1605 tcp_seq onxt = tp->snd_nxt;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1606 u_long win =
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1607 ulmin(tp->snd_wnd, tp->snd_cwnd) /
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1608 2 / tp->t_maxseg;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1609
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1610 #if defined(TCP_SACK) || defined(TCP_NEWRENO)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1611 if (SEQ_LT(th->th_ack, tp->snd_last)){
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1612 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1613 * False fast retx after
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1614 * timeout. Do not cut window.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1615 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1616 tp->snd_cwnd += tp->t_maxseg;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1617 tp->t_dupacks = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1618 (void) tcp_output(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1619 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1620 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1621 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1622 if (win < 2)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1623 win = 2;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1624 tp->snd_ssthresh = win * tp->t_maxseg;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1625 #if defined(TCP_SACK) || defined(TCP_NEWRENO)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1626 tp->snd_last = tp->snd_max;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1627 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1628 #ifdef TCP_SACK
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1629 if (!tp->sack_disable) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1630 tp->t_timer[TCPT_REXMT] = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1631 tp->t_rtt = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1632 tcpstat.tcps_sndrexmitfast++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1633 #if defined(TCP_SACK) && defined(TCP_FACK)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1634 (void) tcp_output(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1635 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1636 * During FR, snd_cwnd is held
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1637 * constant for FACK.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1638 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1639 tp->snd_cwnd = tp->snd_ssthresh;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1640 tp->t_dupacks = tcprexmtthresh;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1641 #else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1642 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1643 * tcp_output() will send
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1644 * oldest SACK-eligible rtx.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1645 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1646 (void) tcp_output(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1647 tp->snd_cwnd = tp->snd_ssthresh+
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1648 tp->t_maxseg * tp->t_dupacks;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1649 #endif /* TCP_FACK */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1650 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1651 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1652 #endif /* TCP_SACK */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1653 tp->t_timer[TCPT_REXMT] = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1654 tp->t_rtt = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1655 tp->snd_nxt = th->th_ack;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1656 tp->snd_cwnd = tp->t_maxseg;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1657 tcpstat.tcps_sndrexmitfast++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1658 (void) tcp_output(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1659
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1660 tp->snd_cwnd = tp->snd_ssthresh +
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1661 tp->t_maxseg * tp->t_dupacks;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1662 if (SEQ_GT(onxt, tp->snd_nxt))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1663 tp->snd_nxt = onxt;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1664 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1665 } else if (tp->t_dupacks > tcprexmtthresh) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1666 #if defined(TCP_SACK) && defined(TCP_FACK)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1667 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1668 * while (awnd < cwnd)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1669 * sendsomething();
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1670 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1671 if (!tp->sack_disable) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1672 if (tp->snd_awnd < tp->snd_cwnd)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1673 tcp_output(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1674 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1675 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1676 #endif /* TCP_FACK */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1677 tp->snd_cwnd += tp->t_maxseg;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1678 (void) tcp_output(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1679 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1680 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1681 } else if (tiwin < tp->snd_wnd) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1682 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1683 * The window was retracted! Previous dup
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1684 * ACKs may have been due to packets arriving
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1685 * after the shrunken window, not a missing
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1686 * packet, so play it safe and reset t_dupacks
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1687 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1688 tp->t_dupacks = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1689 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1690 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1691 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1692 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1693 * If the congestion window was inflated to account
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1694 * for the other side's cached packets, retract it.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1695 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1696 #ifdef TCP_NEWRENO
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1697 if (tp->t_dupacks >= tcprexmtthresh && !tcp_newreno(tp, th)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1698 /* Out of fast recovery */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1699 tp->snd_cwnd = tp->snd_ssthresh;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1700 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1701 * Window inflation should have left us with approx.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1702 * snd_ssthresh outstanding data. But in case we
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1703 * would be inclined to send a burst, better to do
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1704 * it via the slow start mechanism.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1705 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1706 if (tcp_seq_subtract(tp->snd_max, th->th_ack) <
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1707 tp->snd_ssthresh)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1708 tp->snd_cwnd = tcp_seq_subtract(tp->snd_max,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1709 th->th_ack) + tp->t_maxseg;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1710 tp->t_dupacks = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1711 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1712 #elif defined(TCP_SACK)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1713 if (!tp->sack_disable) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1714 if (tp->t_dupacks >= tcprexmtthresh) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1715 /* Check for a partial ACK */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1716 if (tcp_sack_partialack(tp, th)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1717 #if defined(TCP_SACK) && defined(TCP_FACK)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1718 /* Force call to tcp_output */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1719 if (tp->snd_awnd < tp->snd_cwnd)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1720 needoutput = 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1721 #else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1722 tp->snd_cwnd += tp->t_maxseg;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1723 needoutput = 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1724 #endif /* TCP_FACK */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1725 } else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1726 /* Out of fast recovery */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1727 tp->snd_cwnd = tp->snd_ssthresh;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1728 if (tcp_seq_subtract(tp->snd_max,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1729 th->th_ack) < tp->snd_ssthresh)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1730 tp->snd_cwnd =
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1731 tcp_seq_subtract(tp->snd_max,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1732 th->th_ack) + tp->t_maxseg;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1733 tp->t_dupacks = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1734 #if defined(TCP_SACK) && defined(TCP_FACK)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1735 if (SEQ_GT(th->th_ack, tp->snd_fack))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1736 tp->snd_fack = th->th_ack;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1737 #endif /* TCP_FACK */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1738 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1739 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1740 } else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1741 if (tp->t_dupacks >= tcprexmtthresh &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1742 !tcp_newreno(tp, th)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1743 /* Out of fast recovery */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1744 tp->snd_cwnd = tp->snd_ssthresh;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1745 if (tcp_seq_subtract(tp->snd_max, th->th_ack) <
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1746 tp->snd_ssthresh)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1747 tp->snd_cwnd =
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1748 tcp_seq_subtract(tp->snd_max,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1749 th->th_ack) + tp->t_maxseg;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1750 tp->t_dupacks = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1751 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1752 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1753 #else /* else neither TCP_NEWRENO nor TCP_SACK */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1754 if (tp->t_dupacks >= tcprexmtthresh &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1755 tp->snd_cwnd > tp->snd_ssthresh)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1756 tp->snd_cwnd = tp->snd_ssthresh;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1757 tp->t_dupacks = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1758 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1759 if (SEQ_GT(th->th_ack, tp->snd_max)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1760 tcpstat.tcps_rcvacktoomuch++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1761 goto dropafterack;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1762 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1763 acked = th->th_ack - tp->snd_una;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1764 tcpstat.tcps_rcvackpack++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1765 tcpstat.tcps_rcvackbyte += acked;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1766
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1767 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1768 * If we have a timestamp reply, update smoothed
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1769 * round trip time. If no timestamp is present but
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1770 * transmit timer is running and timed sequence
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1771 * number was acked, update smoothed round trip time.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1772 * Since we now have an rtt measurement, cancel the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1773 * timer backoff (cf., Phil Karn's retransmit alg.).
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1774 * Recompute the initial retransmit timer.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1775 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1776 if (ts_present)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1777 tcp_xmit_timer(tp, tcp_now-ts_ecr+1);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1778 else if (tp->t_rtt && SEQ_GT(th->th_ack, tp->t_rtseq))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1779 tcp_xmit_timer(tp,tp->t_rtt);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1780
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1781 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1782 * If all outstanding data is acked, stop retransmit
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1783 * timer and remember to restart (more output or persist).
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1784 * If there is more data to be acked, restart retransmit
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1785 * timer, using current (possibly backed-off) value.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1786 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1787 if (th->th_ack == tp->snd_max) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1788 tp->t_timer[TCPT_REXMT] = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1789 needoutput = 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1790 } else if (tp->t_timer[TCPT_PERSIST] == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1791 tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1792 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1793 * When new data is acked, open the congestion window.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1794 * If the window gives us less than ssthresh packets
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1795 * in flight, open exponentially (maxseg per packet).
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1796 * Otherwise open linearly: maxseg per window
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1797 * (maxseg^2 / cwnd per packet).
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1798 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1799 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1800 register u_int cw = tp->snd_cwnd;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1801 register u_int incr = tp->t_maxseg;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1802
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1803 if (cw > tp->snd_ssthresh)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1804 incr = incr * incr / cw;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1805 #if defined (TCP_NEWRENO) || defined (TCP_SACK)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1806 if (SEQ_GEQ(th->th_ack, tp->snd_last))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1807 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1808 tp->snd_cwnd = min(cw + incr, TCP_MAXWIN<<tp->snd_scale);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1809 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1810 ND6_HINT(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1811 if (acked > so->so_snd.sb_cc) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1812 tp->snd_wnd -= so->so_snd.sb_cc;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1813 sbdrop(&so->so_snd, (int)so->so_snd.sb_cc);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1814 ourfinisacked = 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1815 } else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1816 sbdrop(&so->so_snd, acked);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1817 tp->snd_wnd -= acked;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1818 ourfinisacked = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1819 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1820 if (sb_notify(&so->so_snd))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1821 sowwakeup(so);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1822 tp->snd_una = th->th_ack;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1823 if (SEQ_LT(tp->snd_nxt, tp->snd_una))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1824 tp->snd_nxt = tp->snd_una;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1825 #if defined (TCP_SACK) && defined (TCP_FACK)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1826 if (SEQ_GT(tp->snd_una, tp->snd_fack))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1827 tp->snd_fack = tp->snd_una;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1828 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1829
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1830 switch (tp->t_state) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1831
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1832 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1833 * In FIN_WAIT_1 STATE in addition to the processing
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1834 * for the ESTABLISHED state if our FIN is now acknowledged
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1835 * then enter FIN_WAIT_2.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1836 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1837 case TCPS_FIN_WAIT_1:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1838 if (ourfinisacked) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1839 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1840 * If we can't receive any more
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1841 * data, then closing user can proceed.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1842 * Starting the timer is contrary to the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1843 * specification, but if we don't get a FIN
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1844 * we'll hang forever.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1845 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1846 if (so->so_state & SS_CANTRCVMORE) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1847 soisdisconnected(so);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1848 tp->t_timer[TCPT_2MSL] = tcp_maxidle;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1849 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1850 tp->t_state = TCPS_FIN_WAIT_2;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1851 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1852 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1853
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1854 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1855 * In CLOSING STATE in addition to the processing for
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1856 * the ESTABLISHED state if the ACK acknowledges our FIN
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1857 * then enter the TIME-WAIT state, otherwise ignore
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1858 * the segment.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1859 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1860 case TCPS_CLOSING:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1861 if (ourfinisacked) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1862 tp->t_state = TCPS_TIME_WAIT;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1863 tcp_canceltimers(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1864 tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1865 soisdisconnected(so);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1866 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1867 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1868
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1869 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1870 * In LAST_ACK, we may still be waiting for data to drain
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1871 * and/or to be acked, as well as for the ack of our FIN.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1872 * If our FIN is now acknowledged, delete the TCB,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1873 * enter the closed state and return.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1874 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1875 case TCPS_LAST_ACK:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1876 if (ourfinisacked) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1877 tp = tcp_close(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1878 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1879 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1880 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1881
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1882 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1883 * In TIME_WAIT state the only thing that should arrive
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1884 * is a retransmission of the remote FIN. Acknowledge
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1885 * it and restart the finack timer.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1886 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1887 case TCPS_TIME_WAIT:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1888 tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1889 goto dropafterack;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1890 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1891 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1892
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1893 step6:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1894 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1895 * Update window information.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1896 * Don't look at window if no ACK: TAC's send garbage on first SYN.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1897 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1898 if ((tiflags & TH_ACK) && (SEQ_LT(tp->snd_wl1, th->th_seq) ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1899 (tp->snd_wl1 == th->th_seq && SEQ_LT(tp->snd_wl2, th->th_ack)) ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1900 (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1901 /* keep track of pure window updates */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1902 if (tlen == 0 &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1903 tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1904 tcpstat.tcps_rcvwinupd++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1905 tp->snd_wnd = tiwin;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1906 tp->snd_wl1 = th->th_seq;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1907 tp->snd_wl2 = th->th_ack;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1908 if (tp->snd_wnd > tp->max_sndwnd)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1909 tp->max_sndwnd = tp->snd_wnd;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1910 needoutput = 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1911 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1912
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1913 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1914 * Process segments with URG.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1915 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1916 if ((tiflags & TH_URG) && th->th_urp &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1917 TCPS_HAVERCVDFIN(tp->t_state) == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1918 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1919 * This is a kludge, but if we receive and accept
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1920 * random urgent pointers, we'll crash in
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1921 * soreceive. It's hard to imagine someone
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1922 * actually wanting to send this much urgent data.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1923 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1924 if (th->th_urp + so->so_rcv.sb_cc > sb_max) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1925 th->th_urp = 0; /* XXX */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1926 tiflags &= ~TH_URG; /* XXX */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1927 goto dodata; /* XXX */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1928 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1929 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1930 * If this segment advances the known urgent pointer,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1931 * then mark the data stream. This should not happen
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1932 * in CLOSE_WAIT, CLOSING, LAST_ACK or TIME_WAIT STATES since
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1933 * a FIN has been received from the remote side.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1934 * In these states we ignore the URG.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1935 *
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1936 * According to RFC961 (Assigned Protocols),
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1937 * the urgent pointer points to the last octet
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1938 * of urgent data. We continue, however,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1939 * to consider it to indicate the first octet
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1940 * of data past the urgent section as the original
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1941 * spec states (in one of two places).
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1942 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1943 if (SEQ_GT(th->th_seq+th->th_urp, tp->rcv_up)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1944 tp->rcv_up = th->th_seq + th->th_urp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1945 so->so_oobmark = so->so_rcv.sb_cc +
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1946 (tp->rcv_up - tp->rcv_nxt) - 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1947 if (so->so_oobmark == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1948 so->so_state |= SS_RCVATMARK;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1949 sohasoutofband(so);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1950 tp->t_oobflags &= ~(TCPOOB_HAVEDATA | TCPOOB_HADDATA);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1951 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1952 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1953 * Remove out of band data so doesn't get presented to user.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1954 * This can happen independent of advancing the URG pointer,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1955 * but if two URG's are pending at once, some out-of-band
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1956 * data may creep in... ick.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1957 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1958 if (th->th_urp <= (u_int16_t) tlen
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1959 #ifdef SO_OOBINLINE
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1960 && (so->so_options & SO_OOBINLINE) == 0
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1961 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1962 )
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1963 tcp_pulloutofband(so, th->th_urp, m, hdroptlen);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1964 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1965 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1966 * If no out of band data is expected,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1967 * pull receive urgent pointer along
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1968 * with the receive window.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1969 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1970 if (SEQ_GT(tp->rcv_nxt, tp->rcv_up))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1971 tp->rcv_up = tp->rcv_nxt;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1972 dodata: /* XXX */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1973
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1974 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1975 * Process the segment text, merging it into the TCP sequencing queue,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1976 * and arranging for acknowledgment of receipt if necessary.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1977 * This process logically involves adjusting tp->rcv_wnd as data
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1978 * is presented to the user (this happens in tcp_usrreq.c,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1979 * case PRU_RCVD). If a FIN has already been received on this
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1980 * connection then we just ignore the text.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1981 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1982 if ((tlen || (tiflags & TH_FIN)) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1983 TCPS_HAVERCVDFIN(tp->t_state) == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1984 if (th->th_seq == tp->rcv_nxt && tp->segq.lh_first == NULL &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1985 tp->t_state == TCPS_ESTABLISHED) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1986 if (th->th_flags & TH_PUSH)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1987 tp->t_flags |= TF_ACKNOW;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1988 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1989 tp->t_flags |= TF_DELACK;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1990 tp->rcv_nxt += tlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1991 tiflags = th->th_flags & TH_FIN;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1992 tcpstat.tcps_rcvpack++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1993 tcpstat.tcps_rcvbyte += tlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1994 ND6_HINT(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1995 m_adj(m, hdroptlen);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1996 sbappend(&so->so_rcv, m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1997 sorwakeup(so);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1998 } else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
1999 m_adj(m, hdroptlen);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2000 tiflags = tcp_reass(tp, th, m, &tlen);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2001 tp->t_flags |= TF_ACKNOW;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2002 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2003 #ifdef TCP_SACK
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2004 if (!tp->sack_disable)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2005 tcp_update_sack_list(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2006 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2007
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2008 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2009 * variable len never referenced again in modern BSD,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2010 * so why bother computing it ??
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2011 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2012 #if 0
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2013 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2014 * Note the amount of data that peer has sent into
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2015 * our window, in order to estimate the sender's
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2016 * buffer size.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2017 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2018 len = so->so_rcv.sb_hiwat - (tp->rcv_adv - tp->rcv_nxt);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2019 #endif /* 0 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2020 } else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2021 m_freem(m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2022 tiflags &= ~TH_FIN;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2023 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2024
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2025 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2026 * If FIN is received ACK the FIN and let the user know
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2027 * that the connection is closing. Ignore a FIN received before
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2028 * the connection is fully established.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2029 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2030 if ((tiflags & TH_FIN) && TCPS_HAVEESTABLISHED(tp->t_state)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2031 if (TCPS_HAVERCVDFIN(tp->t_state) == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2032 socantrcvmore(so);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2033 tp->t_flags |= TF_ACKNOW;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2034 tp->rcv_nxt++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2035 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2036 switch (tp->t_state) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2037
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2038 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2039 * In ESTABLISHED STATE enter the CLOSE_WAIT state.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2040 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2041 case TCPS_ESTABLISHED:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2042 tp->t_state = TCPS_CLOSE_WAIT;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2043 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2044
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2045 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2046 * If still in FIN_WAIT_1 STATE FIN has not been acked so
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2047 * enter the CLOSING state.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2048 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2049 case TCPS_FIN_WAIT_1:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2050 tp->t_state = TCPS_CLOSING;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2051 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2052
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2053 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2054 * In FIN_WAIT_2 state enter the TIME_WAIT state,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2055 * starting the time-wait timer, turning off the other
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2056 * standard timers.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2057 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2058 case TCPS_FIN_WAIT_2:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2059 tp->t_state = TCPS_TIME_WAIT;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2060 tcp_canceltimers(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2061 tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2062 soisdisconnected(so);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2063 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2064
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2065 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2066 * In TIME_WAIT state restart the 2 MSL time_wait timer.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2067 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2068 case TCPS_TIME_WAIT:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2069 tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2070 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2071 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2072 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2073 if (so->so_options & SO_DEBUG) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2074 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2075 if (tp->pf == PF_INET6)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2076 tcp_trace(TA_INPUT, ostate, tp, (caddr_t) &tcp_saveti6, 0, tlen);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2077 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2078 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2079 tcp_trace(TA_INPUT, ostate, tp, (caddr_t) &tcp_saveti, 0, tlen);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2080 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2081
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2082 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2083 * Return any desired output.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2084 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2085 if (needoutput || (tp->t_flags & TF_ACKNOW)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2086 (void) tcp_output(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2087 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2088 return;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2089
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2090 dropafterack:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2091 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2092 * Generate an ACK dropping incoming segment if it occupies
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2093 * sequence space, where the ACK reflects our state.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2094 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2095 if (tiflags & TH_RST)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2096 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2097 m_freem(m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2098 tp->t_flags |= TF_ACKNOW;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2099 (void) tcp_output(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2100 return;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2101
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2102 dropwithreset:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2103 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2104 * Generate a RST, dropping incoming segment.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2105 * Make ACK acceptable to originator of segment.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2106 * Don't bother to respond if destination was broadcast/multicast.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2107 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2108 if ((tiflags & TH_RST) || m->m_flags & (M_BCAST|M_MCAST))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2109 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2110 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2111 if (is_ipv6) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2112 /* For following calls to tcp_respond */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2113 ti = mtod(m, struct tcpiphdr *);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2114 if (IN6_IS_ADDR_MULTICAST(&ipv6->ip6_dst))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2115 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2116 } else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2117 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2118 if (IN_MULTICAST(ti->ti_dst.s_addr))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2119 goto drop;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2120 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2121 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2122 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2123 if (tiflags & TH_ACK)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2124 tcp_respond(tp, (caddr_t) ti, m, (tcp_seq)0, th->th_ack, TH_RST);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2125 else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2126 if (tiflags & TH_SYN)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2127 tlen++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2128 tcp_respond(tp, (caddr_t) ti, m, th->th_seq+tlen, (tcp_seq)0,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2129 TH_RST|TH_ACK);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2130 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2131 /* destroy temporarily created socket */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2132 if (dropsocket)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2133 (void) soabort(so);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2134 return;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2135
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2136 drop:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2137 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2138 * Drop space held by incoming segment and return.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2139 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2140 if (tp && (tp->t_inpcb->inp_socket->so_options & SO_DEBUG)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2141 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2142 if (tp->pf == PF_INET6)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2143 tcp_trace(TA_DROP, ostate, tp, (caddr_t) &tcp_saveti6, 0, tlen);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2144 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2145 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2146 tcp_trace(TA_DROP, ostate, tp, (caddr_t) &tcp_saveti, 0, tlen);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2147 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2148
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2149 m_freem(m);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2150 /* destroy temporarily created socket */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2151 if (dropsocket)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2152 (void) soabort(so);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2153 return;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2154 #ifndef TUBA_INCLUDE
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2155 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2156
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2157 void
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2158 tcp_dooptions(tp, cp, cnt, th, ts_present, ts_val, ts_ecr)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2159 struct tcpcb *tp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2160 u_char *cp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2161 int cnt;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2162 struct tcphdr *th;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2163 int *ts_present;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2164 u_int32_t *ts_val, *ts_ecr;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2165 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2166 u_int16_t mss = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2167 int opt, optlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2168
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2169 for (; cnt > 0; cnt -= optlen, cp += optlen) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2170 opt = cp[0];
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2171 if (opt == TCPOPT_EOL)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2172 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2173 if (opt == TCPOPT_NOP)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2174 optlen = 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2175 else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2176 optlen = cp[1];
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2177 if (optlen <= 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2178 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2179 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2180 switch (opt) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2181
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2182 default:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2183 continue;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2184
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2185 case TCPOPT_MAXSEG:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2186 if (optlen != TCPOLEN_MAXSEG)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2187 continue;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2188 if (!(th->th_flags & TH_SYN))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2189 continue;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2190 bcopy((char *) cp + 2, (char *) &mss, sizeof(mss));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2191 NTOHS(mss);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2192 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2193
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2194 case TCPOPT_WINDOW:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2195 if (optlen != TCPOLEN_WINDOW)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2196 continue;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2197 if (!(th->th_flags & TH_SYN))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2198 continue;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2199 tp->t_flags |= TF_RCVD_SCALE;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2200 tp->requested_s_scale = min(cp[2], TCP_MAX_WINSHIFT);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2201 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2202
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2203 case TCPOPT_TIMESTAMP:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2204 if (optlen != TCPOLEN_TIMESTAMP)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2205 continue;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2206 *ts_present = 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2207 bcopy((char *)cp + 2, (char *) ts_val, sizeof(*ts_val));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2208 NTOHL(*ts_val);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2209 bcopy((char *)cp + 6, (char *) ts_ecr, sizeof(*ts_ecr));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2210 NTOHL(*ts_ecr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2211
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2212 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2213 * A timestamp received in a SYN makes
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2214 * it ok to send timestamp requests and replies.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2215 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2216 if (th->th_flags & TH_SYN) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2217 tp->t_flags |= TF_RCVD_TSTMP;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2218 tp->ts_recent = *ts_val;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2219 tp->ts_recent_age = tcp_now;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2220 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2221 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2222
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2223 #ifdef TCP_SACK
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2224 case TCPOPT_SACK_PERMITTED:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2225 if (tp->sack_disable || optlen!=TCPOLEN_SACK_PERMITTED)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2226 continue;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2227 if (th->th_flags & TH_SYN)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2228 /* MUST only be set on SYN */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2229 tp->t_flags |= TF_SACK_PERMIT;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2230 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2231 case TCPOPT_SACK:
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2232 if (tcp_sack_option(tp, th, cp, optlen))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2233 continue;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2234 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2235 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2236 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2237 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2238 /* Update t_maxopd and t_maxseg after all options are processed */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2239 if (th->th_flags & TH_SYN)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2240 (void) tcp_mss(tp, mss); /* sets t_maxseg */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2241 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2242
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2243 #if defined(TCP_SACK) || defined(TCP_NEWRENO)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2244 u_long
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2245 tcp_seq_subtract(a, b)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2246 u_long a, b;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2247 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2248 return ((long)(a - b));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2249 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2250 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2251
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2252
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2253 #ifdef TCP_SACK
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2254 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2255 * This function is called upon receipt of new valid data (while not in header
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2256 * prediction mode), and it updates the ordered list of sacks.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2257 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2258 void
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2259 tcp_update_sack_list(tp)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2260 struct tcpcb *tp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2261 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2262 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2263 * First reported block MUST be the most recent one. Subsequent
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2264 * blocks SHOULD be in the order in which they arrived at the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2265 * receiver. These two conditions make the implementation fully
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2266 * compliant with RFC 2018.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2267 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2268 int i, j = 0, count = 0, lastpos = -1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2269 struct sackblk sack, firstsack, temp[MAX_SACK_BLKS];
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2270
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2271 /* First clean up current list of sacks */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2272 for (i = 0; i < tp->rcv_numsacks; i++) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2273 sack = tp->sackblks[i];
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2274 if (sack.start == 0 && sack.end == 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2275 count++; /* count = number of blocks to be discarded */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2276 continue;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2277 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2278 if (SEQ_LEQ(sack.end, tp->rcv_nxt)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2279 tp->sackblks[i].start = tp->sackblks[i].end = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2280 count++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2281 } else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2282 temp[j].start = tp->sackblks[i].start;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2283 temp[j++].end = tp->sackblks[i].end;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2284 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2285 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2286 tp->rcv_numsacks -= count;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2287 if (tp->rcv_numsacks == 0) { /* no sack blocks currently (fast path) */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2288 tcp_clean_sackreport(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2289 if (SEQ_LT(tp->rcv_nxt, tp->rcv_laststart)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2290 /* ==> need first sack block */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2291 tp->sackblks[0].start = tp->rcv_laststart;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2292 tp->sackblks[0].end = tp->rcv_lastend;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2293 tp->rcv_numsacks = 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2294 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2295 return;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2296 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2297 /* Otherwise, sack blocks are already present. */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2298 for (i = 0; i < tp->rcv_numsacks; i++)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2299 tp->sackblks[i] = temp[i]; /* first copy back sack list */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2300 if (SEQ_GEQ(tp->rcv_nxt, tp->rcv_lastend))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2301 return; /* sack list remains unchanged */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2302 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2303 * From here, segment just received should be (part of) the 1st sack.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2304 * Go through list, possibly coalescing sack block entries.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2305 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2306 firstsack.start = tp->rcv_laststart;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2307 firstsack.end = tp->rcv_lastend;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2308 for (i = 0; i < tp->rcv_numsacks; i++) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2309 sack = tp->sackblks[i];
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2310 if (SEQ_LT(sack.end, firstsack.start) ||
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2311 SEQ_GT(sack.start, firstsack.end))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2312 continue; /* no overlap */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2313 if (sack.start == firstsack.start && sack.end == firstsack.end){
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2314 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2315 * identical block; delete it here since we will
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2316 * move it to the front of the list.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2317 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2318 tp->sackblks[i].start = tp->sackblks[i].end = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2319 lastpos = i; /* last posn with a zero entry */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2320 continue;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2321 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2322 if (SEQ_LEQ(sack.start, firstsack.start))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2323 firstsack.start = sack.start; /* merge blocks */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2324 if (SEQ_GEQ(sack.end, firstsack.end))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2325 firstsack.end = sack.end; /* merge blocks */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2326 tp->sackblks[i].start = tp->sackblks[i].end = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2327 lastpos = i; /* last posn with a zero entry */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2328 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2329 if (lastpos != -1) { /* at least one merge */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2330 for (i = 0, j = 1; i < tp->rcv_numsacks; i++) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2331 sack = tp->sackblks[i];
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2332 if (sack.start == 0 && sack.end == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2333 continue;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2334 temp[j++] = sack;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2335 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2336 tp->rcv_numsacks = j; /* including first blk (added later) */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2337 for (i = 1; i < tp->rcv_numsacks; i++) /* now copy back */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2338 tp->sackblks[i] = temp[i];
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2339 } else { /* no merges -- shift sacks by 1 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2340 if (tp->rcv_numsacks < MAX_SACK_BLKS)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2341 tp->rcv_numsacks++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2342 for (i = tp->rcv_numsacks-1; i > 0; i--)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2343 tp->sackblks[i] = tp->sackblks[i-1];
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2344 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2345 tp->sackblks[0] = firstsack;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2346 return;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2347 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2348
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2349 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2350 * Process the TCP SACK option. Returns 1 if tcp_dooptions() should continue,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2351 * and 0 otherwise, if the option was fine. tp->snd_holes is an ordered list
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2352 * of holes (oldest to newest, in terms of the sequence space).
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2353 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2354 int
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2355 tcp_sack_option(tp, th, cp, optlen)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2356 struct tcpcb *tp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2357 struct tcphdr *th;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2358 u_char *cp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2359 int optlen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2360 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2361 int tmp_olen;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2362 u_char *tmp_cp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2363 struct sackhole *cur, *p, *temp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2364
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2365 if (tp->sack_disable)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2366 return 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2367
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2368 /* Note: TCPOLEN_SACK must be 2*sizeof(tcp_seq) */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2369 if (optlen <= 2 || (optlen - 2) % TCPOLEN_SACK != 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2370 return 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2371 tmp_cp = cp + 2;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2372 tmp_olen = optlen - 2;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2373 if (tp->snd_numholes < 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2374 tp->snd_numholes = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2375 if (tp->t_maxseg == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2376 panic("tcp_sack_option"); /* Should never happen */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2377 while (tmp_olen > 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2378 struct sackblk sack;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2379
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2380 bcopy((char *) tmp_cp, (char *) &(sack.start), sizeof(tcp_seq));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2381 NTOHL(sack.start);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2382 bcopy((char *) tmp_cp + sizeof(tcp_seq),
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2383 (char *) &(sack.end), sizeof(tcp_seq));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2384 NTOHL(sack.end);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2385 tmp_olen -= TCPOLEN_SACK;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2386 tmp_cp += TCPOLEN_SACK;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2387 if (SEQ_LEQ(sack.end, sack.start))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2388 continue; /* bad SACK fields */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2389 if (SEQ_LEQ(sack.end, tp->snd_una))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2390 continue; /* old block */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2391 #if defined(TCP_SACK) && defined(TCP_FACK)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2392 /* Updates snd_fack. */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2393 if (SEQ_GEQ(sack.end, tp->snd_fack))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2394 tp->snd_fack = sack.end;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2395 #endif /* TCP_FACK */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2396 if (SEQ_GT(th->th_ack, tp->snd_una)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2397 if (SEQ_LT(sack.start, th->th_ack))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2398 continue;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2399 } else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2400 if (SEQ_LT(sack.start, tp->snd_una))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2401 continue;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2402 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2403 if (SEQ_GT(sack.end, tp->snd_max))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2404 continue;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2405 if (tp->snd_holes == 0) { /* first hole */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2406 tp->snd_holes = (struct sackhole *)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2407 malloc(sizeof(struct sackhole), M_PCB, M_NOWAIT);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2408 if (tp->snd_holes == NULL) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2409 /* ENOBUFS, so ignore SACKed block for now*/
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2410 continue;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2411 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2412 cur = tp->snd_holes;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2413 cur->start = th->th_ack;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2414 cur->end = sack.start;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2415 cur->rxmit = cur->start;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2416 cur->next = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2417 tp->snd_numholes = 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2418 tp->rcv_lastsack = sack.end;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2419 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2420 * dups is at least one. If more data has been
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2421 * SACKed, it can be greater than one.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2422 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2423 cur->dups = min(tcprexmtthresh,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2424 ((sack.end - cur->end)/tp->t_maxseg));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2425 if (cur->dups < 1)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2426 cur->dups = 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2427 continue; /* with next sack block */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2428 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2429 /* Go thru list of holes: p = previous, cur = current */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2430 p = cur = tp->snd_holes;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2431 while (cur) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2432 if (SEQ_LEQ(sack.end, cur->start))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2433 /* SACKs data before the current hole */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2434 break; /* no use going through more holes */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2435 if (SEQ_GEQ(sack.start, cur->end)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2436 /* SACKs data beyond the current hole */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2437 cur->dups++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2438 if ( ((sack.end - cur->end)/tp->t_maxseg) >=
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2439 tcprexmtthresh)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2440 cur->dups = tcprexmtthresh;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2441 p = cur;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2442 cur = cur->next;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2443 continue;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2444 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2445 if (SEQ_LEQ(sack.start, cur->start)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2446 /* Data acks at least the beginning of hole */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2447 #if defined(TCP_SACK) && defined(TCP_FACK)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2448 if (SEQ_GT(sack.end, cur->rxmit))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2449 tp->retran_data -=
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2450 tcp_seq_subtract(cur->rxmit,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2451 cur->start);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2452 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2453 tp->retran_data -=
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2454 tcp_seq_subtract(sack.end,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2455 cur->start);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2456 #endif /* TCP_FACK */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2457 if (SEQ_GEQ(sack.end,cur->end)){
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2458 /* Acks entire hole, so delete hole */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2459 if (p != cur) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2460 p->next = cur->next;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2461 free(cur, M_PCB);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2462 cur = p->next;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2463 } else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2464 cur=cur->next;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2465 free(p, M_PCB);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2466 p = cur;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2467 tp->snd_holes = p;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2468 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2469 tp->snd_numholes--;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2470 continue;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2471 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2472 /* otherwise, move start of hole forward */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2473 cur->start = sack.end;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2474 cur->rxmit = max (cur->rxmit, cur->start);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2475 p = cur;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2476 cur = cur->next;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2477 continue;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2478 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2479 /* move end of hole backward */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2480 if (SEQ_GEQ(sack.end, cur->end)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2481 #if defined(TCP_SACK) && defined(TCP_FACK)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2482 if (SEQ_GT(cur->rxmit, sack.start))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2483 tp->retran_data -=
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2484 tcp_seq_subtract(cur->rxmit,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2485 sack.start);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2486 #endif /* TCP_FACK */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2487 cur->end = sack.start;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2488 cur->rxmit = min (cur->rxmit, cur->end);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2489 cur->dups++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2490 if ( ((sack.end - cur->end)/tp->t_maxseg) >=
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2491 tcprexmtthresh)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2492 cur->dups = tcprexmtthresh;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2493 p = cur;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2494 cur = cur->next;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2495 continue;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2496 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2497 if (SEQ_LT(cur->start, sack.start) &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2498 SEQ_GT(cur->end, sack.end)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2499 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2500 * ACKs some data in middle of a hole; need to
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2501 * split current hole
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2502 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2503 temp = (struct sackhole *)malloc(sizeof(*temp),
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2504 M_PCB,M_NOWAIT);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2505 if (temp == NULL)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2506 continue; /* ENOBUFS */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2507 #if defined(TCP_SACK) && defined(TCP_FACK)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2508 if (SEQ_GT(cur->rxmit, sack.end))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2509 tp->retran_data -=
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2510 tcp_seq_subtract(sack.end,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2511 sack.start);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2512 else if (SEQ_GT(cur->rxmit, sack.start))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2513 tp->retran_data -=
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2514 tcp_seq_subtract(cur->rxmit,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2515 sack.start);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2516 #endif /* TCP_FACK */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2517 temp->next = cur->next;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2518 temp->start = sack.end;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2519 temp->end = cur->end;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2520 temp->dups = cur->dups;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2521 temp->rxmit = max (cur->rxmit, temp->start);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2522 cur->end = sack.start;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2523 cur->rxmit = min (cur->rxmit, cur->end);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2524 cur->dups++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2525 if ( ((sack.end - cur->end)/tp->t_maxseg) >=
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2526 tcprexmtthresh)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2527 cur->dups = tcprexmtthresh;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2528 cur->next = temp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2529 p = temp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2530 cur = p->next;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2531 tp->snd_numholes++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2532 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2533 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2534 /* At this point, p points to the last hole on the list */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2535 if (SEQ_LT(tp->rcv_lastsack, sack.start)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2536 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2537 * Need to append new hole at end.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2538 * Last hole is p (and it's not NULL).
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2539 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2540 temp = (struct sackhole *) malloc(sizeof(*temp),
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2541 M_PCB, M_NOWAIT);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2542 if (temp == NULL)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2543 continue; /* ENOBUFS */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2544 temp->start = tp->rcv_lastsack;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2545 temp->end = sack.start;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2546 temp->dups = min(tcprexmtthresh,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2547 ((sack.end - sack.start)/tp->t_maxseg));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2548 if (temp->dups < 1)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2549 temp->dups = 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2550 temp->rxmit = temp->start;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2551 temp->next = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2552 p->next = temp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2553 tp->rcv_lastsack = sack.end;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2554 tp->snd_numholes++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2555 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2556 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2557 #if defined(TCP_SACK) && defined(TCP_FACK)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2558 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2559 * Update retran_data and snd_awnd. Go through the list of
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2560 * holes. Increment retran_data by (hole->rxmit - hole->start).
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2561 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2562 tp->retran_data = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2563 cur = tp->snd_holes;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2564 while (cur) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2565 tp->retran_data += cur->rxmit - cur->start;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2566 cur = cur->next;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2567 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2568 tp->snd_awnd = tcp_seq_subtract(tp->snd_nxt, tp->snd_fack) +
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2569 tp->retran_data;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2570 #endif /* TCP_FACK */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2571
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2572 return 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2573 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2574
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2575 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2576 * Delete stale (i.e, cumulatively ack'd) holes. Hole is deleted only if
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2577 * it is completely acked; otherwise, tcp_sack_option(), called from
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2578 * tcp_dooptions(), will fix up the hole.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2579 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2580 void
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2581 tcp_del_sackholes(tp, th)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2582 struct tcpcb *tp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2583 struct tcphdr *th;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2584 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2585 if (!tp->sack_disable && tp->t_state != TCPS_LISTEN) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2586 /* max because this could be an older ack just arrived */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2587 tcp_seq lastack = SEQ_GT(th->th_ack, tp->snd_una) ?
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2588 th->th_ack : tp->snd_una;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2589 struct sackhole *cur = tp->snd_holes;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2590 struct sackhole *prev = cur;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2591 while (cur)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2592 if (SEQ_LEQ(cur->end, lastack)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2593 cur = cur->next;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2594 free(prev, M_PCB);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2595 prev = cur;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2596 tp->snd_numholes--;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2597 } else if (SEQ_LT(cur->start, lastack)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2598 cur->start = lastack;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2599 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2600 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2601 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2602 tp->snd_holes = cur;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2603 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2604 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2605
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2606 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2607 * Delete all receiver-side SACK information.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2608 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2609 void
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2610 tcp_clean_sackreport(tp)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2611 struct tcpcb *tp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2612 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2613 int i;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2614
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2615 tp->rcv_numsacks = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2616 for (i = 0; i < MAX_SACK_BLKS; i++)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2617 tp->sackblks[i].start = tp->sackblks[i].end=0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2618
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2619 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2620
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2621 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2622 * Checks for partial ack. If partial ack arrives, turn off retransmission
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2623 * timer, deflate the window, do not clear tp->t_dupacks, and return 1.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2624 * If the ack advances at least to tp->snd_last, return 0.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2625 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2626 int
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2627 tcp_sack_partialack(tp, th)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2628 struct tcpcb *tp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2629 struct tcphdr *th;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2630 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2631 if (SEQ_LT(th->th_ack, tp->snd_last)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2632 /* Turn off retx. timer (will start again next segment) */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2633 tp->t_timer[TCPT_REXMT] = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2634 tp->t_rtt = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2635 #ifndef TCP_FACK
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2636 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2637 * Partial window deflation. This statement relies on the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2638 * fact that tp->snd_una has not been updated yet. In FACK
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2639 * hold snd_cwnd constant during fast recovery.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2640 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2641 tp->snd_cwnd -= (th->th_ack - tp->snd_una - tp->t_maxseg);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2642 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2643 return 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2644 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2645 return 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2646 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2647 #endif TCP_SACK
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2648
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2649 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2650 * Pull out of band byte out of a segment so
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2651 * it doesn't appear in the user's data queue.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2652 * It is still reflected in the segment length for
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2653 * sequencing purposes.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2654 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2655 void
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2656 tcp_pulloutofband(so, urgent, m, off)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2657 struct socket *so;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2658 u_int urgent;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2659 register struct mbuf *m;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2660 int off;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2661 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2662 int cnt = off + urgent - 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2663
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2664 while (cnt >= 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2665 if (m->m_len > cnt) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2666 char *cp = mtod(m, caddr_t) + cnt;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2667 struct tcpcb *tp = sototcpcb(so);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2668
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2669 tp->t_iobc = *cp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2670 tp->t_oobflags |= TCPOOB_HAVEDATA;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2671 bcopy(cp+1, cp, (unsigned)(m->m_len - cnt - 1));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2672 m->m_len--;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2673 return;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2674 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2675 cnt -= m->m_len;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2676 m = m->m_next;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2677 if (m == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2678 break;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2679 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2680 panic("tcp_pulloutofband");
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2681 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2682
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2683 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2684 * Collect new round-trip time estimate
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2685 * and update averages and current timeout.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2686 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2687 void
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2688 tcp_xmit_timer(tp, rtt)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2689 register struct tcpcb *tp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2690 short rtt;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2691 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2692 register short delta;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2693 short rttmin;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2694
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2695 tcpstat.tcps_rttupdated++;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2696 --rtt;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2697 if (tp->t_srtt != 0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2698 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2699 * srtt is stored as fixed point with 3 bits after the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2700 * binary point (i.e., scaled by 8). The following magic
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2701 * is equivalent to the smoothing algorithm in rfc793 with
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2702 * an alpha of .875 (srtt = rtt/8 + srtt*7/8 in fixed
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2703 * point). Adjust rtt to origin 0.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2704 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2705 delta = (rtt << 2) - (tp->t_srtt >> TCP_RTT_SHIFT);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2706 if ((tp->t_srtt += delta) <= 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2707 tp->t_srtt = 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2708 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2709 * We accumulate a smoothed rtt variance (actually, a
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2710 * smoothed mean difference), then set the retransmit
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2711 * timer to smoothed rtt + 4 times the smoothed variance.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2712 * rttvar is stored as fixed point with 2 bits after the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2713 * binary point (scaled by 4). The following is
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2714 * equivalent to rfc793 smoothing with an alpha of .75
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2715 * (rttvar = rttvar*3/4 + |delta| / 4). This replaces
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2716 * rfc793's wired-in beta.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2717 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2718 if (delta < 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2719 delta = -delta;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2720 delta -= (tp->t_rttvar >> TCP_RTTVAR_SHIFT);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2721 if ((tp->t_rttvar += delta) <= 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2722 tp->t_rttvar = 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2723 } else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2724 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2725 * No rtt measurement yet - use the unsmoothed rtt.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2726 * Set the variance to half the rtt (so our first
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2727 * retransmit happens at 3*rtt).
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2728 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2729 tp->t_srtt = rtt << (TCP_RTT_SHIFT + 2);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2730 tp->t_rttvar = rtt << (TCP_RTTVAR_SHIFT + 2 - 1);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2731 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2732 tp->t_rtt = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2733 tp->t_rxtshift = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2734
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2735 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2736 * the retransmit should happen at rtt + 4 * rttvar.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2737 * Because of the way we do the smoothing, srtt and rttvar
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2738 * will each average +1/2 tick of bias. When we compute
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2739 * the retransmit timer, we want 1/2 tick of rounding and
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2740 * 1 extra tick because of +-1/2 tick uncertainty in the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2741 * firing of the timer. The bias will give us exactly the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2742 * 1.5 tick we need. But, because the bias is
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2743 * statistical, we have to test that we don't drop below
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2744 * the minimum feasible timer (which is 2 ticks).
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2745 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2746 if (tp->t_rttmin > rtt + 2)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2747 rttmin = tp->t_rttmin;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2748 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2749 rttmin = rtt + 2;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2750 TCPT_RANGESET(tp->t_rxtcur, TCP_REXMTVAL(tp), rttmin, TCPTV_REXMTMAX);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2751
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2752 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2753 * We received an ack for a packet that wasn't retransmitted;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2754 * it is probably safe to discard any error indications we've
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2755 * received recently. This isn't quite right, but close enough
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2756 * for now (a route might have failed after we sent a segment,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2757 * and the return path might not be symmetrical).
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2758 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2759 tp->t_softerror = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2760 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2761
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2762 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2763 * Determine a reasonable value for maxseg size.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2764 * If the route is known, check route for mtu.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2765 * If none, use an mss that can be handled on the outgoing
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2766 * interface without forcing IP to fragment; if bigger than
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2767 * an mbuf cluster (MCLBYTES), round down to nearest multiple of MCLBYTES
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2768 * to utilize large mbufs. If no route is found, route has no mtu,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2769 * or the destination isn't local, use a default, hopefully conservative
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2770 * size (usually 512 or the default IP max size, but no more than the mtu
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2771 * of the interface), as we can't discover anything about intervening
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2772 * gateways or networks. We also initialize the congestion/slow start
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2773 * window to be a single segment if the destination isn't local.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2774 * While looking at the routing entry, we also initialize other path-dependent
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2775 * parameters from pre-set or cached values in the routing entry.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2776 *
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2777 * Also take into account the space needed for options that we
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2778 * send regularly. Make maxseg shorter by that amount to assure
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2779 * that we can send maxseg amount of data even when the options
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2780 * are present. Store the upper limit of the length of options plus
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2781 * data in maxopd.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2782 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2783 int
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2784 tcp_mss(tp, offer)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2785 register struct tcpcb *tp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2786 u_int offer;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2787 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2788 struct route *ro;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2789 register struct rtentry *rt;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2790 struct ifnet *ifp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2791 register int rtt, mss;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2792 u_long bufsize;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2793 struct inpcb *inp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2794 struct socket *so;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2795
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2796 inp = tp->t_inpcb;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2797 ro = &inp->inp_route;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2798 so = inp->inp_socket;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2799
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2800 if ((rt = ro->ro_rt) == (struct rtentry *)0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2801 /* No route yet, so try to acquire one */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2802 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2803 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2804 * Get a new IPv6 route if an IPv6 destination, otherwise, get
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2805 * and IPv4 route (including those pesky IPv4-mapped addresses).
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2806 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2807 bzero(ro,sizeof(struct route_in6));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2808 if (sotopf(so) == AF_INET6) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2809 if (IN6_IS_ADDR_V4MAPPED(&inp->inp_faddr6)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2810 /* Get an IPv4 route. */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2811 ro->ro_dst.sa_family = AF_INET;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2812 ro->ro_dst.sa_len = sizeof(ro->ro_dst);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2813 ((struct sockaddr_in *) &ro->ro_dst)->sin_addr =
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2814 inp->inp_faddr;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2815 rtalloc(ro);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2816 } else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2817 ro->ro_dst.sa_family = AF_INET6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2818 ro->ro_dst.sa_len = sizeof(struct sockaddr_in6);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2819 ((struct sockaddr_in6 *) &ro->ro_dst)->sin6_addr =
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2820 inp->inp_faddr6;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2821 rtalloc(ro);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2822 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2823 } else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2824 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2825 if (inp->inp_faddr.s_addr != INADDR_ANY) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2826 ro->ro_dst.sa_family = AF_INET;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2827 ro->ro_dst.sa_len = sizeof(ro->ro_dst);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2828 satosin(&ro->ro_dst)->sin_addr = inp->inp_faddr;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2829 rtalloc(ro);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2830 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2831 if ((rt = ro->ro_rt) == (struct rtentry *)0) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2832 tp->t_maxopd = tp->t_maxseg = tcp_mssdflt;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2833 return (tcp_mssdflt);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2834 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2835 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2836 ifp = rt->rt_ifp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2837
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2838 #ifdef RTV_MTU /* if route characteristics exist ... */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2839 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2840 * While we're here, check if there's an initial rtt
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2841 * or rttvar. Convert from the route-table units
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2842 * to scaled multiples of the slow timeout timer.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2843 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2844 if (tp->t_srtt == 0 && (rtt = rt->rt_rmx.rmx_rtt)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2845 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2846 * XXX the lock bit for MTU indicates that the value
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2847 * is also a minimum value; this is subject to time.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2848 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2849 if (rt->rt_rmx.rmx_locks & RTV_RTT)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2850 TCPT_RANGESET(tp->t_rttmin,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2851 rtt / (RTM_RTTUNIT / PR_SLOWHZ),
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2852 TCPTV_MIN, TCPTV_REXMTMAX);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2853 tp->t_srtt = rtt / (RTM_RTTUNIT / (PR_SLOWHZ * TCP_RTT_SCALE));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2854 if (rt->rt_rmx.rmx_rttvar)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2855 tp->t_rttvar = rt->rt_rmx.rmx_rttvar /
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2856 (RTM_RTTUNIT / (PR_SLOWHZ * TCP_RTTVAR_SCALE));
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2857 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2858 /* default variation is +- 1 rtt */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2859 tp->t_rttvar =
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2860 tp->t_srtt * TCP_RTTVAR_SCALE / TCP_RTT_SCALE;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2861 TCPT_RANGESET((long) tp->t_rxtcur,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2862 ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2863 tp->t_rttmin, TCPTV_REXMTMAX);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2864 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2865 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2866 * if there's an mtu associated with the route, use it
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2867 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2868 if (rt->rt_rmx.rmx_mtu)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2869 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2870 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2871 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2872 * One may wish to lower MSS to take into account options,
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2873 * especially security-related options.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2874 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2875 if (tp->pf == AF_INET6)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2876 mss = rt->rt_rmx.rmx_mtu - sizeof(struct tcpipv6hdr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2877 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2878 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2879 mss = rt->rt_rmx.rmx_mtu - sizeof(struct tcpiphdr);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2880 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2881 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2882 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2883 else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2884 #endif /* RTV_MTU */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2885 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2886 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2887 * ifp may be null and rmx_mtu may be zero in certain
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2888 * v6 cases (e.g., if ND wasn't able to resolve the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2889 * destination host.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2890 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2891 mss = ifp ? ifp->if_mtu - sizeof(struct tcpiphdr) : 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2892 #ifdef INET6
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2893 if (tp->pf == AF_INET)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2894 #endif /* INET6 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2895 if (!in_localaddr(inp->inp_faddr))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2896 mss = min(mss, tcp_mssdflt);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2897 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2898 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2899 * The current mss, t_maxseg, is initialized to the default value.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2900 * If we compute a smaller value, reduce the current mss.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2901 * If we compute a larger value, return it for use in sending
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2902 * a max seg size option, but don't store it for use
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2903 * unless we received an offer at least that large from peer.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2904 * However, do not accept offers under 32 bytes.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2905 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2906 if (offer)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2907 mss = min(mss, offer);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2908 mss = max(mss, 64); /* sanity - at least max opt. space */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2909 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2910 * maxopd stores the maximum length of data AND options
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2911 * in a segment; maxseg is the amount of data in a normal
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2912 * segment. We need to store this value (maxopd) apart
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2913 * from maxseg, because now every segment carries options
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2914 * and thus we normally have somewhat less data in segments.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2915 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2916 tp->t_maxopd = mss;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2917
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2918 if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP &&
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2919 (tp->t_flags & TF_RCVD_TSTMP) == TF_RCVD_TSTMP)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2920 mss -= TCPOLEN_TSTAMP_APPA;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2921
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2922 #if (MCLBYTES & (MCLBYTES - 1)) == 0
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2923 if (mss > MCLBYTES)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2924 mss &= ~(MCLBYTES-1);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2925 #else
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2926 if (mss > MCLBYTES)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2927 mss = mss / MCLBYTES * MCLBYTES;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2928 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2929 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2930 * If there's a pipesize, change the socket buffer
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2931 * to that size. Make the socket buffers an integral
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2932 * number of mss units; if the mss is larger than
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2933 * the socket buffer, decrease the mss.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2934 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2935 #ifdef RTV_SPIPE
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2936 if ((bufsize = rt->rt_rmx.rmx_sendpipe) == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2937 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2938 bufsize = so->so_snd.sb_hiwat;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2939 if (bufsize < mss)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2940 mss = bufsize;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2941 else {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2942 bufsize = roundup(bufsize, mss);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2943 if (bufsize > sb_max)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2944 bufsize = sb_max;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2945 (void)sbreserve(&so->so_snd, bufsize);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2946 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2947 tp->t_maxseg = mss;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2948
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2949 #ifdef RTV_RPIPE
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2950 if ((bufsize = rt->rt_rmx.rmx_recvpipe) == 0)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2951 #endif
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2952 bufsize = so->so_rcv.sb_hiwat;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2953 if (bufsize > mss) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2954 bufsize = roundup(bufsize, mss);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2955 if (bufsize > sb_max)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2956 bufsize = sb_max;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2957 (void)sbreserve(&so->so_rcv, bufsize);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2958 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2959 tp->snd_cwnd = mss;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2960
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2961 #ifdef RTV_SSTHRESH
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2962 if (rt->rt_rmx.rmx_ssthresh) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2963 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2964 * There's some sort of gateway or interface
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2965 * buffer limit on the path. Use this to set
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2966 * the slow start threshhold, but set the
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2967 * threshold to no less than 2*mss.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2968 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2969 tp->snd_ssthresh = max(2 * mss, rt->rt_rmx.rmx_ssthresh);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2970 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2971 #endif /* RTV_MTU */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2972 return (mss);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2973 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2974 #endif /* TUBA_INCLUDE */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2975
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2976 #if defined(TCP_NEWRENO) || defined (TCP_SACK)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2977 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2978 * Checks for partial ack. If partial ack arrives, force the retransmission
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2979 * of the next unacknowledged segment, do not clear tp->t_dupacks, and return
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2980 * 1. By setting snd_nxt to ti_ack, this forces retransmission timer to
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2981 * be started again. If the ack advances at least to tp->snd_last, return 0.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2982 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2983 int
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2984 tcp_newreno(tp, th)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2985 struct tcpcb *tp;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2986 struct tcphdr *th;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2987 {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2988 if (SEQ_LT(th->th_ack, tp->snd_last)) {
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2989 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2990 * snd_una has not been updated and the socket send buffer
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2991 * not yet drained of the acked data, so we have to leave
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2992 * snd_una as it was to get the correct data offset in
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2993 * tcp_output().
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2994 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2995 tcp_seq onxt = tp->snd_nxt;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2996 u_long ocwnd = tp->snd_cwnd;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2997 tp->t_timer[TCPT_REXMT] = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2998 tp->t_rtt = 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
2999 tp->snd_nxt = th->th_ack;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
3000 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
3001 * Set snd_cwnd to one segment beyond acknowledged offset
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
3002 * (tp->snd_una not yet updated when this function is called)
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
3003 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
3004 tp->snd_cwnd = tp->t_maxseg + (th->th_ack - tp->snd_una);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
3005 (void) tcp_output(tp);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
3006 tp->snd_cwnd = ocwnd;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
3007 if (SEQ_GT(onxt, tp->snd_nxt))
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
3008 tp->snd_nxt = onxt;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
3009 /*
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
3010 * Partial window deflation. Relies on fact that tp->snd_una
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
3011 * not updated yet.
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
3012 */
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
3013 tp->snd_cwnd -= (th->th_ack - tp->snd_una - tp->t_maxseg);
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
3014 return 1;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
3015 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
3016 return 0;
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
3017 }
ced4577552cd Merge from eCos master repository on 2000-06-06-08:44:00-BST
jlarmour
parents:
diff changeset
3018 #endif /* TCP_NEWRENO || TCP_SACK */