mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 01:58:19 +00:00
Merge #5856
5856: Fix receiving IPv6 packets after IPv4 ones on Linux r=def- a=heinrich5991 Previously, the socket addresses were truncated as the `msg_namelen` field is both input **and** output: After receiving an IPv4 packet, the socket address field would be too short for an IPv6 address. ## Checklist - [ ] Tested the change ingame - [ ] Provided screenshots if it is a visual change - [ ] Tested in combination with possibly related configuration options - [x] Written a unit test (especially base/) or added coverage to integration test - [ ] Considered possible null pointers and out of bounds array indexing - [ ] Changed no physics that affect existing maps - [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional) Co-authored-by: heinrich5991 <heinrich5991@gmail.com>
This commit is contained in:
commit
bc8ec8c1d7
|
@ -2519,6 +2519,7 @@ if(GTEST_FOUND OR DOWNLOAD_GTEST)
|
||||||
json.cpp
|
json.cpp
|
||||||
mapbugs.cpp
|
mapbugs.cpp
|
||||||
name_ban.cpp
|
name_ban.cpp
|
||||||
|
net.cpp
|
||||||
netaddr.cpp
|
netaddr.cpp
|
||||||
os.cpp
|
os.cpp
|
||||||
packer.cpp
|
packer.cpp
|
||||||
|
|
|
@ -149,6 +149,7 @@ typedef struct
|
||||||
} NETSOCKET_BUFFER;
|
} NETSOCKET_BUFFER;
|
||||||
|
|
||||||
void net_buffer_init(NETSOCKET_BUFFER *buffer);
|
void net_buffer_init(NETSOCKET_BUFFER *buffer);
|
||||||
|
void net_buffer_reinit(NETSOCKET_BUFFER *buffer);
|
||||||
void net_buffer_simple(NETSOCKET_BUFFER *buffer, char **buf, int *size);
|
void net_buffer_simple(NETSOCKET_BUFFER *buffer, char **buf, int *size);
|
||||||
|
|
||||||
struct NETSOCKET_INTERNAL
|
struct NETSOCKET_INTERNAL
|
||||||
|
@ -1698,6 +1699,16 @@ void net_buffer_init(NETSOCKET_BUFFER *buffer)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void net_buffer_reinit(NETSOCKET_BUFFER *buffer)
|
||||||
|
{
|
||||||
|
#if defined(CONF_PLATFORM_LINUX)
|
||||||
|
for(int i = 0; i < VLEN; i++)
|
||||||
|
{
|
||||||
|
buffer->msgs[i].msg_hdr.msg_namelen = sizeof(buffer->sockaddrs[i]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void net_buffer_simple(NETSOCKET_BUFFER *buffer, char **buf, int *size)
|
void net_buffer_simple(NETSOCKET_BUFFER *buffer, char **buf, int *size)
|
||||||
{
|
{
|
||||||
#if defined(CONF_PLATFORM_LINUX)
|
#if defined(CONF_PLATFORM_LINUX)
|
||||||
|
@ -1719,6 +1730,7 @@ int net_udp_recv(NETSOCKET sock, NETADDR *addr, unsigned char **data)
|
||||||
{
|
{
|
||||||
if(sock->buffer.pos >= sock->buffer.size)
|
if(sock->buffer.pos >= sock->buffer.size)
|
||||||
{
|
{
|
||||||
|
net_buffer_reinit(&sock->buffer);
|
||||||
sock->buffer.size = recvmmsg(sock->ipv4sock, sock->buffer.msgs, VLEN, 0, NULL);
|
sock->buffer.size = recvmmsg(sock->ipv4sock, sock->buffer.msgs, VLEN, 0, NULL);
|
||||||
sock->buffer.pos = 0;
|
sock->buffer.pos = 0;
|
||||||
}
|
}
|
||||||
|
@ -1728,6 +1740,7 @@ int net_udp_recv(NETSOCKET sock, NETADDR *addr, unsigned char **data)
|
||||||
{
|
{
|
||||||
if(sock->buffer.pos >= sock->buffer.size)
|
if(sock->buffer.pos >= sock->buffer.size)
|
||||||
{
|
{
|
||||||
|
net_buffer_reinit(&sock->buffer);
|
||||||
sock->buffer.size = recvmmsg(sock->ipv6sock, sock->buffer.msgs, VLEN, 0, NULL);
|
sock->buffer.size = recvmmsg(sock->ipv6sock, sock->buffer.msgs, VLEN, 0, NULL);
|
||||||
sock->buffer.pos = 0;
|
sock->buffer.pos = 0;
|
||||||
}
|
}
|
||||||
|
|
47
src/test/net.cpp
Normal file
47
src/test/net.cpp
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <base/system.h>
|
||||||
|
|
||||||
|
TEST(Net, Ipv4AndIpv6Work)
|
||||||
|
{
|
||||||
|
NETADDR Bindaddr = {};
|
||||||
|
NETSOCKET Socket1;
|
||||||
|
NETSOCKET Socket2;
|
||||||
|
|
||||||
|
Bindaddr.type = NETTYPE_IPV4 | NETTYPE_IPV6;
|
||||||
|
Socket2 = net_udp_create(Bindaddr);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Bindaddr.port = secure_rand() % 64511 + 1024;
|
||||||
|
} while(!(Socket1 = net_udp_create(Bindaddr)));
|
||||||
|
|
||||||
|
NETADDR LocalhostV4;
|
||||||
|
NETADDR LocalhostV6;
|
||||||
|
NETADDR TargetV4;
|
||||||
|
NETADDR TargetV6;
|
||||||
|
ASSERT_FALSE(net_addr_from_str(&LocalhostV4, "127.0.0.1"));
|
||||||
|
ASSERT_FALSE(net_addr_from_str(&LocalhostV6, "[::1]"));
|
||||||
|
TargetV4 = LocalhostV4;
|
||||||
|
TargetV6 = LocalhostV6;
|
||||||
|
TargetV4.port = Bindaddr.port;
|
||||||
|
TargetV6.port = Bindaddr.port;
|
||||||
|
|
||||||
|
NETADDR Addr;
|
||||||
|
unsigned char *pData;
|
||||||
|
|
||||||
|
EXPECT_EQ(net_udp_send(Socket2, &TargetV4, "abc", 3), 3);
|
||||||
|
|
||||||
|
EXPECT_EQ(net_socket_read_wait(Socket1, 10000000), 1);
|
||||||
|
ASSERT_EQ(net_udp_recv(Socket1, &Addr, &pData), 3);
|
||||||
|
Addr.port = 0;
|
||||||
|
EXPECT_EQ(Addr, LocalhostV4);
|
||||||
|
EXPECT_EQ(mem_comp(pData, "abc", 3), 0);
|
||||||
|
|
||||||
|
EXPECT_EQ(net_udp_send(Socket2, &TargetV6, "def", 3), 3);
|
||||||
|
|
||||||
|
EXPECT_EQ(net_socket_read_wait(Socket1, 10000000), 1);
|
||||||
|
ASSERT_EQ(net_udp_recv(Socket1, &Addr, &pData), 3);
|
||||||
|
Addr.port = 0;
|
||||||
|
EXPECT_EQ(Addr, LocalhostV6);
|
||||||
|
EXPECT_EQ(mem_comp(pData, "def", 3), 0);
|
||||||
|
}
|
Loading…
Reference in a new issue