diff --git a/Kernel/Net/IPv4Socket.cpp b/Kernel/Net/IPv4Socket.cpp index f33e90224c..650a8bd616 100644 --- a/Kernel/Net/IPv4Socket.cpp +++ b/Kernel/Net/IPv4Socket.cpp @@ -95,9 +95,6 @@ KResult IPv4Socket::listen(int backlog) if (rc < 0) return KResult(-EADDRINUSE); - if (m_local_address.to_u32() == 0) - return KResult(-EADDRINUSE); - set_backlog(backlog); kprintf("IPv4Socket{%p} listening with backlog=%d\n", this, backlog); diff --git a/Kernel/Net/IPv4Socket.h b/Kernel/Net/IPv4Socket.h index 81667b99c9..9a2bf1f97a 100644 --- a/Kernel/Net/IPv4Socket.h +++ b/Kernel/Net/IPv4Socket.h @@ -39,6 +39,7 @@ public: const IPv4Address& local_address() const { return m_local_address; } u16 local_port() const { return m_local_port; } void set_local_port(u16 port) { m_local_port = port; } + bool has_specific_local_address() { return m_local_address.to_u32() != 0; } const IPv4Address& peer_address() const { return m_peer_address; } u16 peer_port() const { return m_peer_port; } diff --git a/Kernel/Net/TCPSocket.cpp b/Kernel/Net/TCPSocket.cpp index c55d064863..cd9f0f3f0f 100644 --- a/Kernel/Net/TCPSocket.cpp +++ b/Kernel/Net/TCPSocket.cpp @@ -36,6 +36,11 @@ TCPSocketHandle TCPSocket::from_tuple(const IPv4SocketTuple& tuple) if (address_match.has_value()) return { move(address_match.value()) }; + auto wildcard_tuple = IPv4SocketTuple(IPv4Address(), tuple.local_port(), IPv4Address(), 0); + auto wildcard_match = sockets_by_tuple().resource().get(wildcard_tuple); + if (wildcard_match.has_value()) + return { move(wildcard_match.value()) }; + return {}; } @@ -206,7 +211,7 @@ NetworkOrdered TCPSocket::compute_tcp_checksum(const IPv4Address& source, c KResult TCPSocket::protocol_bind() { - if (!m_adapter) { + if (has_specific_local_address() && !m_adapter) { m_adapter = NetworkAdapter::from_ipv4_address(local_address()); if (!m_adapter) return KResult(-EADDRNOTAVAIL); @@ -230,11 +235,17 @@ KResult TCPSocket::protocol_listen() KResult TCPSocket::protocol_connect(FileDescription& description, ShouldBlock should_block) { if (!m_adapter) { - m_adapter = adapter_for_route_to(peer_address()); - if (!m_adapter) - return KResult(-EHOSTUNREACH); + if (has_specific_local_address()) { + m_adapter = NetworkAdapter::from_ipv4_address(local_address()); + if (!m_adapter) + return KResult(-EADDRNOTAVAIL); + } else { + m_adapter = adapter_for_route_to(peer_address()); + if (!m_adapter) + return KResult(-EHOSTUNREACH); - set_local_address(m_adapter->ipv4_address()); + set_local_address(m_adapter->ipv4_address()); + } } allocate_local_port_if_needed();