tcp: Unify initial sequence number calculation for IPv4 and IPv6
tcp_seq_init() has separate paths for IPv4 and IPv6 addresses, which means we will calculate different sequence numbers for IPv4 and equivalent IPv4-mapped IPv6 addresses. Change it to treat these the same by always converting the input address into an inany_addr representation and use that to calculate the sequence number. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
7114fc92eb
commit
a93bfada5b
2 changed files with 19 additions and 28 deletions
|
@ -123,6 +123,7 @@ uint64_t siphash_8b(const uint8_t *in, const uint64_t *k)
|
||||||
*
|
*
|
||||||
* Return: 32 bits obtained by XORing the two halves of the 64-bit hash output
|
* Return: 32 bits obtained by XORing the two halves of the 64-bit hash output
|
||||||
*/
|
*/
|
||||||
|
/* cppcheck-suppress unusedFunction */
|
||||||
uint32_t siphash_12b(const uint8_t *in, const uint64_t *k)
|
uint32_t siphash_12b(const uint8_t *in, const uint64_t *k)
|
||||||
{
|
{
|
||||||
uint32_t *in32 = (uint32_t *)in;
|
uint32_t *in32 = (uint32_t *)in;
|
||||||
|
|
46
tcp.c
46
tcp.c
|
@ -1942,37 +1942,27 @@ static uint32_t tcp_seq_init(const struct ctx *c, int af, const void *addr,
|
||||||
in_port_t dstport, in_port_t srcport,
|
in_port_t dstport, in_port_t srcport,
|
||||||
const struct timespec *now)
|
const struct timespec *now)
|
||||||
{
|
{
|
||||||
|
union inany_addr aany;
|
||||||
|
struct {
|
||||||
|
union inany_addr src;
|
||||||
|
in_port_t srcport;
|
||||||
|
union inany_addr dst;
|
||||||
|
in_port_t dstport;
|
||||||
|
} __attribute__((__packed__)) in = {
|
||||||
|
.srcport = srcport,
|
||||||
|
.dstport = dstport,
|
||||||
|
};
|
||||||
uint32_t ns, seq = 0;
|
uint32_t ns, seq = 0;
|
||||||
|
|
||||||
if (af == AF_INET) {
|
inany_from_af(&aany, af, addr);
|
||||||
struct {
|
in.src = aany;
|
||||||
struct in_addr src;
|
if (af == AF_INET)
|
||||||
in_port_t srcport;
|
inany_from_af(&aany, AF_INET, &c->ip4.addr);
|
||||||
struct in_addr dst;
|
else
|
||||||
in_port_t dstport;
|
inany_from_af(&aany, AF_INET6, &c->ip6.addr);
|
||||||
} __attribute__((__packed__)) in = {
|
in.dst = aany;
|
||||||
.src = *(struct in_addr *)addr,
|
|
||||||
.srcport = srcport,
|
|
||||||
.dst = c->ip4.addr,
|
|
||||||
.dstport = dstport,
|
|
||||||
};
|
|
||||||
|
|
||||||
seq = siphash_12b((uint8_t *)&in, c->tcp.hash_secret);
|
seq = siphash_36b((uint8_t *)&in, c->tcp.hash_secret);
|
||||||
} else if (af == AF_INET6) {
|
|
||||||
struct {
|
|
||||||
struct in6_addr src;
|
|
||||||
in_port_t srcport;
|
|
||||||
struct in6_addr dst;
|
|
||||||
in_port_t dstport;
|
|
||||||
} __attribute__((__packed__)) in = {
|
|
||||||
.src = *(struct in6_addr *)addr,
|
|
||||||
.srcport = srcport,
|
|
||||||
.dst = c->ip6.addr,
|
|
||||||
.dstport = dstport,
|
|
||||||
};
|
|
||||||
|
|
||||||
seq = siphash_36b((uint8_t *)&in, c->tcp.hash_secret);
|
|
||||||
}
|
|
||||||
|
|
||||||
ns = now->tv_sec * 1E9;
|
ns = now->tv_sec * 1E9;
|
||||||
ns += now->tv_nsec >> 5; /* 32ns ticks, overflows 32 bits every 137s */
|
ns += now->tv_nsec >> 5; /* 32ns ticks, overflows 32 bits every 137s */
|
||||||
|
|
Loading…
Reference in a new issue