Eliminate the allocation of a tcp template structure for each
connection. The information contained in a tcptemp can be reconstructed from a tcpcb when needed. Previously, tcp templates required the allocation of one mbuf per connection. On large systems, this change should free up a large number of mbufs. Reviewed by: bmilekic, jlemon, ru MFC after: 2 weeks
This commit is contained in:
parent
1d3771386f
commit
08517d530e
@ -1127,12 +1127,6 @@ tcp_input(m, off0, proto)
|
||||
}
|
||||
FREE(sin, M_SONAME);
|
||||
}
|
||||
tp->t_template = tcp_template(tp);
|
||||
if (tp->t_template == 0) {
|
||||
tp = tcp_drop(tp, ENOBUFS);
|
||||
dropsocket = 0; /* socket is already gone */
|
||||
goto drop;
|
||||
}
|
||||
if ((taop = tcp_gettaocache(inp)) == NULL) {
|
||||
taop = &tao_noncached;
|
||||
bzero(taop, sizeof(*taop));
|
||||
|
@ -632,16 +632,11 @@ tcp_output(tp)
|
||||
m->m_len = hdrlen;
|
||||
}
|
||||
m->m_pkthdr.rcvif = (struct ifnet *)0;
|
||||
if (tp->t_template == 0)
|
||||
panic("tcp_output");
|
||||
#ifdef INET6
|
||||
if (isipv6) {
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
th = (struct tcphdr *)(ip6 + 1);
|
||||
bcopy((caddr_t)tp->t_template->tt_ipgen, (caddr_t)ip6,
|
||||
sizeof(struct ip6_hdr));
|
||||
bcopy((caddr_t)&tp->t_template->tt_t, (caddr_t)th,
|
||||
sizeof(struct tcphdr));
|
||||
tcp_fillheaders(tp, ip6, th);
|
||||
} else
|
||||
#endif /* INET6 */
|
||||
{
|
||||
@ -649,10 +644,7 @@ tcp_output(tp)
|
||||
ipov = (struct ipovly *)ip;
|
||||
th = (struct tcphdr *)(ip + 1);
|
||||
/* this picks up the pseudo header (w/o the length) */
|
||||
bcopy((caddr_t)tp->t_template->tt_ipgen, (caddr_t)ip,
|
||||
sizeof(struct ip));
|
||||
bcopy((caddr_t)&tp->t_template->tt_t, (caddr_t)th,
|
||||
sizeof(struct tcphdr));
|
||||
tcp_fillheaders(tp, ip, th);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1127,12 +1127,6 @@ tcp_input(m, off0, proto)
|
||||
}
|
||||
FREE(sin, M_SONAME);
|
||||
}
|
||||
tp->t_template = tcp_template(tp);
|
||||
if (tp->t_template == 0) {
|
||||
tp = tcp_drop(tp, ENOBUFS);
|
||||
dropsocket = 0; /* socket is already gone */
|
||||
goto drop;
|
||||
}
|
||||
if ((taop = tcp_gettaocache(inp)) == NULL) {
|
||||
taop = &tao_noncached;
|
||||
bzero(taop, sizeof(*taop));
|
||||
|
@ -218,31 +218,24 @@ tcp_init()
|
||||
}
|
||||
|
||||
/*
|
||||
* Create template to be used to send tcp packets on a connection.
|
||||
* Call after host entry created, allocates an mbuf and fills
|
||||
* in a skeletal tcp/ip header, minimizing the amount of work
|
||||
* necessary when the connection is used.
|
||||
* Fill in the IP and TCP headers for an outgoing packet, given the tcpcb.
|
||||
* tcp_template used to store this data in mbufs, but we now recopy it out
|
||||
* of the tcpcb each time to conserve mbufs.
|
||||
*/
|
||||
struct tcptemp *
|
||||
tcp_template(tp)
|
||||
void
|
||||
tcp_fillheaders(tp, ip_ptr, tcp_ptr)
|
||||
struct tcpcb *tp;
|
||||
void *ip_ptr;
|
||||
void *tcp_ptr;
|
||||
{
|
||||
register struct inpcb *inp = tp->t_inpcb;
|
||||
register struct mbuf *m;
|
||||
register struct tcptemp *n;
|
||||
struct inpcb *inp = tp->t_inpcb;
|
||||
struct tcphdr *tcp_hdr = (struct tcphdr *)tcp_ptr;
|
||||
|
||||
if ((n = tp->t_template) == 0) {
|
||||
m = m_get(M_DONTWAIT, MT_HEADER);
|
||||
if (m == NULL)
|
||||
return (0);
|
||||
m->m_len = sizeof (struct tcptemp);
|
||||
n = mtod(m, struct tcptemp *);
|
||||
}
|
||||
#ifdef INET6
|
||||
if ((inp->inp_vflag & INP_IPV6) != 0) {
|
||||
register struct ip6_hdr *ip6;
|
||||
struct ip6_hdr *ip6;
|
||||
|
||||
ip6 = (struct ip6_hdr *)n->tt_ipgen;
|
||||
ip6 = (struct ip6_hdr *)ip_ptr;
|
||||
ip6->ip6_flow = (ip6->ip6_flow & ~IPV6_FLOWINFO_MASK) |
|
||||
(inp->in6p_flowinfo & IPV6_FLOWINFO_MASK);
|
||||
ip6->ip6_vfc = (ip6->ip6_vfc & ~IPV6_VERSION_MASK) |
|
||||
@ -251,29 +244,51 @@ tcp_template(tp)
|
||||
ip6->ip6_plen = sizeof(struct tcphdr);
|
||||
ip6->ip6_src = inp->in6p_laddr;
|
||||
ip6->ip6_dst = inp->in6p_faddr;
|
||||
n->tt_t.th_sum = 0;
|
||||
tcp_hdr->th_sum = 0;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
struct ip *ip = (struct ip *)n->tt_ipgen;
|
||||
{
|
||||
struct ip *ip = (struct ip *) ip_ptr;
|
||||
|
||||
bzero(ip, sizeof(struct ip)); /* XXX overkill? */
|
||||
ip->ip_vhl = IP_VHL_BORING;
|
||||
ip->ip_p = IPPROTO_TCP;
|
||||
ip->ip_src = inp->inp_laddr;
|
||||
ip->ip_dst = inp->inp_faddr;
|
||||
n->tt_t.th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr,
|
||||
htons(sizeof(struct tcphdr) + IPPROTO_TCP));
|
||||
}
|
||||
n->tt_t.th_sport = inp->inp_lport;
|
||||
n->tt_t.th_dport = inp->inp_fport;
|
||||
n->tt_t.th_seq = 0;
|
||||
n->tt_t.th_ack = 0;
|
||||
n->tt_t.th_x2 = 0;
|
||||
n->tt_t.th_off = 5;
|
||||
n->tt_t.th_flags = 0;
|
||||
n->tt_t.th_win = 0;
|
||||
n->tt_t.th_urp = 0;
|
||||
tcp_hdr->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr,
|
||||
htons(sizeof(struct tcphdr) + IPPROTO_TCP));
|
||||
}
|
||||
|
||||
tcp_hdr->th_sport = inp->inp_lport;
|
||||
tcp_hdr->th_dport = inp->inp_fport;
|
||||
tcp_hdr->th_seq = 0;
|
||||
tcp_hdr->th_ack = 0;
|
||||
tcp_hdr->th_x2 = 0;
|
||||
tcp_hdr->th_off = 5;
|
||||
tcp_hdr->th_flags = 0;
|
||||
tcp_hdr->th_win = 0;
|
||||
tcp_hdr->th_urp = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create template to be used to send tcp packets on a connection.
|
||||
* Allocates an mbuf and fills in a skeletal tcp/ip header. The only
|
||||
* use for this function is in keepalives, which use tcp_respond.
|
||||
*/
|
||||
struct tcptemp *
|
||||
tcp_maketemplate(tp)
|
||||
struct tcpcb *tp;
|
||||
{
|
||||
struct mbuf *m;
|
||||
struct tcptemp *n;
|
||||
|
||||
m = m_get(M_DONTWAIT, MT_HEADER);
|
||||
if (m == NULL)
|
||||
return (0);
|
||||
m->m_len = sizeof(struct tcptemp);
|
||||
n = mtod(m, struct tcptemp *);
|
||||
|
||||
tcp_fillheaders(tp, (void *)&n->tt_ipgen, (void *)&n->tt_t);
|
||||
return (n);
|
||||
}
|
||||
|
||||
@ -282,10 +297,9 @@ tcp_template(tp)
|
||||
* the given TCP/IP header. If m == 0, then we make a copy
|
||||
* of the tcpiphdr at ti and send directly to the addressed host.
|
||||
* This is used to force keep alive messages out using the TCP
|
||||
* template for a connection tp->t_template. If flags are given
|
||||
* then we send a message back to the TCP which originated the
|
||||
* segment ti, and discard the mbuf containing it and any other
|
||||
* attached mbufs.
|
||||
* template for a connection. If flags are given then we send
|
||||
* a message back to the TCP which originated the * segment ti,
|
||||
* and discard the mbuf containing it and any other attached mbufs.
|
||||
*
|
||||
* In any case the ack and sequence number of the transmitted
|
||||
* segment are as specified by the parameters.
|
||||
@ -701,8 +715,6 @@ tcp_close(tp)
|
||||
m_freem(q->tqe_m);
|
||||
FREE(q, M_TSEGQ);
|
||||
}
|
||||
if (tp->t_template)
|
||||
(void) m_free(dtom(tp->t_template));
|
||||
inp->inp_ppcb = NULL;
|
||||
soisdisconnected(so);
|
||||
#ifdef INET6
|
||||
@ -1339,7 +1351,7 @@ ipsec_hdrsiz_tcp(tp)
|
||||
#endif /* INET6 */
|
||||
struct tcphdr *th;
|
||||
|
||||
if (!tp || !tp->t_template || !(inp = tp->t_inpcb))
|
||||
if ((tp == NULL) || ((inp = tp->t_inpcb) == NULL))
|
||||
return 0;
|
||||
MGETHDR(m, M_DONTWAIT, MT_DATA);
|
||||
if (!m)
|
||||
@ -1351,10 +1363,7 @@ ipsec_hdrsiz_tcp(tp)
|
||||
th = (struct tcphdr *)(ip6 + 1);
|
||||
m->m_pkthdr.len = m->m_len =
|
||||
sizeof(struct ip6_hdr) + sizeof(struct tcphdr);
|
||||
bcopy((caddr_t)tp->t_template->tt_ipgen, (caddr_t)ip6,
|
||||
sizeof(struct ip6_hdr));
|
||||
bcopy((caddr_t)&tp->t_template->tt_t, (caddr_t)th,
|
||||
sizeof(struct tcphdr));
|
||||
tcp_fillheaders(tp, ip6, th);
|
||||
hdrsiz = ipsec6_hdrsiz(m, IPSEC_DIR_OUTBOUND, inp);
|
||||
} else
|
||||
#endif /* INET6 */
|
||||
@ -1362,10 +1371,7 @@ ipsec_hdrsiz_tcp(tp)
|
||||
ip = mtod(m, struct ip *);
|
||||
th = (struct tcphdr *)(ip + 1);
|
||||
m->m_pkthdr.len = m->m_len = sizeof(struct tcpiphdr);
|
||||
bcopy((caddr_t)tp->t_template->tt_ipgen, (caddr_t)ip,
|
||||
sizeof(struct ip));
|
||||
bcopy((caddr_t)&tp->t_template->tt_t, (caddr_t)th,
|
||||
sizeof(struct tcphdr));
|
||||
tcp_fillheaders(tp, ip, th);
|
||||
ip->ip_vhl = IP_VHL_BORING;
|
||||
hdrsiz = ipsec4_hdrsiz(m, IPSEC_DIR_OUTBOUND, inp);
|
||||
}
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
@ -222,6 +223,7 @@ tcp_timer_keep(xtp)
|
||||
void *xtp;
|
||||
{
|
||||
struct tcpcb *tp = xtp;
|
||||
struct tcptemp *t_template;
|
||||
int s;
|
||||
#ifdef TCPDEBUG
|
||||
int ostate;
|
||||
@ -259,9 +261,13 @@ tcp_timer_keep(xtp)
|
||||
* correspondent TCP to respond.
|
||||
*/
|
||||
tcpstat.tcps_keepprobe++;
|
||||
tcp_respond(tp, tp->t_template->tt_ipgen,
|
||||
&tp->t_template->tt_t, (struct mbuf *)NULL,
|
||||
tp->rcv_nxt, tp->snd_una - 1, 0);
|
||||
t_template = tcp_maketemplate(tp);
|
||||
if (t_template) {
|
||||
tcp_respond(tp, t_template->tt_ipgen,
|
||||
&t_template->tt_t, (struct mbuf *)NULL,
|
||||
tp->rcv_nxt, tp->snd_una - 1, 0);
|
||||
(void) m_free(dtom(t_template));
|
||||
}
|
||||
callout_reset(tp->tt_keep, tcp_keepintvl, tcp_timer_keep, tp);
|
||||
} else
|
||||
callout_reset(tp->tt_keep, tcp_keepidle, tcp_timer_keep, tp);
|
||||
|
@ -218,31 +218,24 @@ tcp_init()
|
||||
}
|
||||
|
||||
/*
|
||||
* Create template to be used to send tcp packets on a connection.
|
||||
* Call after host entry created, allocates an mbuf and fills
|
||||
* in a skeletal tcp/ip header, minimizing the amount of work
|
||||
* necessary when the connection is used.
|
||||
* Fill in the IP and TCP headers for an outgoing packet, given the tcpcb.
|
||||
* tcp_template used to store this data in mbufs, but we now recopy it out
|
||||
* of the tcpcb each time to conserve mbufs.
|
||||
*/
|
||||
struct tcptemp *
|
||||
tcp_template(tp)
|
||||
void
|
||||
tcp_fillheaders(tp, ip_ptr, tcp_ptr)
|
||||
struct tcpcb *tp;
|
||||
void *ip_ptr;
|
||||
void *tcp_ptr;
|
||||
{
|
||||
register struct inpcb *inp = tp->t_inpcb;
|
||||
register struct mbuf *m;
|
||||
register struct tcptemp *n;
|
||||
struct inpcb *inp = tp->t_inpcb;
|
||||
struct tcphdr *tcp_hdr = (struct tcphdr *)tcp_ptr;
|
||||
|
||||
if ((n = tp->t_template) == 0) {
|
||||
m = m_get(M_DONTWAIT, MT_HEADER);
|
||||
if (m == NULL)
|
||||
return (0);
|
||||
m->m_len = sizeof (struct tcptemp);
|
||||
n = mtod(m, struct tcptemp *);
|
||||
}
|
||||
#ifdef INET6
|
||||
if ((inp->inp_vflag & INP_IPV6) != 0) {
|
||||
register struct ip6_hdr *ip6;
|
||||
struct ip6_hdr *ip6;
|
||||
|
||||
ip6 = (struct ip6_hdr *)n->tt_ipgen;
|
||||
ip6 = (struct ip6_hdr *)ip_ptr;
|
||||
ip6->ip6_flow = (ip6->ip6_flow & ~IPV6_FLOWINFO_MASK) |
|
||||
(inp->in6p_flowinfo & IPV6_FLOWINFO_MASK);
|
||||
ip6->ip6_vfc = (ip6->ip6_vfc & ~IPV6_VERSION_MASK) |
|
||||
@ -251,29 +244,51 @@ tcp_template(tp)
|
||||
ip6->ip6_plen = sizeof(struct tcphdr);
|
||||
ip6->ip6_src = inp->in6p_laddr;
|
||||
ip6->ip6_dst = inp->in6p_faddr;
|
||||
n->tt_t.th_sum = 0;
|
||||
tcp_hdr->th_sum = 0;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
struct ip *ip = (struct ip *)n->tt_ipgen;
|
||||
{
|
||||
struct ip *ip = (struct ip *) ip_ptr;
|
||||
|
||||
bzero(ip, sizeof(struct ip)); /* XXX overkill? */
|
||||
ip->ip_vhl = IP_VHL_BORING;
|
||||
ip->ip_p = IPPROTO_TCP;
|
||||
ip->ip_src = inp->inp_laddr;
|
||||
ip->ip_dst = inp->inp_faddr;
|
||||
n->tt_t.th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr,
|
||||
htons(sizeof(struct tcphdr) + IPPROTO_TCP));
|
||||
}
|
||||
n->tt_t.th_sport = inp->inp_lport;
|
||||
n->tt_t.th_dport = inp->inp_fport;
|
||||
n->tt_t.th_seq = 0;
|
||||
n->tt_t.th_ack = 0;
|
||||
n->tt_t.th_x2 = 0;
|
||||
n->tt_t.th_off = 5;
|
||||
n->tt_t.th_flags = 0;
|
||||
n->tt_t.th_win = 0;
|
||||
n->tt_t.th_urp = 0;
|
||||
tcp_hdr->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr,
|
||||
htons(sizeof(struct tcphdr) + IPPROTO_TCP));
|
||||
}
|
||||
|
||||
tcp_hdr->th_sport = inp->inp_lport;
|
||||
tcp_hdr->th_dport = inp->inp_fport;
|
||||
tcp_hdr->th_seq = 0;
|
||||
tcp_hdr->th_ack = 0;
|
||||
tcp_hdr->th_x2 = 0;
|
||||
tcp_hdr->th_off = 5;
|
||||
tcp_hdr->th_flags = 0;
|
||||
tcp_hdr->th_win = 0;
|
||||
tcp_hdr->th_urp = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create template to be used to send tcp packets on a connection.
|
||||
* Allocates an mbuf and fills in a skeletal tcp/ip header. The only
|
||||
* use for this function is in keepalives, which use tcp_respond.
|
||||
*/
|
||||
struct tcptemp *
|
||||
tcp_maketemplate(tp)
|
||||
struct tcpcb *tp;
|
||||
{
|
||||
struct mbuf *m;
|
||||
struct tcptemp *n;
|
||||
|
||||
m = m_get(M_DONTWAIT, MT_HEADER);
|
||||
if (m == NULL)
|
||||
return (0);
|
||||
m->m_len = sizeof(struct tcptemp);
|
||||
n = mtod(m, struct tcptemp *);
|
||||
|
||||
tcp_fillheaders(tp, (void *)&n->tt_ipgen, (void *)&n->tt_t);
|
||||
return (n);
|
||||
}
|
||||
|
||||
@ -282,10 +297,9 @@ tcp_template(tp)
|
||||
* the given TCP/IP header. If m == 0, then we make a copy
|
||||
* of the tcpiphdr at ti and send directly to the addressed host.
|
||||
* This is used to force keep alive messages out using the TCP
|
||||
* template for a connection tp->t_template. If flags are given
|
||||
* then we send a message back to the TCP which originated the
|
||||
* segment ti, and discard the mbuf containing it and any other
|
||||
* attached mbufs.
|
||||
* template for a connection. If flags are given then we send
|
||||
* a message back to the TCP which originated the * segment ti,
|
||||
* and discard the mbuf containing it and any other attached mbufs.
|
||||
*
|
||||
* In any case the ack and sequence number of the transmitted
|
||||
* segment are as specified by the parameters.
|
||||
@ -701,8 +715,6 @@ tcp_close(tp)
|
||||
m_freem(q->tqe_m);
|
||||
FREE(q, M_TSEGQ);
|
||||
}
|
||||
if (tp->t_template)
|
||||
(void) m_free(dtom(tp->t_template));
|
||||
inp->inp_ppcb = NULL;
|
||||
soisdisconnected(so);
|
||||
#ifdef INET6
|
||||
@ -1339,7 +1351,7 @@ ipsec_hdrsiz_tcp(tp)
|
||||
#endif /* INET6 */
|
||||
struct tcphdr *th;
|
||||
|
||||
if (!tp || !tp->t_template || !(inp = tp->t_inpcb))
|
||||
if ((tp == NULL) || ((inp = tp->t_inpcb) == NULL))
|
||||
return 0;
|
||||
MGETHDR(m, M_DONTWAIT, MT_DATA);
|
||||
if (!m)
|
||||
@ -1351,10 +1363,7 @@ ipsec_hdrsiz_tcp(tp)
|
||||
th = (struct tcphdr *)(ip6 + 1);
|
||||
m->m_pkthdr.len = m->m_len =
|
||||
sizeof(struct ip6_hdr) + sizeof(struct tcphdr);
|
||||
bcopy((caddr_t)tp->t_template->tt_ipgen, (caddr_t)ip6,
|
||||
sizeof(struct ip6_hdr));
|
||||
bcopy((caddr_t)&tp->t_template->tt_t, (caddr_t)th,
|
||||
sizeof(struct tcphdr));
|
||||
tcp_fillheaders(tp, ip6, th);
|
||||
hdrsiz = ipsec6_hdrsiz(m, IPSEC_DIR_OUTBOUND, inp);
|
||||
} else
|
||||
#endif /* INET6 */
|
||||
@ -1362,10 +1371,7 @@ ipsec_hdrsiz_tcp(tp)
|
||||
ip = mtod(m, struct ip *);
|
||||
th = (struct tcphdr *)(ip + 1);
|
||||
m->m_pkthdr.len = m->m_len = sizeof(struct tcpiphdr);
|
||||
bcopy((caddr_t)tp->t_template->tt_ipgen, (caddr_t)ip,
|
||||
sizeof(struct ip));
|
||||
bcopy((caddr_t)&tp->t_template->tt_t, (caddr_t)th,
|
||||
sizeof(struct tcphdr));
|
||||
tcp_fillheaders(tp, ip, th);
|
||||
ip->ip_vhl = IP_VHL_BORING;
|
||||
hdrsiz = ipsec4_hdrsiz(m, IPSEC_DIR_OUTBOUND, inp);
|
||||
}
|
||||
|
@ -749,12 +749,6 @@ tcp_connect(tp, nam, p)
|
||||
inp->inp_fport = sin->sin_port;
|
||||
in_pcbrehash(inp);
|
||||
|
||||
tp->t_template = tcp_template(tp);
|
||||
if (tp->t_template == 0) {
|
||||
in_pcbdisconnect(inp);
|
||||
return ENOBUFS;
|
||||
}
|
||||
|
||||
/* Compute window scaling to request. */
|
||||
while (tp->request_r_scale < TCP_MAX_WINSHIFT &&
|
||||
(TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat)
|
||||
@ -841,12 +835,6 @@ tcp6_connect(tp, nam, p)
|
||||
inp->in6p_flowinfo = sin6->sin6_flowinfo;
|
||||
in_pcbrehash(inp);
|
||||
|
||||
tp->t_template = tcp_template(tp);
|
||||
if (tp->t_template == 0) {
|
||||
in6_pcbdisconnect(inp);
|
||||
return ENOBUFS;
|
||||
}
|
||||
|
||||
/* Compute window scaling to request. */
|
||||
while (tp->request_r_scale < TCP_MAX_WINSHIFT &&
|
||||
(TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat)
|
||||
|
@ -66,7 +66,7 @@ struct tcptemp {
|
||||
struct tcpcb {
|
||||
struct tsegqe_head t_segq;
|
||||
int t_dupacks; /* consecutive dup acks recd */
|
||||
struct tcptemp *t_template; /* skeletal packet for transmit */
|
||||
struct tcptemp *unused; /* unused */
|
||||
|
||||
struct callout *tt_rexmt; /* retransmit timer */
|
||||
struct callout *tt_persist; /* retransmit persistence */
|
||||
@ -400,7 +400,8 @@ struct rtentry *
|
||||
void tcp_setpersist __P((struct tcpcb *));
|
||||
void tcp_slowtimo __P((void));
|
||||
struct tcptemp *
|
||||
tcp_template __P((struct tcpcb *));
|
||||
tcp_maketemplate __P((struct tcpcb *));
|
||||
void tcp_fillheaders __P((struct tcpcb *, void *, void *));
|
||||
struct tcpcb *
|
||||
tcp_timers __P((struct tcpcb *, int));
|
||||
void tcp_trace __P((int, int, struct tcpcb *, void *, struct tcphdr *,
|
||||
|
Loading…
Reference in New Issue
Block a user