Index: tcp.h
===================================================================
RCS file: /home/cvs-freebsd/src/sys/netinet/tcp.h,v
retrieving revision 1.27
diff -u -p -r1.27 tcp.h
--- tcp.h	2 Nov 2004 22:22:21 -0000	1.27
+++ tcp.h	18 Nov 2004 10:08:05 -0000
@@ -93,6 +93,13 @@ struct tcphdr {
 
 #define	MAX_TCPOPTLEN		40	/* Absolute maximum TCP options len */
 
+#define	TCPOPT_SCOOKIE		20
+#define	    TCPOLEN_SCOOKIE		8
+#define	    TCPOPT_SCOOKIE_MASK		0x000000000000ffff
+#define	TCPOPT_CCOOKIE		21
+#define	    TCPOLEN_CCOOKIE		8
+#define	    TCPOPT_CCOOKIE_MASK		0x000000000000ffff
+
 #define	TCPOPT_SIGNATURE		19	/* Keyed MD5: RFC 2385 */
 #define	   TCPOLEN_SIGNATURE		18
 
@@ -159,6 +166,7 @@ struct tcphdr {
 #define TCP_NOPUSH	0x04	/* don't push last block of write */
 #define TCP_NOOPT	0x08	/* don't use TCP options */
 #define TCP_MD5SIG	0x10	/* use MD5 digests (RFC2385) */
+#define	TCP_TTCPv2	0x20	/* use transactional TCPv2 */
 #endif
 
 #endif /* !_NETINET_TCP_H_ */
Index: tcp_hostcache.c
===================================================================
RCS file: /home/cvs-freebsd/src/sys/netinet/tcp_hostcache.c,v
retrieving revision 1.8
diff -u -p -r1.8 tcp_hostcache.c
--- tcp_hostcache.c	2 Nov 2004 22:22:21 -0000	1.8
+++ tcp_hostcache.c	18 Nov 2004 10:08:05 -0000
@@ -121,6 +121,9 @@ struct hc_metrics {
 	u_long	rmx_cwnd;	/* congestion window */
 	u_long	rmx_sendpipe;	/* outbound delay-bandwidth product */
 	u_long	rmx_recvpipe;	/* inbound delay-bandwidth product */
+	/* TTCPv2 */
+	u_int64_t rmx_cscookie;	/* server host cookie as client */
+	u_int64_t rmx_sscookie;	/* server host cookie as server */
 	/* tcp hostcache internal data */
 	int	rmx_expire;	/* lifetime for object */
 	u_long	rmx_hits;	/* number of hits */
@@ -456,6 +459,66 @@ tcp_hc_getmtu(struct in_conninfo *inc)
 }
 
 /*
+ * External function: get the server cookie as client.
+ */
+u_int64_t
+tcp_hc_getcscookie(struct in_conninfo *inc)
+{
+	struct hc_metrics *hc_entry;
+	u_int64_t cscookie;
+
+	hc_entry = tcp_hc_lookup(inc);
+	if (hc_entry == NULL) {
+		return 0;
+	}
+	hc_entry->rmx_hits++;
+	hc_entry->rmx_expire = tcp_hostcache.expire; /* start over again */
+
+	cscookie = hc_entry->rmx_cscookie;
+	THC_UNLOCK(&hc_entry->rmx_head->hch_mtx);
+	return cscookie;
+}
+
+/*
+ * External function: get the server cookie as server. Generates new cookie if none exists.
+ * XXX: Need to implement expiration and rotation of server cookie.
+ */
+u_int64_t
+tcp_hc_getsscookie(struct in_conninfo *inc)
+{
+	struct hc_metrics *hc_entry;
+	u_int64_t sscookie;
+
+	/*
+	 * Find the right bucket
+	 */
+	hc_entry = tcp_hc_lookup(inc);
+
+	/*
+	 * If we don't have an existing object try to insert a new one
+	 */
+	if (hc_entry == NULL) {
+		hc_entry = tcp_hc_insert(inc);
+		if (hc_entry == NULL)
+			return 0;
+		hc_entry->rmx_updates++;
+	} else {
+		hc_entry->rmx_hits++;
+		hc_entry->rmx_expire = tcp_hostcache.expire; /* start over again */
+	}
+
+	/* Generate new cookie if none yet */
+	if (!hc_entry->rmx_sscookie) {
+		hc_entry->rmx_sscookie = tcp_newccookie(NULL);
+		hc_entry->rmx_sscookie &= ~TCPOPT_SCOOKIE_MASK;
+	}
+
+	sscookie = hc_entry->rmx_sscookie;
+	THC_UNLOCK(&hc_entry->rmx_head->hch_mtx);
+	return sscookie;
+}
+
+/*
  * External function: update the mtu value of an entry in the hostcache.
  * Creates a new entry if none was found.
  */
@@ -495,6 +558,45 @@ tcp_hc_updatemtu(struct in_conninfo *inc
 }
 
 /*
+ * External function: update the client server cookie of an entry in the hostcache.
+ * Creates a new entry if none was found.
+ */
+void
+tcp_hc_updatecscookie(struct in_conninfo *inc, u_int64_t cscookie)
+{
+	struct hc_metrics *hc_entry;
+
+	/*
+	 * Find the right bucket
+	 */
+	hc_entry = tcp_hc_lookup(inc);
+
+	/*
+	 * If we don't have an existing object try to insert a new one
+	 */
+	if (hc_entry == NULL) {
+		hc_entry = tcp_hc_insert(inc);
+		if (hc_entry == NULL)
+			return;
+	}
+	hc_entry->rmx_updates++;
+	hc_entry->rmx_expire = tcp_hostcache.expire; /* start over again */
+
+	hc_entry->rmx_cscookie = cscookie;
+
+	/*
+	 * put it upfront so we find it faster next time
+	 */
+	TAILQ_REMOVE(&hc_entry->rmx_head->hch_bucket, hc_entry, rmx_q);
+	TAILQ_INSERT_HEAD(&hc_entry->rmx_head->hch_bucket, hc_entry, rmx_q);
+
+	/*
+	 * unlock bucket row
+	 */
+	THC_UNLOCK(&hc_entry->rmx_head->hch_mtx);
+}
+
+/*
  * External function: update the tcp metrics of an entry in the hostcache.
  * Creates a new entry if none was found.
  */
Index: tcp_input.c
===================================================================
RCS file: /home/cvs-freebsd/src/sys/netinet/tcp_input.c,v
retrieving revision 1.255
diff -u -p -r1.255 tcp_input.c
--- tcp_input.c	7 Nov 2004 19:19:35 -0000	1.255
+++ tcp_input.c	18 Nov 2004 10:08:05 -0000
@@ -802,7 +802,7 @@ findpcb:
 		inc.inc_lport = th->th_dport;
 
 	        /*
-	         * If the state is LISTEN then ignore segment if it contains
+		 * If the state is LISTEN then ignore segment if it contains
 		 * a RST.  If the segment contains an ACK then it is bad and
 		 * send a RST.  If it does not contain a SYN then it is not
 		 * interesting; drop it.
@@ -827,7 +827,7 @@ findpcb:
 					/*
 					 * Could not complete 3-way handshake,
 					 * connection is being closed down, and
-					 * syncache will free mbuf.
+					 * syncache already free'd mbuf.
 					 */
 					INP_UNLOCK(inp);
 					INP_INFO_WUNLOCK(&tcbinfo);
@@ -1064,6 +1064,11 @@ after_listen:
 	}
 
 	/*
+	 * XXX: The following and the one before do not check if segment is
+	 * within window. That is a problem and needs to be fixed.
+	 */
+
+	/*
 	 * Segment received on connection.
 	 * Reset idle time and keep-alive timer.
 	 */
@@ -1388,6 +1393,11 @@ after_listen:
 				callout_reset(tp->tt_keep, tcp_keepidle,
 					      tcp_timer_keep, tp);
 			}
+			/* Everything fine and dandy, update server cookie. */
+			if ((tp->t_flags & TF_SCOOKIE) && to.to_scookie)
+				tcp_hc_updatecscookie(&inp->inp_inc, to.to_scookie);
+			else
+				tp->t_flags &= ~TF_SCOOKIE;
 		} else {
 			/*
 			 * Received initial SYN in SYN-SENT[*] state =>
@@ -2554,6 +2564,22 @@ tcp_dooptions(tp, to, cp, cnt, is_syn, t
 			    (char *)&to->to_tsecr, sizeof(to->to_tsecr));
 			to->to_tsecr = ntohl(to->to_tsecr);
 			break;
+		case TCPOPT_SCOOKIE:
+			if (optlen != TCPOLEN_SCOOKIE)
+				continue;
+			to->to_flags |= TOF_SCOOKIE;
+			bcopy((char *)cp,
+			    (char *)&to->to_scookie, sizeof(to->to_scookie));
+			to->to_scookie &= ~TCPOPT_SCOOKIE_MASK;
+			break;
+		case TCPOPT_CCOOKIE:
+			if (optlen != TCPOLEN_CCOOKIE)
+				continue;
+			to->to_flags |= TOF_CCOOKIE;
+			bcopy((char *)cp,
+			    (char *)&to->to_ccookie, sizeof(to->to_ccookie));
+			to->to_ccookie &= ~TCPOPT_CCOOKIE_MASK;
+			break;
 #ifdef TCP_SIGNATURE
 		/*
 		 * XXX In order to reply to a host which has set the
Index: tcp_output.c
===================================================================
RCS file: /home/cvs-freebsd/src/sys/netinet/tcp_output.c,v
retrieving revision 1.105
diff -u -p -r1.105 tcp_output.c
--- tcp_output.c	2 Nov 2004 22:22:21 -0000	1.105
+++ tcp_output.c	18 Nov 2004 10:08:05 -0000
@@ -556,6 +556,31 @@ send:
 					tp->request_r_scale);
 				optlen += 4;
 			}
+
+			/*
+			 * On active open SYN set the server connection cookie if TTCPv2
+			 * enabled on socket.
+			 */
+			if ((flags & TH_ACK) == 0 &&
+			    (tp->t_flags & TF_SCOOKIE)) {
+				*((u_int64_t *)(opt + optlen)) =
+				    tcp_hc_getcscookie(&tp->t_inpcb->inp_inc);
+				opt[optlen] = TCPOPT_SCOOKIE;
+				opt[optlen + 1] = TCPOLEN_SCOOKIE;
+				optlen += TCPOLEN_SCOOKIE;
+			}
+
+			/* On active open SYN set the client connection cookie. */
+			if ((flags & TH_ACK) == 0 &&
+			    (tp->t_flags & TF_CCOOKIE)) {
+				tp->rcv_ccookie = tcp_newccookie(tp);
+				tp->rcv_ccookie &= ~TCPOPT_CCOOKIE_MASK;
+				*((u_int64_t *)(opt + optlen)) =
+					tp->rcv_ccookie;
+				opt[optlen] = TCPOPT_CCOOKIE;
+				opt[optlen + 1] = TCPOLEN_CCOOKIE;
+				optlen += TCPOLEN_CCOOKIE;
+			}
 		}
 	}
 
@@ -576,6 +601,18 @@ send:
 		*lp   = htonl(tp->ts_recent);
 		optlen += TCPOLEN_TSTAMP_APPA;
 	}
+	
+	/*
+	 * Send client cookie in any packet containing an ACK (including SYN ACK,
+	 * however this is handled in syncache) if one was specified.
+	 */
+	if ((flags & TH_ACK) && (tp->t_flags & TF_NOOPT) == 0 &&
+	    (tp->t_flags & TF_CCOOKIE) && tp->rcv_ccookie) {
+		*((u_int64_t *)(opt + optlen)) = tp->rcv_ccookie;
+		opt[optlen] = TCPOPT_CCOOKIE;
+		opt[optlen + 1] = TCPOLEN_CCOOKIE;
+		optlen += TCPOLEN_CCOOKIE;
+	}
 
 	/*
 	 * Send SACKs if necessary.  This should be the last option processed.
@@ -1121,3 +1158,14 @@ tcp_setpersist(tp)
 	if (tp->t_rxtshift < TCP_MAXRXTSHIFT)
 		tp->t_rxtshift++;
 }
+
+u_int64_t
+tcp_newccookie(tp)
+	struct tcpcb *tp;
+{
+	/* Just a hack to get some random 64bit value back. */
+	struct bintime bt;
+	
+	getbintime(&bt);
+	return (bt.frac);
+}
Index: tcp_subr.c
===================================================================
RCS file: /home/cvs-freebsd/src/sys/netinet/tcp_subr.c,v
retrieving revision 1.207
diff -u -p -r1.207 tcp_subr.c
--- tcp_subr.c	8 Nov 2004 18:49:50 -0000	1.207
+++ tcp_subr.c	18 Nov 2004 10:08:05 -0000
@@ -146,6 +146,12 @@ SYSCTL_INT(_net_inet_tcp, OID_AUTO, minm
     &tcp_minmssoverload , 0, "Number of TCP Segments per Second allowed to"
     "be under the MINMSS Size");
 
+int	tcp_do_ccookie = 1;
+#if 0
+SYSCTL_INT(_net_inet_tcp, OID_AUTO, client_cookie, CTFLAG_RW,
+    &tcp_do_ccookie, 0, "Send and respond to connection cookies");
+#endif
+    
 #if 0
 static int	tcp_rttdflt = TCPTV_SRTTDFLT / PR_SLOWHZ;
 SYSCTL_INT(_net_inet_tcp, TCPCTL_RTTDFLT, rttdflt, CTLFLAG_RW,
@@ -608,6 +614,9 @@ tcp_newtcpcb(inp)
 
 	if (tcp_do_rfc1323)
 		tp->t_flags = (TF_REQ_SCALE|TF_REQ_TSTMP);
+	if (tcp_do_ccookie)
+		tp->t_flags |= TF_CCOOKIE;
+	tp->t_flags |= TF_SCOOKIE;	/* XXX: Conditional on TTCPv2. */
 	tp->sack_enable = tcp_do_sack;
 	tp->t_inpcb = inp;	/* XXX */
 	/*
@@ -791,6 +800,7 @@ tcp_drain()
 	 *      reassembly queue should be flushed, but in a situation
 	 *	where we're really low on mbufs, this is potentially
 	 *	usefull.
+	 * XXX: This breaks with SACK!
 	 */
 		INP_INFO_RLOCK(&tcbinfo);
 		LIST_FOREACH(inpb, tcbinfo.listhead, inp_list) {
Index: tcp_syncache.c
===================================================================
RCS file: /home/cvs-freebsd/src/sys/netinet/tcp_syncache.c,v
retrieving revision 1.68
diff -u -p -r1.68 tcp_syncache.c
--- tcp_syncache.c	2 Nov 2004 22:22:21 -0000	1.68
+++ tcp_syncache.c	18 Nov 2004 10:08:05 -0000
@@ -469,6 +469,9 @@ syncache_chkrst(inc, th)
 	 *   echo of our outgoing acknowlegement numbers, but some hosts
 	 *   send a reset with the sequence number at the rightmost edge
 	 *   of our receive window, and we have to handle this case.
+	 *
+	 * XXX: Make this check more explicit by checking exactly for
+	 * outgoing ACKseq or ACKseq+wnd?
 	 */
 	if (SEQ_GEQ(th->th_seq, sc->sc_irs) &&
 	    SEQ_LEQ(th->th_seq, sc->sc_irs + sc->sc_wnd)) {
@@ -694,6 +697,13 @@ syncache_socket(sc, lso, m)
 		tp->ts_recent = sc->sc_tsrecent;
 		tp->ts_recent_age = ticks;
 	}
+	if (sc->sc_flags & SCF_SCOOKIE) {
+		tp->t_flags |= TF_SCOOKIE;
+	}
+	if (sc->sc_flags & SCF_CCOOKIE) {
+		tp->t_flags |= TF_CCOOKIE;
+		tp->rcv_ccookie = sc->sc_ccookie;
+	}
 #ifdef TCP_SIGNATURE
 	if (sc->sc_flags & SCF_SIGNATURE)
 		tp->t_flags |= TF_SIGNATURE;
@@ -704,7 +714,7 @@ syncache_socket(sc, lso, m)
 	}
 	/*
 	 * Set up MSS and get cached values from tcp_hostcache.
-	 * This might overwrite some of the defaults we just set.
+	 * This may overwrite some of the defaults we just set.
 	 */
 	tcp_mss(tp, sc->sc_peer_mss);
 
@@ -977,8 +987,22 @@ syncache_add(inc, to, th, sop, m)
 			sc->sc_flags |= SCF_WINSCALE;
 		}
 	}
-	if (tp->t_flags & TF_NOOPT)
-		sc->sc_flags = SCF_NOOPT;
+
+	/* Only do server cookies if enabled on the socket and requested by client. */
+	if ((tp->t_flags & TF_SCOOKIE) &&
+	    (to->to_flags & TOF_SCOOKIE)) {
+		sc->sc_flags |= SCF_SCOOKIE;
+	}
+
+	/*
+	 * Only do client connection cookies if requested by client in SYN packet
+	 * and cookie sent to us is not NULL.
+	 */
+	if ((to->to_flags & TOF_CCOOKIE) && to->to_ccookie) {
+		sc->sc_flags |= SCF_CCOOKIE;
+		sc->sc_ccookie = to->to_ccookie;
+	}
+
 #ifdef TCP_SIGNATURE
 	/*
 	 * If listening socket requested TCP digests, and received SYN
@@ -994,6 +1018,10 @@ syncache_add(inc, to, th, sop, m)
 	if (to->to_flags & TOF_SACK)
 		sc->sc_flags |= SCF_SACK;
 
+	/* NOOPT on socket overrides everything. */
+	if (tp->t_flags & TF_NOOPT)
+		sc->sc_flags = SCF_NOOPT;
+
 	/*
 	 * Do a standard 3-way handshake.
 	 */
@@ -1054,6 +1082,8 @@ syncache_respond(sc, m)
 		optlen = TCPOLEN_MAXSEG +
 		    ((sc->sc_flags & SCF_WINSCALE) ? 4 : 0) +
 		    ((sc->sc_flags & SCF_TIMESTAMP) ? TCPOLEN_TSTAMP_APPA : 0);
+		optlen += ((sc->sc_flags & SCF_SCOOKIE) ? TCPOLEN_SCOOKIE : 0);
+		optlen += ((sc->sc_flags & SCF_CCOOKIE) ? TCPOLEN_CCOOKIE : 0);
 #ifdef TCP_SIGNATURE
 		optlen += (sc->sc_flags & SCF_SIGNATURE) ?
 		    TCPOLEN_SIGNATURE + 2 : 0;
@@ -1165,6 +1195,19 @@ syncache_respond(sc, m)
 			optp += TCPOLEN_TSTAMP_APPA;
 		}
 
+		if (sc->sc_flags & SCF_SCOOKIE) {
+			*((u_int64_t *)optp) = tcp_hc_getsscookie(&sc->sc_inc);
+			*optp = TCPOPT_SCOOKIE;
+			*(optp+1) = TCPOLEN_SCOOKIE;
+			optp += TCPOLEN_SCOOKIE;
+		}
+
+		if (sc->sc_flags & SCF_CCOOKIE) {
+			bcopy(&sc->sc_ccookie, optp, sizeof(sc->sc_ccookie));
+			*optp = TCPOPT_CCOOKIE;
+			*(optp+1) = TCPOLEN_CCOOKIE;
+			optp += TCPOLEN_CCOOKIE;
+		}
 #ifdef TCP_SIGNATURE
 		/*
 		 * Handle TCP-MD5 passive opener response.
Index: tcp_usrreq.c
===================================================================
RCS file: /home/cvs-freebsd/src/sys/netinet/tcp_usrreq.c,v
retrieving revision 1.109
diff -u -p -r1.109 tcp_usrreq.c
--- tcp_usrreq.c	8 Nov 2004 14:44:53 -0000	1.109
+++ tcp_usrreq.c	18 Nov 2004 10:08:05 -0000
@@ -1045,6 +1045,18 @@ tcp_ctloutput(so, sopt)
 			else
 				error = EINVAL;
 			break;
+		
+		case TCP_TTCPv2:
+			error = sooptcopyin(sopt, &optval, sizeof optval,
+					    sizeof optval);
+			if (error)
+				break;
+				
+			if (optval)
+				tp->t_flags |= TF_TTCPv2;
+			else
+				tp->t_flags &= ~TF_TTCPv2;
+			break;
 
 		default:
 			error = ENOPROTOOPT;
@@ -1071,6 +1083,9 @@ tcp_ctloutput(so, sopt)
 		case TCP_NOPUSH:
 			optval = tp->t_flags & TF_NOPUSH;
 			break;
+		case TCP_TTCPv2:
+			optval = tp->t_flags & TF_TTCPv2;
+			break;
 		default:
 			error = ENOPROTOOPT;
 			break;
Index: tcp_var.h
===================================================================
RCS file: /home/cvs-freebsd/src/sys/netinet/tcp_var.h,v
retrieving revision 1.112
diff -u -p -r1.112 tcp_var.h
--- tcp_var.h	2 Nov 2004 22:22:21 -0000	1.112
+++ tcp_var.h	18 Nov 2004 10:08:06 -0000
@@ -101,6 +101,9 @@ struct tcpcb {
 #define	TF_NEEDSYN	0x000400	/* send SYN (implicit state) */
 #define	TF_NEEDFIN	0x000800	/* send FIN (implicit state) */
 #define	TF_NOPUSH	0x001000	/* don't push */
+#define	TF_SCOOKIE	0x002000	/* send server host cookie */
+#define	TF_CCOOKIE	0x004000	/* reflect client connection cookie */
+#define	TF_TTCPv2	0x008000	/* do transactional TCPv2 */
 #define	TF_MORETOCOME	0x010000	/* More data to be appended to sock */
 #define	TF_LQ_OVERFLOW	0x020000	/* listen queue overflow */
 #define	TF_LASTIDLE	0x040000	/* connection was previously idle */
@@ -179,6 +182,8 @@ struct tcpcb {
 	tcp_seq	snd_recover_prev;	/* snd_recover prior to retransmit */
 	u_long	t_badrxtwin;		/* window for retransmit recovery */
 	u_char	snd_limited;		/* segments limited transmitted */
+
+	u_int64_t rcv_ccookie;		/* received client connection cookie */
 /* anti DoS counters */
 	u_long	rcv_second;		/* start of interval second */
 	u_long	rcv_pps;		/* received packets per second */
@@ -224,6 +229,8 @@ struct tcpcb {
 struct tcpopt {
 	u_long		to_flags;	/* which options are present */
 #define TOF_TS		0x0001		/* timestamp */
+#define	TOF_SCOOKIE	0x0002		/* server host cookie */
+#define	TOF_CCOOKIE	0x0004		/* client connection cookie */
 #define	TOF_MSS		0x0010
 #define	TOF_SCALE	0x0020
 #define	TOF_SIGNATURE	0x0040		/* signature option present */
@@ -231,6 +238,8 @@ struct tcpopt {
 #define	TOF_SACK	0x0100		/* Peer sent SACK option */
 	u_int32_t	to_tsval;
 	u_int32_t	to_tsecr;
+	u_int64_t	to_scookie;
+	u_int64_t	to_ccookie;
 	u_int16_t	to_mss;
 	u_int8_t	to_requested_s_scale;
 	u_int8_t	to_pad;
@@ -244,6 +253,7 @@ struct syncache {
 	struct		in_conninfo sc_inc;	/* addresses */
 	u_int32_t	sc_tsrecent;
 	u_int32_t	sc_flowlabel;		/* IPv6 flowlabel */
+	u_int64_t	sc_ccookie;		/* client connection cookie */
 	tcp_seq		sc_irs;			/* seq from peer */
 	tcp_seq		sc_iss;			/* our ISS */
 	u_long		sc_rxttime;		/* retransmit time */
@@ -256,8 +266,10 @@ struct syncache {
 #define SCF_NOOPT	0x01			/* no TCP options */
 #define SCF_WINSCALE	0x02			/* negotiated window scaling */
 #define SCF_TIMESTAMP	0x04			/* negotiated timestamps */
+#define	SCF_CCOOKIE	0x08			/* client connection cookie */
 #define SCF_UNREACH	0x10			/* icmp unreachable received */
 #define SCF_SIGNATURE	0x20			/* send MD5 digests */
+#define	SCF_SCOOKIE	0x40			/* server cookie */
 #define SCF_SACK	0x80			/* send SACK option */
 	TAILQ_ENTRY(syncache)	sc_hash;
 	TAILQ_ENTRY(syncache)	sc_timerq;
@@ -532,6 +544,8 @@ struct inpcb *
 	 tcp_drop_syn_sent(struct inpcb *, int);
 struct inpcb *
 	 tcp_mtudisc(struct inpcb *, int);
+u_int64_t
+	 tcp_newccookie(struct tcpcb *);
 struct tcpcb *
 	 tcp_newtcpcb(struct inpcb *);
 int	 tcp_output(struct tcpcb *);
@@ -566,7 +580,10 @@ void	 syncache_badack(struct in_conninfo
 void	 tcp_hc_init(void);
 void	 tcp_hc_get(struct in_conninfo *, struct hc_metrics_lite *);
 u_long	 tcp_hc_getmtu(struct in_conninfo *);
+u_int64_t tcp_hc_getcscookie(struct in_conninfo *);
+u_int64_t tcp_hc_getsscookie(struct in_conninfo *);
 void	 tcp_hc_updatemtu(struct in_conninfo *, u_long);
+void	 tcp_hc_updatecscookie(struct in_conninfo *, u_int64_t);
 void	 tcp_hc_update(struct in_conninfo *, struct hc_metrics_lite *);
 
 extern	struct pr_usrreqs tcp_usrreqs;
