From 780d2a08c488e5e8a61f7508f7cc31f35bdf8b26 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 4 May 2019 03:27:50 +0200 Subject: IPv4: Save the source address/port together with incoming packet payloads. We need the address/port to fill in the out-params in recvfrom(). It should now be more or less possible to create a UDP server. :^) --- Kernel/Net/IPv4Socket.cpp | 20 +++++++++++++++----- Kernel/Net/IPv4Socket.h | 10 ++++++++-- Kernel/Net/NetworkTask.cpp | 8 ++++---- Kernel/Net/TCPSocket.cpp | 4 ---- Kernel/Net/UDPSocket.cpp | 4 ---- 5 files changed, 27 insertions(+), 19 deletions(-) (limited to 'Kernel/Net') diff --git a/Kernel/Net/IPv4Socket.cpp b/Kernel/Net/IPv4Socket.cpp index f590ad8b51..697e24f1d9 100644 --- a/Kernel/Net/IPv4Socket.cpp +++ b/Kernel/Net/IPv4Socket.cpp @@ -178,11 +178,16 @@ ssize_t IPv4Socket::recvfrom(FileDescriptor& descriptor, void* buffer, size_t bu kprintf("recvfrom: type=%d, source_port=%u\n", type(), source_port()); #endif + IPv4Address peer_address; + word peer_port = 0; ByteBuffer packet_buffer; { LOCKER(lock()); if (!m_receive_queue.is_empty()) { - packet_buffer = m_receive_queue.take_first(); + auto packet = m_receive_queue.take_first(); + packet_buffer = packet.data; + peer_address = packet.source_address; + peer_port = packet.source_port; m_can_read = !m_receive_queue.is_empty(); #ifdef IPV4_SOCKET_DEBUG kprintf("IPv4Socket(%p): recvfrom without blocking %d bytes, packets in queue: %d\n", this, packet_buffer.size(), m_receive_queue.size_slow()); @@ -205,7 +210,10 @@ ssize_t IPv4Socket::recvfrom(FileDescriptor& descriptor, void* buffer, size_t bu } ASSERT(m_can_read); ASSERT(!m_receive_queue.is_empty()); - packet_buffer = m_receive_queue.take_first(); + auto packet = m_receive_queue.take_first(); + packet_buffer = packet.data; + peer_address = packet.source_address; + peer_port = packet.source_port; m_can_read = !m_receive_queue.is_empty(); #ifdef IPV4_SOCKET_DEBUG kprintf("IPv4Socket(%p): recvfrom with blocking %d bytes, packets in queue: %d\n", this, packet_buffer.size(), m_receive_queue.size_slow()); @@ -215,8 +223,10 @@ ssize_t IPv4Socket::recvfrom(FileDescriptor& descriptor, void* buffer, size_t bu auto& ipv4_packet = *(const IPv4Packet*)(packet_buffer.pointer()); if (addr) { + dbgprintf("Incoming packet is from: %s:%u\n", peer_address.to_string().characters(), peer_port); auto& ia = *(sockaddr_in*)addr; - memcpy(&ia.sin_addr, &m_destination_address, sizeof(IPv4Address)); + memcpy(&ia.sin_addr, &peer_address, sizeof(IPv4Address)); + ia.sin_port = htons(peer_port); ia.sin_family = AF_INET; ASSERT(addr_length); *addr_length = sizeof(sockaddr_in); @@ -231,11 +241,11 @@ ssize_t IPv4Socket::recvfrom(FileDescriptor& descriptor, void* buffer, size_t bu return protocol_receive(packet_buffer, buffer, buffer_length, flags, addr, addr_length); } -void IPv4Socket::did_receive(ByteBuffer&& packet) +void IPv4Socket::did_receive(const IPv4Address& source_address, word source_port, ByteBuffer&& packet) { LOCKER(lock()); auto packet_size = packet.size(); - m_receive_queue.append(move(packet)); + m_receive_queue.append({ source_address, source_port, move(packet) }); m_can_read = true; m_bytes_received += packet_size; #ifdef IPV4_SOCKET_DEBUG diff --git a/Kernel/Net/IPv4Socket.h b/Kernel/Net/IPv4Socket.h index f011182621..47ec8804f3 100644 --- a/Kernel/Net/IPv4Socket.h +++ b/Kernel/Net/IPv4Socket.h @@ -32,7 +32,7 @@ public: virtual ssize_t sendto(FileDescriptor&, const void*, size_t, int, const sockaddr*, socklen_t) override; virtual ssize_t recvfrom(FileDescriptor&, void*, size_t, int flags, sockaddr*, socklen_t*) override; - void did_receive(ByteBuffer&&); + void did_receive(const IPv4Address& source_address, word source_port, ByteBuffer&&); const IPv4Address& source_address() const; word source_port() const { return m_source_port; } @@ -67,7 +67,13 @@ private: DoubleBuffer m_for_client; DoubleBuffer m_for_server; - SinglyLinkedList m_receive_queue; + struct ReceivedPacket { + IPv4Address source_address; + word source_port; + ByteBuffer data; + }; + + SinglyLinkedList m_receive_queue; word m_source_port { 0 }; word m_destination_port { 0 }; diff --git a/Kernel/Net/NetworkTask.cpp b/Kernel/Net/NetworkTask.cpp index 4a238d47d2..680dfc33c8 100644 --- a/Kernel/Net/NetworkTask.cpp +++ b/Kernel/Net/NetworkTask.cpp @@ -218,7 +218,7 @@ void handle_icmp(const EthernetFrameHeader& eth, int frame_size) LOCKER(socket->lock()); if (socket->protocol() != (unsigned)IPv4Protocol::ICMP) continue; - socket->did_receive(ByteBuffer::copy(&ipv4_packet, sizeof(IPv4Packet) + ipv4_packet.payload_size())); + socket->did_receive(ipv4_packet.source(), 0, ByteBuffer::copy(&ipv4_packet, sizeof(IPv4Packet) + ipv4_packet.payload_size())); } } @@ -277,7 +277,7 @@ void handle_udp(const EthernetFrameHeader& eth, int frame_size) ASSERT(socket->type() == SOCK_DGRAM); ASSERT(socket->source_port() == udp_packet.destination_port()); - socket->did_receive(ByteBuffer::copy(&ipv4_packet, sizeof(IPv4Packet) + ipv4_packet.payload_size())); + socket->did_receive(ipv4_packet.source(), udp_packet.source_port(), ByteBuffer::copy(&ipv4_packet, sizeof(IPv4Packet) + ipv4_packet.payload_size())); } void handle_tcp(const EthernetFrameHeader& eth, int frame_size) @@ -337,7 +337,7 @@ void handle_tcp(const EthernetFrameHeader& eth, int frame_size) kprintf("handle_tcp: Got FIN, payload_size=%u\n", payload_size); if (payload_size != 0) - socket->did_receive(ByteBuffer::copy(&ipv4_packet, sizeof(IPv4Packet) + ipv4_packet.payload_size())); + socket->did_receive(ipv4_packet.source(), tcp_packet.source_port(), ByteBuffer::copy(&ipv4_packet, sizeof(IPv4Packet) + ipv4_packet.payload_size())); socket->set_ack_number(tcp_packet.sequence_number() + payload_size + 1); socket->send_tcp_packet(TCPFlags::FIN | TCPFlags::ACK); @@ -357,5 +357,5 @@ void handle_tcp(const EthernetFrameHeader& eth, int frame_size) socket->send_tcp_packet(TCPFlags::ACK); if (payload_size != 0) - socket->did_receive(ByteBuffer::copy(&ipv4_packet, sizeof(IPv4Packet) + ipv4_packet.payload_size())); + socket->did_receive(ipv4_packet.source(), tcp_packet.source_port(), ByteBuffer::copy(&ipv4_packet, sizeof(IPv4Packet) + ipv4_packet.payload_size())); } diff --git a/Kernel/Net/TCPSocket.cpp b/Kernel/Net/TCPSocket.cpp index 00d30e1476..6f73144791 100644 --- a/Kernel/Net/TCPSocket.cpp +++ b/Kernel/Net/TCPSocket.cpp @@ -54,10 +54,6 @@ int TCPSocket::protocol_receive(const ByteBuffer& packet_buffer, void* buffer, s size_t payload_size = packet_buffer.size() - sizeof(IPv4Packet) - tcp_packet.header_size(); kprintf("payload_size %u, will it fit in %u?\n", payload_size, buffer_size); ASSERT(buffer_size >= payload_size); - if (addr) { - auto& ia = *(sockaddr_in*)addr; - ia.sin_port = htons(tcp_packet.destination_port()); - } memcpy(buffer, tcp_packet.payload(), payload_size); return payload_size; } diff --git a/Kernel/Net/UDPSocket.cpp b/Kernel/Net/UDPSocket.cpp index e631054630..982bdd8606 100644 --- a/Kernel/Net/UDPSocket.cpp +++ b/Kernel/Net/UDPSocket.cpp @@ -53,10 +53,6 @@ int UDPSocket::protocol_receive(const ByteBuffer& packet_buffer, void* buffer, s auto& udp_packet = *static_cast(ipv4_packet.payload()); ASSERT(udp_packet.length() >= sizeof(UDPPacket)); // FIXME: This should be rejected earlier. ASSERT(buffer_size >= (udp_packet.length() - sizeof(UDPPacket))); - if (addr) { - auto& ia = *(sockaddr_in*)addr; - ia.sin_port = htons(udp_packet.destination_port()); - } memcpy(buffer, udp_packet.payload(), udp_packet.length() - sizeof(UDPPacket)); return udp_packet.length() - sizeof(UDPPacket); } -- cgit v1.2.3