tcp: Add struct for TCP execution context, move hash_secret to it
We don't need to keep small data as static variables, move the only small variable we have so far to the new struct. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
bb9fb9e2d1
commit
cd14bff5ea
3 changed files with 36 additions and 17 deletions
4
passt.h
4
passt.h
|
@ -1,5 +1,7 @@
|
||||||
#define UNIX_SOCK_PATH "/tmp/passt.socket"
|
#define UNIX_SOCK_PATH "/tmp/passt.socket"
|
||||||
|
|
||||||
|
#include "tcp.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct ctx - Execution context
|
* struct ctx - Execution context
|
||||||
* @epollfd: file descriptor for epoll instance
|
* @epollfd: file descriptor for epoll instance
|
||||||
|
@ -36,4 +38,6 @@ struct ctx {
|
||||||
struct in6_addr dns6;
|
struct in6_addr dns6;
|
||||||
|
|
||||||
char ifn[IF_NAMESIZE];
|
char ifn[IF_NAMESIZE];
|
||||||
|
|
||||||
|
struct tcp_ctx tcp;
|
||||||
};
|
};
|
||||||
|
|
34
tcp.c
34
tcp.c
|
@ -453,9 +453,6 @@ static struct tcp_conn tc[MAX_CONNS];
|
||||||
/* Hash table for socket lookup given remote address, local port, remote port */
|
/* Hash table for socket lookup given remote address, local port, remote port */
|
||||||
static int tc_hash[TCP_HASH_TABLE_SIZE];
|
static int tc_hash[TCP_HASH_TABLE_SIZE];
|
||||||
|
|
||||||
/* 128-bit secret for hash functions, for initial sequence numbers and table */
|
|
||||||
static uint64_t hash_secret[2];
|
|
||||||
|
|
||||||
static int tcp_send_to_tap(struct ctx *c, int s, int flags, char *in, int len);
|
static int tcp_send_to_tap(struct ctx *c, int s, int flags, char *in, int len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -574,6 +571,7 @@ static int tcp_sock_hash_match(struct tcp_conn *conn, int af, void *addr,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tcp_sock_hash() - Calculate hash value for connection given address and ports
|
* tcp_sock_hash() - Calculate hash value for connection given address and ports
|
||||||
|
* @c: Execution context
|
||||||
* @af: Address family, AF_INET or AF_INET6
|
* @af: Address family, AF_INET or AF_INET6
|
||||||
* @addr: Remote address, pointer to sin_addr or sin6_addr
|
* @addr: Remote address, pointer to sin_addr or sin6_addr
|
||||||
* @tap_port: tap-facing port
|
* @tap_port: tap-facing port
|
||||||
|
@ -581,7 +579,7 @@ static int tcp_sock_hash_match(struct tcp_conn *conn, int af, void *addr,
|
||||||
*
|
*
|
||||||
* Return: hash value, already modulo size of the hash table
|
* Return: hash value, already modulo size of the hash table
|
||||||
*/
|
*/
|
||||||
static unsigned int tcp_sock_hash(int af, void *addr,
|
static unsigned int tcp_sock_hash(struct ctx *c, int af, void *addr,
|
||||||
in_port_t tap_port, in_port_t sock_port)
|
in_port_t tap_port, in_port_t sock_port)
|
||||||
{
|
{
|
||||||
uint64_t b;
|
uint64_t b;
|
||||||
|
@ -597,7 +595,7 @@ static unsigned int tcp_sock_hash(int af, void *addr,
|
||||||
.sock_port = sock_port,
|
.sock_port = sock_port,
|
||||||
};
|
};
|
||||||
|
|
||||||
b = siphash_8b((uint8_t *)&in, hash_secret);
|
b = siphash_8b((uint8_t *)&in, c->tcp.hash_secret);
|
||||||
} else if (af == AF_INET6) {
|
} else if (af == AF_INET6) {
|
||||||
struct {
|
struct {
|
||||||
struct in6_addr addr;
|
struct in6_addr addr;
|
||||||
|
@ -609,7 +607,7 @@ static unsigned int tcp_sock_hash(int af, void *addr,
|
||||||
.sock_port = sock_port,
|
.sock_port = sock_port,
|
||||||
};
|
};
|
||||||
|
|
||||||
b = siphash_20b((uint8_t *)&in, hash_secret);
|
b = siphash_20b((uint8_t *)&in, c->tcp.hash_secret);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (unsigned int)(b % TCP_HASH_TABLE_SIZE);
|
return (unsigned int)(b % TCP_HASH_TABLE_SIZE);
|
||||||
|
@ -617,18 +615,19 @@ static unsigned int tcp_sock_hash(int af, void *addr,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tcp_sock_hash_insert() - Insert socket into hash table, chain link if needed
|
* tcp_sock_hash_insert() - Insert socket into hash table, chain link if needed
|
||||||
|
* @c: Execution context
|
||||||
* @s: File descriptor number for socket
|
* @s: File descriptor number for socket
|
||||||
* @af: Address family, AF_INET or AF_INET6
|
* @af: Address family, AF_INET or AF_INET6
|
||||||
* @addr: Remote address, pointer to sin_addr or sin6_addr
|
* @addr: Remote address, pointer to sin_addr or sin6_addr
|
||||||
* @tap_port: tap-facing port
|
* @tap_port: tap-facing port
|
||||||
* @sock_port: Socket-facing port
|
* @sock_port: Socket-facing port
|
||||||
*/
|
*/
|
||||||
static void tcp_sock_hash_insert(int s, int af, void *addr,
|
static void tcp_sock_hash_insert(struct ctx *c, int s, int af, void *addr,
|
||||||
in_port_t tap_port, in_port_t sock_port)
|
in_port_t tap_port, in_port_t sock_port)
|
||||||
{
|
{
|
||||||
int b;
|
int b;
|
||||||
|
|
||||||
b = tcp_sock_hash(af, addr, tap_port, sock_port);
|
b = tcp_sock_hash(c, af, addr, tap_port, sock_port);
|
||||||
tc[s].next = tc_hash[b] ? &tc[tc_hash[b]] : NULL;
|
tc[s].next = tc_hash[b] ? &tc[tc_hash[b]] : NULL;
|
||||||
tc_hash[b] = tc[s].sock = s;
|
tc_hash[b] = tc[s].sock = s;
|
||||||
tc[s].hash_bucket = b;
|
tc[s].hash_bucket = b;
|
||||||
|
@ -657,6 +656,7 @@ static void tcp_sock_hash_remove(int b, int s)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tcp_sock_hash_lookup() - Look up socket given remote address and ports
|
* tcp_sock_hash_lookup() - Look up socket given remote address and ports
|
||||||
|
* @c: Execution context
|
||||||
* @af: Address family, AF_INET or AF_INET6
|
* @af: Address family, AF_INET or AF_INET6
|
||||||
* @addr: Remote address, pointer to sin_addr or sin6_addr
|
* @addr: Remote address, pointer to sin_addr or sin6_addr
|
||||||
* @tap_port: tap-facing port
|
* @tap_port: tap-facing port
|
||||||
|
@ -664,13 +664,13 @@ static void tcp_sock_hash_remove(int b, int s)
|
||||||
*
|
*
|
||||||
* Return: file descriptor number for socket, if found, -ENOENT otherwise
|
* Return: file descriptor number for socket, if found, -ENOENT otherwise
|
||||||
*/
|
*/
|
||||||
static int tcp_sock_hash_lookup(int af, void *addr,
|
static int tcp_sock_hash_lookup(struct ctx *c, int af, void *addr,
|
||||||
in_port_t tap_port, in_port_t sock_port)
|
in_port_t tap_port, in_port_t sock_port)
|
||||||
{
|
{
|
||||||
struct tcp_conn *conn;
|
struct tcp_conn *conn;
|
||||||
int b;
|
int b;
|
||||||
|
|
||||||
b = tcp_sock_hash(af, addr, tap_port, sock_port);
|
b = tcp_sock_hash(c, af, addr, tap_port, sock_port);
|
||||||
if (!tc_hash[b])
|
if (!tc_hash[b])
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
|
@ -869,7 +869,7 @@ static uint32_t tcp_seq_init(struct ctx *c, int af, void *addr,
|
||||||
.dstport = dstport,
|
.dstport = dstport,
|
||||||
};
|
};
|
||||||
|
|
||||||
seq = siphash_12b((uint8_t *)&in, hash_secret);
|
seq = siphash_12b((uint8_t *)&in, c->tcp.hash_secret);
|
||||||
} else if (af == AF_INET6) {
|
} else if (af == AF_INET6) {
|
||||||
struct {
|
struct {
|
||||||
struct in6_addr src;
|
struct in6_addr src;
|
||||||
|
@ -883,7 +883,7 @@ static uint32_t tcp_seq_init(struct ctx *c, int af, void *addr,
|
||||||
.dstport = dstport,
|
.dstport = dstport,
|
||||||
};
|
};
|
||||||
|
|
||||||
seq = siphash_36b((uint8_t *)&in, hash_secret);
|
seq = siphash_36b((uint8_t *)&in, c->tcp.hash_secret);
|
||||||
}
|
}
|
||||||
|
|
||||||
ns = ts.tv_sec * 1E9;
|
ns = ts.tv_sec * 1E9;
|
||||||
|
@ -963,7 +963,7 @@ static void tcp_conn_from_tap(struct ctx *c, int af, void *addr,
|
||||||
tc[s].seq_to_tap = tcp_seq_init(c, af, addr, th->dest, th->source);
|
tc[s].seq_to_tap = tcp_seq_init(c, af, addr, th->dest, th->source);
|
||||||
tc[s].seq_ack_from_tap = tc[s].seq_to_tap + 1;
|
tc[s].seq_ack_from_tap = tc[s].seq_to_tap + 1;
|
||||||
|
|
||||||
tcp_sock_hash_insert(s, af, addr, th->source, th->dest);
|
tcp_sock_hash_insert(c, s, af, addr, th->source, th->dest);
|
||||||
|
|
||||||
if (connect(s, sa, sl)) {
|
if (connect(s, sa, sl)) {
|
||||||
if (errno != EINPROGRESS) {
|
if (errno != EINPROGRESS) {
|
||||||
|
@ -1016,7 +1016,7 @@ static void tcp_conn_from_sock(struct ctx *c, int fd)
|
||||||
tc[s].sock_port,
|
tc[s].sock_port,
|
||||||
tc[s].tap_port);
|
tc[s].tap_port);
|
||||||
|
|
||||||
tcp_sock_hash_insert(s, AF_INET, &sa4->sin_addr,
|
tcp_sock_hash_insert(c, s, AF_INET, &sa4->sin_addr,
|
||||||
tc[s].tap_port, tc[s].sock_port);
|
tc[s].tap_port, tc[s].sock_port);
|
||||||
} else if (sa_l.ss_family == AF_INET6) {
|
} else if (sa_l.ss_family == AF_INET6) {
|
||||||
struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&sa_r;
|
struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&sa_r;
|
||||||
|
@ -1030,7 +1030,7 @@ static void tcp_conn_from_sock(struct ctx *c, int fd)
|
||||||
tc[s].sock_port,
|
tc[s].sock_port,
|
||||||
tc[s].tap_port);
|
tc[s].tap_port);
|
||||||
|
|
||||||
tcp_sock_hash_insert(s, AF_INET6, &sa6->sin6_addr,
|
tcp_sock_hash_insert(c, s, AF_INET6, &sa6->sin6_addr,
|
||||||
tc[s].tap_port, tc[s].sock_port);
|
tc[s].tap_port, tc[s].sock_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1201,7 +1201,7 @@ void tcp_tap_handler(struct ctx *c, int af, void *addr, char *in, size_t len)
|
||||||
if (off < sizeof(*th) || off > len)
|
if (off < sizeof(*th) || off > len)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((s = tcp_sock_hash_lookup(af, addr, th->source, th->dest)) < 0) {
|
if ((s = tcp_sock_hash_lookup(c, af, addr, th->source, th->dest)) < 0) {
|
||||||
if (th->syn)
|
if (th->syn)
|
||||||
tcp_conn_from_tap(c, af, addr, th, len);
|
tcp_conn_from_tap(c, af, addr, th, len);
|
||||||
return;
|
return;
|
||||||
|
@ -1431,7 +1431,7 @@ int tcp_sock_init(struct ctx *c)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
getrandom(hash_secret, sizeof(hash_secret), GRND_RANDOM);
|
getrandom(&c->tcp.hash_secret, sizeof(c->tcp.hash_secret), GRND_RANDOM);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
15
tcp.h
15
tcp.h
|
@ -1,4 +1,19 @@
|
||||||
|
#ifndef TCP_H
|
||||||
|
#define TCP_H
|
||||||
|
|
||||||
|
struct ctx;
|
||||||
|
|
||||||
void tcp_sock_handler(struct ctx *c, int s, uint32_t events);
|
void tcp_sock_handler(struct ctx *c, int s, uint32_t events);
|
||||||
void tcp_tap_handler(struct ctx *c, int af, void *addr, char *in, size_t len);
|
void tcp_tap_handler(struct ctx *c, int af, void *addr, char *in, size_t len);
|
||||||
int tcp_sock_init(struct ctx *c);
|
int tcp_sock_init(struct ctx *c);
|
||||||
void tcp_timer(struct ctx *c, struct timespec *ts);
|
void tcp_timer(struct ctx *c, struct timespec *ts);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct tcp_ctx - Execution context for TCP routines
|
||||||
|
* @hash_secret: 128-bit secret for hash functions, ISN and hash table
|
||||||
|
*/
|
||||||
|
struct tcp_ctx {
|
||||||
|
uint64_t hash_secret[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* TCP_H */
|
||||||
|
|
Loading…
Reference in a new issue