tcp_subr.c (c3229e05a368643ab2e7e7c210b40586d041ba04) | tcp_subr.c (3d4d47f39858441d8b8625898e74563f7b60e2b5) |
---|---|
1/* 2 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 17 unchanged lines hidden (view full) --- 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)tcp_subr.c 8.2 (Berkeley) 5/24/95 | 1/* 2 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 17 unchanged lines hidden (view full) --- 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)tcp_subr.c 8.2 (Berkeley) 5/24/95 |
34 * $Id: tcp_subr.c,v 1.41 1998/01/25 04:23:32 eivind Exp $ | 34 * $Id: tcp_subr.c,v 1.42 1998/01/27 09:15:10 davidg Exp $ |
35 */ 36 37#include "opt_compat.h" 38#include "opt_tcpdebug.h" 39 40#include <sys/param.h> 41#include <sys/systm.h> 42#include <sys/kernel.h> 43#include <sys/sysctl.h> 44#include <sys/malloc.h> 45#include <sys/mbuf.h> 46#include <sys/socket.h> 47#include <sys/socketvar.h> 48#include <sys/protosw.h> | 35 */ 36 37#include "opt_compat.h" 38#include "opt_tcpdebug.h" 39 40#include <sys/param.h> 41#include <sys/systm.h> 42#include <sys/kernel.h> 43#include <sys/sysctl.h> 44#include <sys/malloc.h> 45#include <sys/mbuf.h> 46#include <sys/socket.h> 47#include <sys/socketvar.h> 48#include <sys/protosw.h> |
49#include <vm/vm_zone.h> |
|
49 50#include <net/route.h> 51#include <net/if.h> 52 53#define _IP_VHL 54#include <netinet/in.h> 55#include <netinet/in_systm.h> 56#include <netinet/ip.h> --- 32 unchanged lines hidden (view full) --- 89/* 90 * Target size of TCP PCB hash tables. Must be a power of two. 91 */ 92#ifndef TCBHASHSIZE 93#define TCBHASHSIZE 512 94#endif 95 96/* | 50 51#include <net/route.h> 52#include <net/if.h> 53 54#define _IP_VHL 55#include <netinet/in.h> 56#include <netinet/in_systm.h> 57#include <netinet/ip.h> --- 32 unchanged lines hidden (view full) --- 90/* 91 * Target size of TCP PCB hash tables. Must be a power of two. 92 */ 93#ifndef TCBHASHSIZE 94#define TCBHASHSIZE 512 95#endif 96 97/* |
98 * This is the actual shape of what we allocate using the zone 99 * allocator. Doing it this way allows us to protect both structures 100 * using the same generation count, and also eliminates the overhead 101 * of allocating tcpcbs separately. By hiding the structure here, 102 * we avoid changing most of the rest of the code (although it needs 103 * to be changed, eventually, for greater efficiency). 104 */ 105#define ALIGNMENT 32 106#define ALIGNM1 (ALIGNMENT-1) 107struct inp_tp { 108 union { 109 struct inpcb inp; 110 char align[(sizeof(struct inpcb) + ALIGNM1) & ~ALIGNM1]; 111 } inp_tp_u; 112 struct tcpcb tcb; 113}; 114#undef ALIGNMENT 115#undef ALIGNM1 116 117/* |
|
97 * Tcp initialization 98 */ 99void 100tcp_init() 101{ 102 103 tcp_iss = random(); /* wrong, but better than a constant */ 104 tcp_ccgen = 1; 105 tcp_cleartaocache(); 106 LIST_INIT(&tcb); 107 tcbinfo.listhead = &tcb; 108 tcbinfo.hashbase = hashinit(TCBHASHSIZE, M_PCB, &tcbinfo.hashmask); 109 tcbinfo.porthashbase = hashinit(TCBHASHSIZE, M_PCB, &tcbinfo.porthashmask); | 118 * Tcp initialization 119 */ 120void 121tcp_init() 122{ 123 124 tcp_iss = random(); /* wrong, but better than a constant */ 125 tcp_ccgen = 1; 126 tcp_cleartaocache(); 127 LIST_INIT(&tcb); 128 tcbinfo.listhead = &tcb; 129 tcbinfo.hashbase = hashinit(TCBHASHSIZE, M_PCB, &tcbinfo.hashmask); 130 tcbinfo.porthashbase = hashinit(TCBHASHSIZE, M_PCB, &tcbinfo.porthashmask); |
131 /* For the moment, we just worry about putting inpcbs here. */ 132 /* 133 * Rationale for a maximum of `nmbclusters': 134 * 1) It's a convenient value, sized by config, based on 135 * parameters already known to be tweakable as needed 136 * for network-intensive systems. 137 * 2) Under the Old World Order, when pcbs were stored in 138 * mbufs, it was of course impossible to have more 139 * pcbs than mbufs. 140 * 3) The zone allocator doesn't allocate physical memory 141 * for this many pcbs; it just sizes the virtual 142 * address space appropriately. Thus, even for very large 143 * values of nmbclusters, we don't actually take up much 144 * memory unless required. 145 */ 146 tcbinfo.ipi_zone = zinit("tcpcb", sizeof(struct inp_tp), nmbclusters, 147 ZONE_INTERRUPT, 0); |
|
110 if (max_protohdr < sizeof(struct tcpiphdr)) 111 max_protohdr = sizeof(struct tcpiphdr); 112 if (max_linkhdr + sizeof(struct tcpiphdr) > MHLEN) 113 panic("tcp_init"); 114} 115 116/* 117 * Create template to be used to send tcp packets on a connection. --- 123 unchanged lines hidden (view full) --- 241 if (ro == &sro && ro->ro_rt) { 242 RTFREE(ro->ro_rt); 243 } 244} 245 246/* 247 * Create a new TCP control block, making an 248 * empty reassembly queue and hooking it to the argument | 148 if (max_protohdr < sizeof(struct tcpiphdr)) 149 max_protohdr = sizeof(struct tcpiphdr); 150 if (max_linkhdr + sizeof(struct tcpiphdr) > MHLEN) 151 panic("tcp_init"); 152} 153 154/* 155 * Create template to be used to send tcp packets on a connection. --- 123 unchanged lines hidden (view full) --- 279 if (ro == &sro && ro->ro_rt) { 280 RTFREE(ro->ro_rt); 281 } 282} 283 284/* 285 * Create a new TCP control block, making an 286 * empty reassembly queue and hooking it to the argument |
249 * protocol control block. | 287 * protocol control block. The `inp' parameter must have 288 * come from the zone allocator set up in tcp_init(). |
250 */ 251struct tcpcb * 252tcp_newtcpcb(inp) 253 struct inpcb *inp; 254{ | 289 */ 290struct tcpcb * 291tcp_newtcpcb(inp) 292 struct inpcb *inp; 293{ |
294 struct inp_tp *it; |
|
255 register struct tcpcb *tp; 256 | 295 register struct tcpcb *tp; 296 |
257 tp = malloc(sizeof(*tp), M_PCB, M_NOWAIT); 258 if (tp == NULL) 259 return ((struct tcpcb *)0); | 297 it = (struct inp_tp *)inp; 298 tp = &it->tcb; |
260 bzero((char *) tp, sizeof(struct tcpcb)); 261 tp->seg_next = tp->seg_prev = (struct tcpiphdr *)tp; 262 tp->t_maxseg = tp->t_maxopd = tcp_mssdflt; 263 264 if (tcp_do_rfc1323) 265 tp->t_flags = (TF_REQ_SCALE|TF_REQ_TSTMP); 266 if (tcp_do_rfc1644) 267 tp->t_flags |= TF_REQ_CC; | 299 bzero((char *) tp, sizeof(struct tcpcb)); 300 tp->seg_next = tp->seg_prev = (struct tcpiphdr *)tp; 301 tp->t_maxseg = tp->t_maxopd = tcp_mssdflt; 302 303 if (tcp_do_rfc1323) 304 tp->t_flags = (TF_REQ_SCALE|TF_REQ_TSTMP); 305 if (tcp_do_rfc1644) 306 tp->t_flags |= TF_REQ_CC; |
268 tp->t_inpcb = inp; | 307 tp->t_inpcb = inp; /* XXX */ |
269 /* 270 * Init srtt to TCPTV_SRTTBASE (0), so we can tell that we have no 271 * rtt estimate. Set rttvar so that srtt + 4 * rttvar gives 272 * reasonable initial retransmit time. 273 */ 274 tp->t_srtt = TCPTV_SRTTBASE; 275 tp->t_rttvar = ((TCPTV_RTOBASE - TCPTV_SRTTBASE) << TCP_RTTVAR_SHIFT) / 4; 276 tp->t_rttmin = TCPTV_MIN; 277 tp->t_rxtcur = TCPTV_RTOBASE; 278 tp->snd_cwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT; 279 tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT; 280 inp->inp_ip_ttl = ip_defttl; 281 inp->inp_ppcb = (caddr_t)tp; | 308 /* 309 * Init srtt to TCPTV_SRTTBASE (0), so we can tell that we have no 310 * rtt estimate. Set rttvar so that srtt + 4 * rttvar gives 311 * reasonable initial retransmit time. 312 */ 313 tp->t_srtt = TCPTV_SRTTBASE; 314 tp->t_rttvar = ((TCPTV_RTOBASE - TCPTV_SRTTBASE) << TCP_RTTVAR_SHIFT) / 4; 315 tp->t_rttmin = TCPTV_MIN; 316 tp->t_rxtcur = TCPTV_RTOBASE; 317 tp->snd_cwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT; 318 tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT; 319 inp->inp_ip_ttl = ip_defttl; 320 inp->inp_ppcb = (caddr_t)tp; |
282 return (tp); | 321 return (tp); /* XXX */ |
283} 284 285/* 286 * Drop a TCP connection, reporting 287 * the specified error. If connection is synchronized, 288 * then send a RST to peer. 289 */ 290struct tcpcb * --- 122 unchanged lines hidden (view full) --- 413 t = (struct tcpiphdr *)t->ti_next; 414 m = REASS_MBUF((struct tcpiphdr *)t->ti_prev); 415 remque(t->ti_prev); 416 m_freem(m); 417 } 418 if (tp->t_template) 419 (void) m_free(dtom(tp->t_template)); 420 inp->inp_ppcb = NULL; | 322} 323 324/* 325 * Drop a TCP connection, reporting 326 * the specified error. If connection is synchronized, 327 * then send a RST to peer. 328 */ 329struct tcpcb * --- 122 unchanged lines hidden (view full) --- 452 t = (struct tcpiphdr *)t->ti_next; 453 m = REASS_MBUF((struct tcpiphdr *)t->ti_prev); 454 remque(t->ti_prev); 455 m_freem(m); 456 } 457 if (tp->t_template) 458 (void) m_free(dtom(tp->t_template)); 459 inp->inp_ppcb = NULL; |
421 free(tp, M_PCB); | |
422 soisdisconnected(so); 423 in_pcbdetach(inp); 424 tcpstat.tcps_closed++; 425 return ((struct tcpcb *)0); 426} 427 428void 429tcp_drain() --- 218 unchanged lines hidden --- | 460 soisdisconnected(so); 461 in_pcbdetach(inp); 462 tcpstat.tcps_closed++; 463 return ((struct tcpcb *)0); 464} 465 466void 467tcp_drain() --- 218 unchanged lines hidden --- |