#ifndef _NETINET_TCP_VAR_H_
#define _NETINET_TCP_VAR_H_
#include <sys/timeout.h>
struct sackblk {
tcp_seq start;
tcp_seq end;
};
struct sackhole {
tcp_seq start;
tcp_seq end;
int dups;
tcp_seq rxmit;
struct sackhole *next;
};
TAILQ_HEAD(tcpqehead, tcpqent);
struct tcpqent {
TAILQ_ENTRY(tcpqent) tcpqe_q;
struct tcphdr *tcpqe_tcp;
struct mbuf *tcpqe_m;
};
struct tcpcb {
struct tcpqehead t_segq;
struct timeout t_timer[TCPT_NTIMERS];
short t_state;
short t_rxtshift;
int t_rxtcur;
short t_dupacks;
u_short t_maxseg;
char t_force;
u_int t_flags;
#define TF_ACKNOW 0x0001U
#define TF_NODELAY 0x0004U
#define TF_NOOPT 0x0008U
#define TF_SENTFIN 0x0010U
#define TF_REQ_SCALE 0x0020U
#define TF_RCVD_SCALE 0x0040U
#define TF_REQ_TSTMP 0x0080U
#define TF_RCVD_TSTMP 0x0100U
#define TF_SACK_PERMIT 0x0200U
#define TF_SIGNATURE 0x0400U
#ifdef TCP_ECN
#define TF_ECN_PERMIT 0x00008000U
#define TF_RCVD_CE 0x00010000U
#define TF_SEND_CWR 0x00020000U
#define TF_DISABLE_ECN 0x00040000U
#endif
#define TF_LASTIDLE 0x00100000U
#define TF_PMTUD_PEND 0x00400000U
#define TF_NEEDOUTPUT 0x00800000U
#define TF_NOPUSH 0x02000000U
#define TF_TMR_REXMT 0x04000000U
#define TF_TMR_PERSIST 0x08000000U
#define TF_TMR_KEEP 0x10000000U
#define TF_TMR_2MSL 0x20000000U
#define TF_TMR_DELACK 0x40000000U
#define TF_TIMER TF_TMR_REXMT
struct mbuf *t_template;
struct inpcb *t_inpcb;
tcp_seq snd_una;
tcp_seq snd_nxt;
tcp_seq snd_up;
tcp_seq snd_wl1;
tcp_seq snd_wl2;
tcp_seq iss;
u_long snd_wnd;
int sack_enable;
int snd_numholes;
struct sackhole *snd_holes;
tcp_seq snd_last;
u_long rcv_wnd;
tcp_seq rcv_nxt;
tcp_seq rcv_up;
tcp_seq irs;
tcp_seq rcv_lastsack;
int rcv_numsacks;
struct sackblk sackblks[MAX_SACK_BLKS];
tcp_seq rcv_adv;
tcp_seq snd_max;
u_long snd_cwnd;
u_long snd_ssthresh;
uint64_t rfbuf_ts;
u_int rfbuf_cnt;
u_short t_maxopd;
u_short t_peermss;
uint64_t t_rcvtime;
uint64_t t_rcvacktime;
uint64_t t_sndtime;
uint64_t t_sndacktime;
uint64_t t_rtttime;
tcp_seq t_rtseq;
int t_srtt;
int t_rttvar;
u_int t_rttmin;
u_long max_sndwnd;
char t_oobflags;
char t_iobc;
#define TCPOOB_HAVEDATA 0x01
#define TCPOOB_HADDATA 0x02
short t_softerror;
u_char snd_scale;
u_char rcv_scale;
u_char request_r_scale;
u_char requested_s_scale;
uint32_t ts_recent;
uint32_t ts_modulate;
uint64_t ts_recent_age;
tcp_seq last_ack_sent;
LIST_HEAD(, syn_cache) t_sc;
u_int t_pmtud_mss_acked;
u_int t_pmtud_mtu_sent;
tcp_seq t_pmtud_th_seq;
u_int t_pmtud_nextmtu;
u_short t_pmtud_ip_len;
u_short t_pmtud_ip_hl;
int pf;
u_int t_rcvoopack;
u_int t_sndrexmitpack;
u_int t_sndzerowin;
};
#define intotcpcb(ip) ((struct tcpcb *)(ip)->inp_ppcb)
#define sototcpcb(so) (intotcpcb(sotoinpcb(so)))
#ifdef _KERNEL
struct tcp_opt_info {
int ts_present;
u_int32_t ts_val;
u_int32_t ts_ecr;
u_int16_t maxseg;
};
extern struct mutex syn_cache_mtx;
#define TCP_SYN_HASH_SIZE 293
#define TCP_SYN_BUCKET_SIZE 35
union syn_cache_sa {
struct sockaddr sa;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
};
struct syn_cache {
TAILQ_ENTRY(syn_cache) sc_bucketq;
struct refcnt sc_refcnt;
struct timeout sc_timer;
struct route sc_route;
long sc_win;
struct syn_cache_head *sc_buckethead;
struct syn_cache_set *sc_set;
u_int64_t sc_timestamp;
u_int32_t sc_hash;
u_int32_t sc_modulate;
union syn_cache_sa sc_src;
union syn_cache_sa sc_dst;
tcp_seq sc_irs;
tcp_seq sc_iss;
u_int sc_rtableid;
u_int sc_rxtcur;
u_int sc_rxttot;
u_int sc_rxtshift;
u_int sc_dynflags;
#define SCF_UNREACH 0x0001U
u_short sc_fixflags;
#define SCF_TIMESTAMP 0x0010U
#define SCF_SACK_PERMIT 0x0020U
#define SCF_ECN_PERMIT 0x0040U
#define SCF_SIGNATURE 0x0080U
struct mbuf *sc_ipopts;
u_int16_t sc_peermaxseg;
u_int16_t sc_ourmaxseg;
u_int sc_request_r_scale : 4,
sc_requested_s_scale : 4;
struct inpcb *sc_inplisten;
LIST_ENTRY(syn_cache) sc_tpq;
};
struct syn_cache_head {
TAILQ_HEAD(, syn_cache) sch_bucket;
u_short sch_length;
};
struct syn_cache_set {
struct syn_cache_head *scs_buckethead;
long scs_use;
int scs_size;
int scs_count;
u_int32_t scs_random[5];
};
#endif
#define TCP_RTT_SHIFT 3
#define TCP_RTTVAR_SHIFT 2
#define TCP_RTT_BASE_SHIFT 2
#define TCP_RTT_MAX (1<<18)
#define TCP_REXMTVAL(tp) \
((((tp)->t_srtt >> TCP_RTT_SHIFT) + (tp)->t_rttvar) \
>> TCP_RTT_BASE_SHIFT)
struct tcpstat {
u_int32_t tcps_connattempt;
u_int32_t tcps_accepts;
u_int32_t tcps_connects;
u_int32_t tcps_drops;
u_int32_t tcps_conndrops;
u_int32_t tcps_closed;
u_int32_t tcps_segstimed;
u_int32_t tcps_rttupdated;
u_int32_t tcps_delack;
u_int32_t tcps_timeoutdrop;
u_int32_t tcps_rexmttimeo;
u_int32_t tcps_persisttimeo;
u_int32_t tcps_persistdrop;
u_int32_t tcps_keeptimeo;
u_int32_t tcps_keepprobe;
u_int32_t tcps_keepdrops;
u_int32_t tcps_sndtotal;
u_int32_t tcps_sndpack;
u_int64_t tcps_sndbyte;
u_int32_t tcps_sndrexmitpack;
u_int64_t tcps_sndrexmitbyte;
u_int64_t tcps_sndrexmitfast;
u_int32_t tcps_sndacks;
u_int32_t tcps_sndprobe;
u_int32_t tcps_sndurg;
u_int32_t tcps_sndwinup;
u_int32_t tcps_sndctrl;
u_int32_t tcps_rcvtotal;
u_int32_t tcps_rcvpack;
u_int64_t tcps_rcvbyte;
u_int32_t tcps_rcvbadsum;
u_int32_t tcps_rcvbadoff;
u_int32_t tcps_rcvmemdrop;
u_int32_t tcps_rcvnosec;
u_int32_t tcps_rcvshort;
u_int32_t tcps_rcvduppack;
u_int64_t tcps_rcvdupbyte;
u_int32_t tcps_rcvpartduppack;
u_int64_t tcps_rcvpartdupbyte;
u_int32_t tcps_rcvoopack;
u_int64_t tcps_rcvoobyte;
u_int32_t tcps_rcvpackafterwin;
u_int64_t tcps_rcvbyteafterwin;
u_int32_t tcps_rcvafterclose;
u_int32_t tcps_rcvwinprobe;
u_int32_t tcps_rcvdupack;
u_int32_t tcps_rcvacktoomuch;
u_int32_t tcps_rcvacktooold;
u_int32_t tcps_rcvackpack;
u_int64_t tcps_rcvackbyte;
u_int32_t tcps_rcvwinupd;
u_int32_t tcps_pawsdrop;
u_int32_t tcps_predack;
u_int32_t tcps_preddat;
u_int32_t tcps_pcbhashmiss;
u_int32_t tcps_noport;
u_int32_t tcps_closing;
u_int32_t tcps_badsyn;
u_int32_t tcps_dropsyn;
u_int32_t tcps_rcvbadsig;
u_int64_t tcps_rcvgoodsig;
u_int32_t tcps_inswcsum;
u_int32_t tcps_outswcsum;
u_int32_t tcps_ecn_accepts;
u_int32_t tcps_ecn_rcvece;
u_int32_t tcps_ecn_rcvcwr;
u_int32_t tcps_ecn_rcvce;
u_int32_t tcps_ecn_sndect;
u_int32_t tcps_ecn_sndece;
u_int32_t tcps_ecn_sndcwr;
u_int32_t tcps_cwr_ecn;
u_int32_t tcps_cwr_frecovery;
u_int32_t tcps_cwr_timeout;
u_int64_t tcps_sc_added;
u_int64_t tcps_sc_completed;
u_int64_t tcps_sc_timed_out;
u_int64_t tcps_sc_overflowed;
u_int64_t tcps_sc_reset;
u_int64_t tcps_sc_unreach;
u_int64_t tcps_sc_bucketoverflow;
u_int64_t tcps_sc_aborted;
u_int64_t tcps_sc_dupesyn;
u_int64_t tcps_sc_dropped;
u_int64_t tcps_sc_collisions;
u_int64_t tcps_sc_retransmitted;
u_int64_t tcps_sc_seedrandom;
u_int64_t tcps_sc_hash_size;
u_int64_t tcps_sc_entry_count;
u_int64_t tcps_sc_entry_limit;
u_int64_t tcps_sc_bucket_maxlen;
u_int64_t tcps_sc_bucket_limit;
int64_t tcps_sc_uses_left;
u_int64_t tcps_conndrained;
u_int64_t tcps_sack_recovery_episode;
u_int64_t tcps_sack_rexmits;
u_int64_t tcps_sack_rexmit_bytes;
u_int64_t tcps_sack_rcv_opts;
u_int64_t tcps_sack_snd_opts;
u_int64_t tcps_sack_drop_opts;
u_int32_t tcps_outswtso;
u_int32_t tcps_outhwtso;
u_int32_t tcps_outpkttso;
u_int32_t tcps_outbadtso;
u_int32_t tcps_inswlro;
u_int32_t tcps_inhwlro;
u_int32_t tcps_inpktlro;
u_int32_t tcps_inbadlro;
};
#define TCPCTL_RFC1323 1
#define TCPCTL_KEEPINITTIME 2
#define TCPCTL_KEEPIDLE 3
#define TCPCTL_KEEPINTVL 4
#define TCPCTL_SLOWHZ 5
#define TCPCTL_BADDYNAMIC 6
#define TCPCTL_RECVSPACE 7
#define TCPCTL_SENDSPACE 8
#define TCPCTL_IDENT 9
#define TCPCTL_SACK 10
#define TCPCTL_MSSDFLT 11
#define TCPCTL_RSTPPSLIMIT 12
#define TCPCTL_ACK_ON_PUSH 13
#define TCPCTL_ECN 14
#define TCPCTL_SYN_CACHE_LIMIT 15
#define TCPCTL_SYN_BUCKET_LIMIT 16
#define TCPCTL_RFC3390 17
#define TCPCTL_REASS_LIMIT 18
#define TCPCTL_DROP 19
#define TCPCTL_SACKHOLE_LIMIT 20
#define TCPCTL_STATS 21
#define TCPCTL_ALWAYS_KEEPALIVE 22
#define TCPCTL_SYN_USE_LIMIT 23
#define TCPCTL_ROOTONLY 24
#define TCPCTL_SYN_HASH_SIZE 25
#define TCPCTL_TSO 26
#define TCPCTL_MAXID 27
#define TCPCTL_NAMES { \
{ 0, 0 }, \
{ "rfc1323", CTLTYPE_INT }, \
{ "keepinittime", CTLTYPE_INT }, \
{ "keepidle", CTLTYPE_INT }, \
{ "keepintvl", CTLTYPE_INT }, \
{ NULL, 0 }, \
{ "baddynamic", CTLTYPE_STRUCT }, \
{ NULL, 0 }, \
{ NULL, 0 }, \
{ "ident", CTLTYPE_STRUCT }, \
{ "sack", CTLTYPE_INT }, \
{ "mssdflt", CTLTYPE_INT }, \
{ "rstppslimit", CTLTYPE_INT }, \
{ "ackonpush", CTLTYPE_INT }, \
{ "ecn", CTLTYPE_INT }, \
{ "syncachelimit", CTLTYPE_INT }, \
{ "synbucketlimit", CTLTYPE_INT }, \
{ "rfc3390", CTLTYPE_INT }, \
{ "reasslimit", CTLTYPE_INT }, \
{ "drop", CTLTYPE_STRUCT }, \
{ "sackholelimit", CTLTYPE_INT }, \
{ "stats", CTLTYPE_STRUCT }, \
{ "always_keepalive", CTLTYPE_INT }, \
{ "synuselimit", CTLTYPE_INT }, \
{ "rootonly", CTLTYPE_STRUCT }, \
{ "synhashsize", CTLTYPE_INT }, \
{ "tso", CTLTYPE_INT }, \
}
struct tcp_ident_mapping {
struct sockaddr_storage faddr, laddr;
int euid, ruid;
u_int rdomain;
};
#ifdef _KERNEL
#include <sys/percpu.h>
#include <sys/stat.h>
enum tcpstat_counters {
tcps_connattempt,
tcps_accepts,
tcps_connects,
tcps_drops,
tcps_conndrops,
tcps_closed,
tcps_segstimed,
tcps_rttupdated,
tcps_delack,
tcps_timeoutdrop,
tcps_rexmttimeo,
tcps_persisttimeo,
tcps_persistdrop,
tcps_keeptimeo,
tcps_keepprobe,
tcps_keepdrops,
tcps_sndtotal,
tcps_sndpack,
tcps_sndbyte,
tcps_sndrexmitpack,
tcps_sndrexmitbyte,
tcps_sndrexmitfast,
tcps_sndacks,
tcps_sndprobe,
tcps_sndurg,
tcps_sndwinup,
tcps_sndctrl,
tcps_rcvtotal,
tcps_rcvpack,
tcps_rcvbyte,
tcps_rcvbadsum,
tcps_rcvbadoff,
tcps_rcvmemdrop,
tcps_rcvnosec,
tcps_rcvshort,
tcps_rcvduppack,
tcps_rcvdupbyte,
tcps_rcvpartduppack,
tcps_rcvpartdupbyte,
tcps_rcvoopack,
tcps_rcvoobyte,
tcps_rcvpackafterwin,
tcps_rcvbyteafterwin,
tcps_rcvafterclose,
tcps_rcvwinprobe,
tcps_rcvdupack,
tcps_rcvacktoomuch,
tcps_rcvacktooold,
tcps_rcvackpack,
tcps_rcvackbyte,
tcps_rcvwinupd,
tcps_pawsdrop,
tcps_predack,
tcps_preddat,
tcps_pcbhashmiss,
tcps_noport,
tcps_closing,
tcps_badsyn,
tcps_dropsyn,
tcps_rcvbadsig,
tcps_rcvgoodsig,
tcps_inswcsum,
tcps_outswcsum,
tcps_ecn_accepts,
tcps_ecn_rcvece,
tcps_ecn_rcvcwr,
tcps_ecn_rcvce,
tcps_ecn_sndect,
tcps_ecn_sndece,
tcps_ecn_sndcwr,
tcps_cwr_ecn,
tcps_cwr_frecovery,
tcps_cwr_timeout,
tcps_sc_added,
tcps_sc_completed,
tcps_sc_timed_out,
tcps_sc_overflowed,
tcps_sc_reset,
tcps_sc_unreach,
tcps_sc_bucketoverflow,
tcps_sc_aborted,
tcps_sc_dupesyn,
tcps_sc_dropped,
tcps_sc_collisions,
tcps_sc_retransmitted,
tcps_sc_seedrandom,
tcps_sc_hash_size,
tcps_sc_entry_count,
tcps_sc_entry_limit,
tcps_sc_bucket_maxlen,
tcps_sc_bucket_limit,
tcps_sc_uses_left,
tcps_conndrained,
tcps_sack_recovery_episode,
tcps_sack_rexmits,
tcps_sack_rexmit_bytes,
tcps_sack_rcv_opts,
tcps_sack_snd_opts,
tcps_sack_drop_opts,
tcps_outswtso,
tcps_outhwtso,
tcps_outpkttso,
tcps_outbadtso,
tcps_inswlro,
tcps_inhwlro,
tcps_inpktlro,
tcps_inbadlro,
tcps_ncounters,
};
extern struct cpumem *tcpcounters;
static inline void
tcpstat_inc(enum tcpstat_counters c)
{
int s = splnet();
counters_inc(tcpcounters, c);
splx(s);
}
static inline void
tcpstat_add(enum tcpstat_counters c, uint64_t v)
{
int s = splnet();
counters_add(tcpcounters, c, v);
splx(s);
}
static inline void
tcpstat_pkt(enum tcpstat_counters pcounter, enum tcpstat_counters bcounter,
uint64_t v)
{
int s = splnet();
counters_pkt(tcpcounters, pcounter, bcounter, v);
splx(s);
}
extern uint64_t tcp_starttime;
static inline uint64_t
tcp_now(void)
{
return tcp_starttime + (getnsecruntime() / 1000000ULL);
}
#define TCP_TIME(_sec) ((_sec) * 1000)
extern struct mutex tcp_timer_mtx;
extern const struct pr_usrreqs tcp_usrreqs;
#ifdef INET6
extern const struct pr_usrreqs tcp6_usrreqs;
#endif
extern struct pool tcpcb_pool;
extern struct inpcbtable tcbtable, tcb6table;
extern int tcp_do_rfc1323;
extern const int tcprexmtthresh;
extern int tcp_mssdflt;
extern int tcp_rst_ppslim;
extern int tcp_ack_on_push;
extern int tcp_do_sack;
extern struct pool sackhl_pool;
extern int tcp_sackhole_limit;
extern int tcp_do_ecn;
extern int tcp_do_rfc3390;
extern int tcp_do_tso;
extern struct pool tcpqe_pool;
extern int tcp_reass_limit;
extern int tcp_syn_hash_size;
extern int tcp_syn_cache_limit;
extern int tcp_syn_bucket_limit;
extern int tcp_syn_use_limit;
extern struct syn_cache_set tcp_syn_cache[];
extern int tcp_syn_cache_active;
struct tdb;
void tcp_canceltimers(struct tcpcb *);
struct tcpcb *
tcp_close(struct tcpcb *);
int tcp_freeq(struct tcpcb *);
#ifdef INET6
void tcp6_ctlinput(int, struct sockaddr *, u_int, void *);
#endif
void tcp_ctlinput(int, struct sockaddr *, u_int, void *);
int tcp_ctloutput(int, struct socket *, int, int, struct mbuf *);
struct tcpcb *
tcp_dodisconnect(struct tcpcb *);
struct tcpcb *
tcp_drop(struct tcpcb *, int);
int tcp_dooptions(struct tcpcb *, u_char *, int, struct tcphdr *,
struct mbuf *, int, struct tcp_opt_info *, u_int, uint64_t);
void tcp_init(void);
int tcp_input(struct mbuf **, int *, int, int, struct netstack *);
void tcp_input_mlist(struct mbuf_list *, int);
int tcp_mss(struct tcpcb *, int);
void tcp_mss_update(struct tcpcb *);
void tcp_softlro_glue(struct mbuf_list *, struct mbuf *, struct ifnet *);
u_int tcp_hdrsz(struct tcpcb *);
void tcp_mtudisc(struct inpcb *, int);
void tcp_mtudisc_increase(struct inpcb *, int);
#ifdef INET6
void tcp6_mtudisc_callback(struct sockaddr_in6 *, u_int);
#endif
struct tcpcb *
tcp_newtcpcb(struct inpcb *, int);
void tcp_notify(struct inpcb *, int);
int tcp_output(struct tcpcb *);
int tcp_softtso_chop(struct mbuf_list *, struct mbuf *, struct ifnet *,
u_int);
int tcp_if_output_tso(struct ifnet *, struct mbuf **, struct sockaddr *,
struct rtentry *, uint32_t, u_int);
void tcp_pulloutofband(struct socket *, u_int, struct mbuf *, int);
int tcp_reass(struct tcpcb *, struct tcphdr *, struct mbuf *, int *);
void tcp_rscale(struct tcpcb *, u_long);
void tcp_respond(struct tcpcb *, caddr_t, struct tcphdr *, tcp_seq,
tcp_seq, int, u_int, uint64_t);
void tcp_setpersist(struct tcpcb *);
void tcp_update_sndspace(struct tcpcb *);
void tcp_update_rcvspace(struct tcpcb *);
void tcp_slowtimo(void);
struct mbuf *
tcp_template(struct tcpcb *);
#ifndef SMALL_KERNEL
void tcp_trace(short, short, struct tcpcb *, struct tcpcb *, caddr_t,
int, int);
#endif
struct tcpcb *
tcp_usrclosed(struct tcpcb *);
int tcp_sysctl(int *, u_int, void *, size_t *, void *, size_t);
int tcp_attach(struct socket *, int, int);
int tcp_detach(struct socket *);
int tcp_bind(struct socket *, struct mbuf *, struct proc *);
int tcp_listen(struct socket *);
int tcp_connect(struct socket *, struct mbuf *);
int tcp_accept(struct socket *, struct mbuf *);
int tcp_disconnect(struct socket *);
int tcp_shutdown(struct socket *);
void tcp_rcvd(struct socket *);
int tcp_send(struct socket *, struct mbuf *, struct mbuf *,
struct mbuf *);
void tcp_abort(struct socket *);
int tcp_sockaddr(struct socket *, struct mbuf *);
int tcp_peeraddr(struct socket *, struct mbuf *);
int tcp_sense(struct socket *, struct stat *);
int tcp_rcvoob(struct socket *, struct mbuf *, int);
int tcp_sendoob(struct socket *, struct mbuf *, struct mbuf *,
struct mbuf *);
void tcp_xmit_timer(struct tcpcb *, int32_t);
void tcp_sack_option(struct tcpcb *,struct tcphdr *,u_char *,int);
void tcp_update_sack_list(struct tcpcb *tp, tcp_seq, tcp_seq);
void tcp_del_sackholes(struct tcpcb *, struct tcphdr *);
void tcp_clean_sackreport(struct tcpcb *tp);
void tcp_sack_adjust(struct tcpcb *tp);
struct sackhole *
tcp_sack_output(struct tcpcb *tp);
#ifdef DEBUG
void tcp_print_holes(struct tcpcb *tp);
#endif
u_long tcp_seq_subtract(u_long, u_long );
#ifdef TCP_SIGNATURE
int tcp_signature_apply(caddr_t, caddr_t, unsigned int);
int tcp_signature(struct tdb *, int, struct mbuf *, struct tcphdr *,
int, int, char *);
#endif
void tcp_set_iss_tsm(struct tcpcb *);
void syn_cache_unreach(const struct sockaddr *, const struct sockaddr *,
struct tcphdr *, u_int);
void syn_cache_init(void);
void syn_cache_cleanup(struct tcpcb *);
#ifdef SMALL_KERNEL
static inline void
tcp_trace(short act, short ostate, struct tcpcb *tp, struct tcpcb *otp,
caddr_t headers, int req, int len)
{
}
#endif
#endif
#endif