-/* $OpenBSD: tcp_input.c,v 1.388 2023/05/30 19:32:57 bluhm Exp $ */
+/* $OpenBSD: tcp_input.c,v 1.389 2023/07/06 09:15:23 bluhm Exp $ */
/* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */
/*
#define TCP_PAWS_IDLE TCP_TIME(24 * 24 * 60 * 60)
/* for modulo comparisons of timestamps */
-#define TSTMP_LT(a,b) ((int)((a)-(b)) < 0)
-#define TSTMP_GEQ(a,b) ((int)((a)-(b)) >= 0)
+#define TSTMP_LT(a,b) ((int32_t)((a)-(b)) < 0)
+#define TSTMP_GEQ(a,b) ((int32_t)((a)-(b)) >= 0)
/* for TCP SACK comparisons */
#define SEQ_MIN(a,b) (SEQ_LT(a,b) ? (a) : (b))
void syn_cache_put(struct syn_cache *);
void syn_cache_rm(struct syn_cache *);
-int syn_cache_respond(struct syn_cache *, struct mbuf *, uint32_t);
+int syn_cache_respond(struct syn_cache *, struct mbuf *, uint64_t);
void syn_cache_timer(void *);
void syn_cache_reaper(void *);
void syn_cache_insert(struct syn_cache *, struct tcpcb *);
struct tcphdr *, u_int);
int syn_cache_add(struct sockaddr *, struct sockaddr *, struct tcphdr *,
unsigned int, struct socket *, struct mbuf *, u_char *, int,
- struct tcp_opt_info *, tcp_seq *, uint32_t);
+ struct tcp_opt_info *, tcp_seq *, uint64_t);
struct socket *syn_cache_get(struct sockaddr *, struct sockaddr *,
struct tcphdr *, unsigned int, unsigned int, struct socket *,
- struct mbuf *, uint32_t);
+ struct mbuf *, uint64_t);
struct syn_cache *syn_cache_lookup(struct sockaddr *, struct sockaddr *,
struct syn_cache_head **, u_int);
short ostate;
caddr_t saveti;
tcp_seq iss, *reuse = NULL;
- uint32_t now;
+ uint64_t now;
u_long tiwin;
struct tcp_opt_info opti;
struct tcphdr *th;
goto drop;
if (opti.ts_present && opti.ts_ecr) {
- int rtt_test;
+ int32_t rtt_test;
/* subtract out the tcp timestamp modulator */
opti.ts_ecr -= tp->ts_modulate;
TSTMP_LT(opti.ts_val, tp->ts_recent)) {
/* Check to see if ts_recent is over 24 days old. */
- if ((int)(now - tp->ts_recent_age) > TCP_PAWS_IDLE) {
+ if (now - tp->ts_recent_age > TCP_PAWS_IDLE) {
/*
* Invalidate ts_recent. If this segment updates
* ts_recent, the age will be reset later and ts_recent
int
tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt, struct tcphdr *th,
struct mbuf *m, int iphlen, struct tcp_opt_info *oi,
- u_int rtableid, uint32_t now)
+ u_int rtableid, uint64_t now)
{
u_int16_t mss = 0;
int opt, optlen;
* and update averages and current timeout.
*/
void
-tcp_xmit_timer(struct tcpcb *tp, int rtt)
+tcp_xmit_timer(struct tcpcb *tp, int32_t rtt)
{
int delta, rttmin;
syn_cache_timer(void *arg)
{
struct syn_cache *sc = arg;
- uint32_t now;
+ uint64_t now;
NET_LOCK();
if (sc->sc_flags & SCF_DEAD)
*/
struct socket *
syn_cache_get(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th,
- u_int hlen, u_int tlen, struct socket *so, struct mbuf *m, uint32_t now)
+ u_int hlen, u_int tlen, struct socket *so, struct mbuf *m, uint64_t now)
{
struct syn_cache *sc;
struct syn_cache_head *scp;
int
syn_cache_add(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th,
u_int iphlen, struct socket *so, struct mbuf *m, u_char *optp, int optlen,
- struct tcp_opt_info *oi, tcp_seq *issp, uint32_t now)
+ struct tcp_opt_info *oi, tcp_seq *issp, uint64_t now)
{
struct tcpcb tb, *tp;
long win;
}
int
-syn_cache_respond(struct syn_cache *sc, struct mbuf *m, uint32_t now)
+syn_cache_respond(struct syn_cache *sc, struct mbuf *m, uint64_t now)
{
u_int8_t *optp;
int optlen, error;
-/* $OpenBSD: tcp_output.c,v 1.139 2023/07/04 10:48:19 bluhm Exp $ */
+/* $OpenBSD: tcp_output.c,v 1.140 2023/07/06 09:15:24 bluhm Exp $ */
/* $NetBSD: tcp_output.c,v 1.16 1997/06/03 16:17:09 kml Exp $ */
/*
int idle, sendalot = 0;
int i, sack_rxmit = 0;
struct sackhole *p;
- uint32_t now;
+ uint64_t now;
#ifdef TCP_SIGNATURE
unsigned int sigoff;
#endif /* TCP_SIGNATURE */
-/* $OpenBSD: tcp_subr.c,v 1.191 2023/05/10 12:07:16 bluhm Exp $ */
+/* $OpenBSD: tcp_subr.c,v 1.192 2023/07/06 09:15:24 bluhm Exp $ */
/* $NetBSD: tcp_subr.c,v 1.22 1996/02/13 23:44:00 christos Exp $ */
/*
u_char tcp_secret[16]; /* [I] */
SHA2_CTX tcp_secret_ctx; /* [I] */
tcp_seq tcp_iss; /* [T] updated by timer and connection */
+uint64_t tcp_starttime; /* [I] random offset for tcp_now() */
/*
* Tcp initialization
tcp_init(void)
{
tcp_iss = 1; /* wrong */
+ /* 0 is treated special so add 1, 63 bits to count is enough */
+ arc4random_buf(&tcp_starttime, sizeof(tcp_starttime));
+ tcp_starttime = 1ULL + (tcp_starttime / 2);
pool_init(&tcpcb_pool, sizeof(struct tcpcb), 0, IPL_SOFTNET, 0,
"tcpcb", NULL);
pool_init(&tcpqe_pool, sizeof(struct tcpqent), 0, IPL_SOFTNET, 0,
*/
void
tcp_respond(struct tcpcb *tp, caddr_t template, struct tcphdr *th0,
- tcp_seq ack, tcp_seq seq, int flags, u_int rtableid, uint32_t now)
+ tcp_seq ack, tcp_seq seq, int flags, u_int rtableid, uint64_t now)
{
int tlen;
int win = 0;
-/* $OpenBSD: tcp_timer.c,v 1.72 2023/03/14 00:24:05 yasuoka Exp $ */
+/* $OpenBSD: tcp_timer.c,v 1.73 2023/07/06 09:15:24 bluhm Exp $ */
/* $NetBSD: tcp_timer.c,v 1.14 1996/02/13 23:44:09 christos Exp $ */
/*
struct tcpcb *otp = NULL, *tp = arg;
uint32_t rto;
short ostate;
- uint32_t now;
+ uint64_t now;
NET_LOCK();
/* Ignore canceled timeouts or timeouts that have been rescheduled. */
tp->t_inpcb->inp_socket->so_options & SO_KEEPALIVE) &&
tp->t_state <= TCPS_CLOSING) {
int maxidle;
- uint32_t now;
+ uint64_t now;
maxidle = READ_ONCE(tcp_maxidle);
now = tcp_now();
struct tcpcb *otp = NULL, *tp = arg;
short ostate;
int maxidle;
- uint32_t now;
+ uint64_t now;
NET_LOCK();
/* Ignore canceled timeouts or timeouts that have been rescheduled. */
-/* $OpenBSD: tcp_usrreq.c,v 1.220 2023/07/02 19:59:15 bluhm Exp $ */
+/* $OpenBSD: tcp_usrreq.c,v 1.221 2023/07/06 09:15:24 bluhm Exp $ */
/* $NetBSD: tcp_usrreq.c,v 1.20 1996/02/13 23:44:16 christos Exp $ */
/*
struct proc *p = curproc;
struct tcp_info *ti;
u_int t = 1000; /* msec => usec */
- uint32_t now;
+ uint64_t now;
if (sizeof(*ti) > MLEN) {
MCLGETL(m, M_WAITOK, sizeof(*ti));
-/* $OpenBSD: tcp_var.h,v 1.168 2023/07/02 19:59:15 bluhm Exp $ */
+/* $OpenBSD: tcp_var.h,v 1.169 2023/07/06 09:15:24 bluhm Exp $ */
/* $NetBSD: tcp_var.h,v 1.17 1996/02/13 23:44:24 christos Exp $ */
/*
*/
/* auto-sizing variables */
+ uint64_t rfbuf_ts; /* recv buffer autoscaling time stamp */
u_int rfbuf_cnt; /* recv buffer autoscaling byte count */
- u_int32_t rfbuf_ts; /* recv buffer autoscaling time stamp */
u_short t_maxopd; /* mss plus options */
u_short t_peermss; /* peer's maximum segment size */
* transmit timing stuff. See below for scale of srtt and rttvar.
* "Variance" is actually smoothed difference.
*/
- uint32_t t_rcvtime; /* time last segment received */
- uint32_t t_rcvacktime; /* time last ack received */
- uint32_t t_sndtime; /* time last segment sent */
- uint32_t t_sndacktime; /* time last ack sent */
- uint32_t t_rtttime; /* time we started measuring rtt */
+ uint64_t t_rcvtime; /* time last segment received */
+ uint64_t t_rcvacktime; /* time last ack received */
+ uint64_t t_sndtime; /* time last segment sent */
+ uint64_t t_sndacktime; /* time last ack sent */
+ uint64_t t_rtttime; /* time we started measuring rtt */
tcp_seq t_rtseq; /* sequence number being timed */
int t_srtt; /* smoothed round-trip time */
int t_rttvar; /* variance in round-trip time */
u_char rcv_scale; /* window scaling for recv window */
u_char request_r_scale; /* pending window scaling */
u_char requested_s_scale;
- u_int32_t ts_recent; /* timestamp echo data */
- u_int32_t ts_modulate; /* modulation on timestamp */
- u_int32_t ts_recent_age; /* when last updated */
+ uint32_t ts_recent; /* timestamp echo data */
+ uint32_t ts_modulate; /* modulation on timestamp */
+ uint64_t ts_recent_age; /* when last updated */
tcp_seq last_ack_sent;
/* pointer for syn cache entries*/
long sc_win; /* advertised window */
struct syn_cache_head *sc_buckethead; /* our bucket index */
struct syn_cache_set *sc_set; /* our syn cache set */
+ u_int64_t sc_timestamp; /* timestamp from SYN */
u_int32_t sc_hash;
- u_int32_t sc_timestamp; /* timestamp from SYN */
u_int32_t sc_modulate; /* our timestamp modulator */
-#if 0
- u_int32_t sc_timebase; /* our local timebase */
-#endif
union syn_cache_sa sc_src;
union syn_cache_sa sc_dst;
tcp_seq sc_irs;
counters_pkt(tcpcounters, pcounter, bcounter, v);
}
-static inline uint32_t
+extern uint64_t tcp_starttime;
+
+static inline uint64_t
tcp_now(void)
{
- return (getnsecruntime() / 1000000);
+ /* TCP time ticks in 63 bit milliseconds with 63 bit random offset. */
+ return tcp_starttime + (getnsecruntime() / 1000000ULL);
}
#define TCP_TIME(_sec) ((_sec) * 1000) /* tcp_now() is in milliseconds */
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, uint32_t);
+ struct mbuf *, int, struct tcp_opt_info *, u_int, uint64_t);
void tcp_init(void);
int tcp_input(struct mbuf **, int *, int, int);
int tcp_mss(struct tcpcb *, 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, uint32_t);
+ tcp_seq, int, u_int, uint64_t);
void tcp_setpersist(struct tcpcb *);
void tcp_update_sndspace(struct tcpcb *);
void tcp_update_rcvspace(struct tcpcb *);
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 *, int);
+void tcp_xmit_timer(struct tcpcb *, int32_t);
void tcpdropoldhalfopen(struct tcpcb *, u_int16_t);
void tcp_sack_option(struct tcpcb *,struct tcphdr *,u_char *,int);
void tcp_update_sack_list(struct tcpcb *tp, tcp_seq, tcp_seq);