mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-12-07 21:59:54 +00:00
LibCore: Define SocketAddress out-of-line to remove SocketAddressWindows
SocketAddressWindows.h contains a bunch of copy-pasted Windows definitions. This started causing ad-nauseam redefinition errors when implementing the HTTP disk cache for Windows. Instead, let's forward-declare the types we can in SocketAddress.h and only define the couple of constants that we need. We can then assert at compile-time that we defined them correctly.
This commit is contained in:
parent
5c88c3718b
commit
90525f7e97
Notes:
github-actions[bot]
2025-12-01 11:35:35 +00:00
Author: https://github.com/trflynn89
Commit: 90525f7e97
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6979
11 changed files with 157 additions and 230 deletions
|
|
@ -8,6 +8,7 @@ set(SOURCES
|
|||
DirIterator.cpp
|
||||
Environment.cpp
|
||||
File.cpp
|
||||
SocketAddress.cpp
|
||||
StandardPaths.cpp
|
||||
Version.cpp
|
||||
)
|
||||
|
|
@ -147,7 +148,6 @@ if (ANDROID)
|
|||
endif()
|
||||
|
||||
if (ENABLE_SWIFT)
|
||||
set(SWIFT_EXCLUDE_HEADERS "SocketAddressWindows.h")
|
||||
if(WIN32)
|
||||
list(APPEND SWIFT_EXCLUDE_HEADERS "EventLoopImplementationUnix.h")
|
||||
else()
|
||||
|
|
|
|||
114
Libraries/LibCore/SocketAddress.cpp
Normal file
114
Libraries/LibCore/SocketAddress.cpp
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <andreas@ladybird.org>
|
||||
* Copyright (c) 2022, the SerenityOS developers.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibCore/SocketAddress.h>
|
||||
|
||||
#if defined(AK_OS_WINDOWS)
|
||||
// SOCK_STREAM and SOCK_DGRAM are defined with #define. Let's cache our custom definitions before including Windows
|
||||
// headers to ensure we defined them correctly.
|
||||
static constexpr auto LADYBIRD_SOCK_STREAM = SOCK_STREAM;
|
||||
static constexpr auto LADYBIRD_SOCK_DGRAM = SOCK_DGRAM;
|
||||
|
||||
# include <AK/Windows.h>
|
||||
# include <ws2tcpip.h>
|
||||
|
||||
static_assert(LADYBIRD_SOCK_STREAM == SOCK_STREAM);
|
||||
static_assert(LADYBIRD_SOCK_DGRAM == SOCK_DGRAM);
|
||||
static_assert(AF_LOCAL == AF_UNIX);
|
||||
#else
|
||||
# include <arpa/inet.h>
|
||||
# include <netinet/in.h>
|
||||
# include <sys/socket.h>
|
||||
# include <sys/un.h>
|
||||
#endif
|
||||
|
||||
namespace Core {
|
||||
|
||||
SocketAddress::SocketAddress() = default;
|
||||
|
||||
SocketAddress::SocketAddress(IPv4Address const& address)
|
||||
: m_type(Type::IPv4)
|
||||
, m_ip_address { address }
|
||||
{
|
||||
}
|
||||
|
||||
SocketAddress::SocketAddress(IPv6Address const& address)
|
||||
: m_type(Type::IPv6)
|
||||
, m_ip_address { address }
|
||||
{
|
||||
}
|
||||
|
||||
SocketAddress::SocketAddress(IPv4Address const& address, u16 port)
|
||||
: m_type(Type::IPv4)
|
||||
, m_ip_address { address }
|
||||
, m_port(port)
|
||||
{
|
||||
}
|
||||
|
||||
SocketAddress::SocketAddress(IPv6Address const& address, u16 port)
|
||||
: m_type(Type::IPv6)
|
||||
, m_ip_address { address }
|
||||
, m_port(port)
|
||||
{
|
||||
}
|
||||
|
||||
SocketAddress SocketAddress::local(ByteString const& address)
|
||||
{
|
||||
SocketAddress addr;
|
||||
addr.m_type = Type::Local;
|
||||
addr.m_local_address = address;
|
||||
return addr;
|
||||
}
|
||||
|
||||
ByteString SocketAddress::to_byte_string() const
|
||||
{
|
||||
switch (m_type) {
|
||||
case Type::IPv4:
|
||||
return ByteString::formatted("{}:{}", m_ip_address.get<IPv4Address>(), m_port);
|
||||
case Type::IPv6:
|
||||
return ByteString::formatted("[{}]:{}", m_ip_address.get<IPv6Address>(), m_port);
|
||||
case Type::Local:
|
||||
return m_local_address;
|
||||
default:
|
||||
return "[SocketAddress]";
|
||||
}
|
||||
}
|
||||
|
||||
Optional<sockaddr_un> SocketAddress::to_sockaddr_un() const
|
||||
{
|
||||
VERIFY(type() == Type::Local);
|
||||
sockaddr_un address;
|
||||
address.sun_family = AF_LOCAL;
|
||||
bool fits = m_local_address.copy_characters_to_buffer(address.sun_path, sizeof(address.sun_path));
|
||||
if (!fits)
|
||||
return {};
|
||||
return address;
|
||||
}
|
||||
|
||||
sockaddr_in6 SocketAddress::to_sockaddr_in6() const
|
||||
{
|
||||
VERIFY(type() == Type::IPv6);
|
||||
sockaddr_in6 address {};
|
||||
memset(&address, 0, sizeof(address));
|
||||
address.sin6_family = AF_INET6;
|
||||
address.sin6_port = htons(port());
|
||||
auto ipv6_addr = ipv6_address();
|
||||
memcpy(&address.sin6_addr, &ipv6_addr.to_in6_addr_t(), sizeof(address.sin6_addr));
|
||||
return address;
|
||||
}
|
||||
|
||||
sockaddr_in SocketAddress::to_sockaddr_in() const
|
||||
{
|
||||
VERIFY(type() == Type::IPv4);
|
||||
sockaddr_in address {};
|
||||
address.sin_family = AF_INET;
|
||||
address.sin_port = htons(port());
|
||||
address.sin_addr.s_addr = ipv4_address().to_in_addr_t();
|
||||
return address;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -10,15 +10,25 @@
|
|||
#include <AK/IPv4Address.h>
|
||||
#include <AK/IPv6Address.h>
|
||||
|
||||
#ifndef AK_OS_WINDOWS
|
||||
#if defined(AK_OS_WINDOWS)
|
||||
constexpr inline int SOCK_STREAM = 1;
|
||||
constexpr inline int SOCK_DGRAM = 2;
|
||||
|
||||
using ADDRESS_FAMILY = unsigned short;
|
||||
constexpr inline ADDRESS_FAMILY AF_LOCAL = 1;
|
||||
|
||||
# include <afunix.h>
|
||||
#else
|
||||
# include <arpa/inet.h>
|
||||
# include <netinet/in.h>
|
||||
# include <sys/socket.h>
|
||||
# include <sys/un.h>
|
||||
#else
|
||||
# include "SocketAddressWindows.h"
|
||||
#endif
|
||||
|
||||
struct sockaddr_in;
|
||||
struct sockaddr_in6;
|
||||
struct sockaddr_un;
|
||||
|
||||
namespace Core {
|
||||
|
||||
class SocketAddress {
|
||||
|
|
@ -30,40 +40,13 @@ public:
|
|||
Local
|
||||
};
|
||||
|
||||
SocketAddress() = default;
|
||||
SocketAddress(IPv4Address const& address)
|
||||
: m_type(Type::IPv4)
|
||||
, m_ip_address { address }
|
||||
{
|
||||
}
|
||||
SocketAddress();
|
||||
SocketAddress(IPv4Address const& address);
|
||||
SocketAddress(IPv6Address const& address);
|
||||
SocketAddress(IPv4Address const& address, u16 port);
|
||||
SocketAddress(IPv6Address const& address, u16 port);
|
||||
|
||||
SocketAddress(IPv6Address const& address)
|
||||
: m_type(Type::IPv6)
|
||||
, m_ip_address { address }
|
||||
{
|
||||
}
|
||||
|
||||
SocketAddress(IPv4Address const& address, u16 port)
|
||||
: m_type(Type::IPv4)
|
||||
, m_ip_address { address }
|
||||
, m_port(port)
|
||||
{
|
||||
}
|
||||
|
||||
SocketAddress(IPv6Address const& address, u16 port)
|
||||
: m_type(Type::IPv6)
|
||||
, m_ip_address { address }
|
||||
, m_port(port)
|
||||
{
|
||||
}
|
||||
|
||||
static SocketAddress local(ByteString const& address)
|
||||
{
|
||||
SocketAddress addr;
|
||||
addr.m_type = Type::Local;
|
||||
addr.m_local_address = address;
|
||||
return addr;
|
||||
}
|
||||
static SocketAddress local(ByteString const& address);
|
||||
|
||||
Type type() const { return m_type; }
|
||||
bool is_valid() const { return m_type != Type::Invalid; }
|
||||
|
|
@ -72,52 +55,11 @@ public:
|
|||
IPv6Address ipv6_address() const { return m_ip_address.get<IPv6Address>(); }
|
||||
u16 port() const { return m_port; }
|
||||
|
||||
ByteString to_byte_string() const
|
||||
{
|
||||
switch (m_type) {
|
||||
case Type::IPv4:
|
||||
return ByteString::formatted("{}:{}", m_ip_address.get<IPv4Address>(), m_port);
|
||||
case Type::IPv6:
|
||||
return ByteString::formatted("[{}]:{}", m_ip_address.get<IPv6Address>(), m_port);
|
||||
case Type::Local:
|
||||
return m_local_address;
|
||||
default:
|
||||
return "[SocketAddress]";
|
||||
}
|
||||
}
|
||||
ByteString to_byte_string() const;
|
||||
|
||||
Optional<sockaddr_un> to_sockaddr_un() const
|
||||
{
|
||||
VERIFY(type() == Type::Local);
|
||||
sockaddr_un address;
|
||||
address.sun_family = AF_LOCAL;
|
||||
bool fits = m_local_address.copy_characters_to_buffer(address.sun_path, sizeof(address.sun_path));
|
||||
if (!fits)
|
||||
return {};
|
||||
return address;
|
||||
}
|
||||
|
||||
sockaddr_in6 to_sockaddr_in6() const
|
||||
{
|
||||
VERIFY(type() == Type::IPv6);
|
||||
sockaddr_in6 address {};
|
||||
memset(&address, 0, sizeof(address));
|
||||
address.sin6_family = AF_INET6;
|
||||
address.sin6_port = htons(port());
|
||||
auto ipv6_addr = ipv6_address();
|
||||
memcpy(&address.sin6_addr, &ipv6_addr.to_in6_addr_t(), sizeof(address.sin6_addr));
|
||||
return address;
|
||||
}
|
||||
|
||||
sockaddr_in to_sockaddr_in() const
|
||||
{
|
||||
VERIFY(type() == Type::IPv4);
|
||||
sockaddr_in address {};
|
||||
address.sin_family = AF_INET;
|
||||
address.sin_port = htons(port());
|
||||
address.sin_addr.s_addr = ipv4_address().to_in_addr_t();
|
||||
return address;
|
||||
}
|
||||
Optional<sockaddr_un> to_sockaddr_un() const;
|
||||
sockaddr_in6 to_sockaddr_in6() const;
|
||||
sockaddr_in to_sockaddr_in() const;
|
||||
|
||||
bool operator==(SocketAddress const& other) const = default;
|
||||
bool operator!=(SocketAddress const& other) const = default;
|
||||
|
|
|
|||
|
|
@ -1,142 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2025, stasoid <stasoid@yahoo.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
// This header is needed because winsock2.h and windows.h are banned from including from headers and SocketAddress.h needs some struct definitions from those headers.
|
||||
// These definitions were copied from Windows SDK headers. Comments, #ifdefs and special annotations like _Field_size_bytes_ were removed. This is fair use, see Oracle v. Google.
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef int INT;
|
||||
typedef unsigned long ULONG;
|
||||
typedef unsigned short USHORT;
|
||||
typedef char CHAR;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef const CHAR* PCSTR;
|
||||
typedef USHORT ADDRESS_FAMILY;
|
||||
typedef int socklen_t;
|
||||
|
||||
#define WINAPI_FAMILY_PARTITION(x) 1
|
||||
#define FAR
|
||||
#include <inaddr.h>
|
||||
#undef WINAPI_FAMILY_PARTITION
|
||||
|
||||
#include <afunix.h>
|
||||
|
||||
#define AF_UNSPEC 0
|
||||
#define AF_LOCAL 1 // AF_UNIX
|
||||
#define AF_INET 2
|
||||
#define AF_INET6 23
|
||||
|
||||
#define SOCK_STREAM 1
|
||||
#define SOCK_DGRAM 2
|
||||
|
||||
#define INADDR_LOOPBACK 0x7f000001
|
||||
|
||||
enum IPPROTO {
|
||||
IPPROTO_TCP = 6
|
||||
};
|
||||
|
||||
#define INET_ADDRSTRLEN 22
|
||||
#define INET6_ADDRSTRLEN 65
|
||||
|
||||
struct in6_addr {
|
||||
union {
|
||||
UCHAR Byte[16];
|
||||
USHORT Word[8];
|
||||
} u;
|
||||
};
|
||||
|
||||
#define s6_addr u.Byte
|
||||
|
||||
struct SCOPE_ID {
|
||||
union {
|
||||
struct {
|
||||
ULONG Zone : 28;
|
||||
ULONG Level : 4;
|
||||
} u;
|
||||
ULONG Value;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct sockaddr_in6 {
|
||||
ADDRESS_FAMILY sin6_family;
|
||||
USHORT sin6_port;
|
||||
ULONG sin6_flowinfo;
|
||||
in6_addr sin6_addr;
|
||||
union {
|
||||
ULONG sin6_scope_id;
|
||||
SCOPE_ID sin6_scope_struct;
|
||||
};
|
||||
};
|
||||
|
||||
struct sockaddr_in {
|
||||
ADDRESS_FAMILY sin_family;
|
||||
USHORT sin_port;
|
||||
IN_ADDR sin_addr;
|
||||
CHAR sin_zero[8];
|
||||
};
|
||||
|
||||
struct sockaddr {
|
||||
ADDRESS_FAMILY sa_family;
|
||||
CHAR sa_data[14];
|
||||
};
|
||||
using SOCKADDR = sockaddr;
|
||||
using LPSOCKADDR = sockaddr*;
|
||||
|
||||
struct addrinfo {
|
||||
int ai_flags;
|
||||
int ai_family;
|
||||
int ai_socktype;
|
||||
int ai_protocol;
|
||||
size_t ai_addrlen;
|
||||
char* ai_canonname;
|
||||
sockaddr* ai_addr;
|
||||
addrinfo* ai_next;
|
||||
};
|
||||
using ADDRINFOA = addrinfo;
|
||||
using PADDRINFOA = addrinfo*;
|
||||
|
||||
struct SOCKET_ADDRESS {
|
||||
sockaddr* lpSockaddr;
|
||||
INT iSockaddrLength;
|
||||
};
|
||||
|
||||
struct SOCKET_ADDRESS_LIST {
|
||||
INT iAddressCount;
|
||||
SOCKET_ADDRESS Address[1];
|
||||
};
|
||||
using PSOCKET_ADDRESS_LIST = SOCKET_ADDRESS_LIST*;
|
||||
|
||||
struct CSADDR_INFO {
|
||||
SOCKET_ADDRESS LocalAddr;
|
||||
SOCKET_ADDRESS RemoteAddr;
|
||||
INT iSocketType;
|
||||
INT iProtocol;
|
||||
};
|
||||
using LPCSADDR_INFO = CSADDR_INFO*;
|
||||
|
||||
struct WSABUF {
|
||||
ULONG len;
|
||||
CHAR* buf;
|
||||
};
|
||||
using LPWSABUF = WSABUF*;
|
||||
|
||||
struct WSAMSG {
|
||||
LPSOCKADDR name;
|
||||
INT namelen;
|
||||
LPWSABUF lpBuffers;
|
||||
ULONG dwBufferCount;
|
||||
WSABUF Control;
|
||||
ULONG dwFlags;
|
||||
};
|
||||
using LPWSAMSG = WSAMSG*;
|
||||
|
||||
extern "C" __stdcall INT getaddrinfo(PCSTR pNodeName, PCSTR pServiceName, const ADDRINFOA* pHints, PADDRINFOA* ppResult);
|
||||
extern "C" __stdcall void freeaddrinfo(PADDRINFOA pAddrInfo);
|
||||
extern "C" __stdcall PCSTR inet_ntop(int Family, void const* pAddr, char* pStringBuf, size_t StringBufSize);
|
||||
extern "C" __stdcall USHORT htons(USHORT hostshort);
|
||||
|
||||
#define _WS2DEF_ // don't include ws2def.h
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
#include <LibCore/System.h>
|
||||
|
||||
#include <AK/Windows.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
#define MSG_DONTWAIT 0x40
|
||||
|
||||
|
|
|
|||
|
|
@ -25,9 +25,10 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <LibCore/SocketAddressWindows.h>
|
||||
#include <LibCore/SocketAddress.h>
|
||||
|
||||
#include <AK/Windows.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
namespace Core::System {
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include <sys/mman.h>
|
||||
|
||||
#include <AK/Windows.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
namespace Core::System {
|
||||
|
||||
|
|
|
|||
|
|
@ -71,6 +71,12 @@ ErrorOr<ByteBuffer> UDPServer::receive(size_t size, sockaddr_in& in)
|
|||
return buf;
|
||||
}
|
||||
|
||||
ErrorOr<ByteBuffer> UDPServer::receive(size_t size)
|
||||
{
|
||||
struct sockaddr_in saddr;
|
||||
return receive(size, saddr);
|
||||
}
|
||||
|
||||
Optional<IPv4Address> UDPServer::local_address() const
|
||||
{
|
||||
if (m_fd == -1)
|
||||
|
|
|
|||
|
|
@ -25,11 +25,7 @@ public:
|
|||
|
||||
bool bind(IPv4Address const& address, u16 port);
|
||||
ErrorOr<ByteBuffer> receive(size_t size, sockaddr_in& from);
|
||||
ErrorOr<ByteBuffer> receive(size_t size)
|
||||
{
|
||||
struct sockaddr_in saddr;
|
||||
return receive(size, saddr);
|
||||
}
|
||||
ErrorOr<ByteBuffer> receive(size_t size);
|
||||
|
||||
ErrorOr<size_t> send(ReadonlyBytes, sockaddr_in const& to);
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,12 @@ ErrorOr<ByteBuffer> UDPServer::receive(size_t size, sockaddr_in& in)
|
|||
return buf;
|
||||
}
|
||||
|
||||
ErrorOr<ByteBuffer> UDPServer::receive(size_t size)
|
||||
{
|
||||
struct sockaddr_in saddr;
|
||||
return receive(size, saddr);
|
||||
}
|
||||
|
||||
ErrorOr<size_t> UDPServer::send(ReadonlyBytes buffer, sockaddr_in const& to)
|
||||
{
|
||||
socklen_t to_len = sizeof(to);
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
#include <LibThreading/BackgroundAction.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <AK/Windows.h>
|
||||
|
||||
// File tests
|
||||
|
||||
TEST_CASE(file_open)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue