Commit graph

431 commits

Author SHA1 Message Date
Gunnar Beutner
093818de62 Kernel: Avoid allocations when receiving network packets
This avoids two allocations when receiving network packets. One for
inserting a PacketWithTimestamp into m_packet_queue and another one
when inserting buffers into the list of unused packet buffers.

With this fixed the only allocations in NetworkTask happen when
initially allocating the PacketWithTimestamp structs and when switching
contexts.
2021-05-18 16:06:27 +02:00
Gunnar Beutner
006f11f23d Kernel: Avoid allocations when handling network packets 2021-05-16 17:49:42 +02:00
Brian Gianforcaro
f255993349 Kernel: Log unexpected TCP packet flags in NetworkTask handle_tcp()
Occasionally we'll see messages in the serial console like:

    handle_tcp: unexpected flags in FinWait1 state

In these cases it would be nice to know what flags we are receiving that
we aren't expecting.
2021-05-15 09:46:50 +02:00
Gunnar Beutner
c22296505c Kernel: Merge do_retransmit_packets() into retransmit_packets() 2021-05-14 16:50:00 +02:00
Gunnar Beutner
08aa3a91e3 Kernel: Try to retransmit lost TCP packets
Previously we didn't retransmit lost TCP packets which would cause
connections to hang if packets were lost. Also we now time out
TCP connections after a number of retransmission attempts.
2021-05-14 16:50:00 +02:00
Gunnar Beutner
9daec809b7 Kernel: Wake up NetworkTask every 500 milliseconds
This wakes up NetworkTask every 500 milliseconds so that it can send
pending delayed TCP ACKs and isn't forced to send all of them early
when it goes to sleep like it did before.
2021-05-14 16:50:00 +02:00
Gunnar Beutner
990b2d0989 Kernel: Don't use delayed ACKs when establishing the connection
When establishing the connection we should send ACKs right away so
as to not delay the connection process. This didn't previously
matter because we'd flush all delayed ACKs when NetworkTask waits
for incoming packets.
2021-05-14 16:50:00 +02:00
Brian Gianforcaro
4728f2af80 Kernel: Avoid unnecessary time under lock in TCPSocket::create
Avoid holding the sockets_by_tuple lock while allocating the TCPSocket.
While checking if the list contains the item we can also hold the lock
in shared mode, as we are only reading the hash table.

In addition the call to from_tuple appears to be superfluous, as we
created the socket, so we should be able to just return it directly.
This avoids the recursive lock acquisition, as well as the unnecessary
hash table lookups.
2021-05-14 11:32:50 +02:00
Brian Gianforcaro
879eec6aa8 Kernel: Remove dead TCPSocket::from_endpoints method 2021-05-14 11:32:50 +02:00
Brian Gianforcaro
2e34714ba1 Kernel: Make UDPSocket::create() API OOM safe 2021-05-13 16:21:53 +02:00
Brian Gianforcaro
858fff979a Kernel: Make IPv4Socket::create API for SOCK_RAW OOM safe 2021-05-13 16:21:53 +02:00
Brian Gianforcaro
46ce7adf7b Kernel: Make TCPSocket::create API OOM safe
Note that the changes to IPv4Socket::create are unfortunately needed as
the return type of TCPSocket::create and IPv4Socket::create don't match.

 - KResultOr<NonnullRefPtr<TcpSocket>>>
   vs
 - KResultOr<NonnullRefPtr<Socket>>>

To handle this we are forced to manually decompose the KResultOr<T> and
return the value() and error() separately.
2021-05-13 16:21:53 +02:00
Brian Gianforcaro
9375f3dc09 Kernel: Make LocalSocket factory APIs OOM safe 2021-05-13 16:21:53 +02:00
Gunnar Beutner
1bb20a255f Kernel: Avoid unnecessary allocations in NetworkAdapter::for_each
This avoids allocations for initializing the Function<T>
for the NetworkAdapter::for_each callback argument.

Applying this patch decreases CPU utilization for NetworkTask
from 40% to 28% when receiving TCP packets at a rate of 100Mbit/s.
2021-05-13 08:27:42 +02:00
Gunnar Beutner
76deda802d Kernel: Avoid allocating and then freeing packet buffers
We already have another limit for the total number of packet buffers
allowed (max_packet_buffers). This second limit caused us to
repeatedly allocate and then free buffers.
2021-05-13 08:27:42 +02:00
Gunnar Beutner
790d68ac5e Kernel: Route packets destined for us through the loopback adapter
Without this patch we'd send packets through the physical adapter
and they'd incorrectly end up on the network.
2021-05-12 16:31:29 +02:00
Gunnar Beutner
2b6aa571d1 Kernel: Outbound packets should use the source address from the socket
Previously we'd use the adapter's address as the source address
when sending packets. Instead we should use the socket's bound local
address.
2021-05-12 16:31:29 +02:00
Gunnar Beutner
532db9f768 Kernel: Treat 0.0.0.0 as a loopback address
This matches what other operating systems like Linux do:

$ ip route get 0.0.0.0
local 0.0.0.0 dev lo src 127.0.0.1 uid 1000
    cache <local>

$ ssh 0.0.0.0
gunnar@0.0.0.0's password:

$ ss -na | grep :22 | grep ESTAB
tcp   ESTAB      0      0   127.0.0.1:43118   127.0.0.1:22
tcp   ESTAB      0      0   127.0.0.1:22      127.0.0.1:43118
2021-05-12 13:47:07 +02:00
Gunnar Beutner
af59f64bc0 Kernel: Coalesce TCP ACKs
Previously we'd send a TCP ACK for each TCP packet we received. This
changes NetworkTask so that we send fewer TCP ACKs.
2021-05-12 13:47:07 +02:00
Gunnar Beutner
ffc6b714b0 Kernel: Trigger TCP fast retransmission when we encounter lost packets
When we receive a TCP packet with a sequence number that is not what
we expected we have lost one or more packets. We can signal this to
the sender by sending a TCP ACK with the previous ack number so that
they can resend the missing TCP fragments.
2021-05-12 13:47:07 +02:00
Gunnar Beutner
7272127927 Kernel: Don't process TCP packets out of order
Previously we'd process TCP packets in whatever order we received
them in. In the case where packets arrived out of order we'd end
up passing garbage to the userspace process.

This was most evident for TLS connections:

courage:~ $ git clone https://github.com/SerenityOS/serenity
Cloning into 'serenity'...
remote: Enumerating objects: 178826, done.
remote: Counting objects: 100% (1880/1880), done.
remote: Compressing objects: 100% (907/907), done.
error: RPC failed; curl 56 OpenSSL SSL_read: error:1408F119:SSL
routines:SSL3_GET_RECORD:decryption failed or bad record mac, errno 0
error: 1918 bytes of body are still expected
fetch-pack: unexpected disconnect while reading sideband packet
fatal: early EOF
fatal: fetch-pack: invalid index-pack output
2021-05-12 13:47:07 +02:00
Gunnar Beutner
aff4d22de9 Kernel: Set MSS option for outbound TCP SYN packets
When the MSS option header is missing the default maximum segment
size is 536 which results in lots of very small TCP packets that
NetworkTask has to handle.

This adds the MSS option header to outbound TCP SYN packets and
sets it to an appropriate value depending on the interface's MTU.

Note that we do not currently do path MTU discovery so this could
cause problems when hops don't fragment packets properly.
2021-05-12 13:47:07 +02:00
Gunnar Beutner
5feeb62843 Kernel: Avoid allocating KBuffers for TCP packets
This avoids allocating a KBuffer for each incoming TCP packet.
2021-05-12 13:47:07 +02:00
Gunnar Beutner
c0800ab898 Kernel: Increase the default TCP window size
This increases the default TCP window size to a more reasonable
value of 64k. This allows TCP peers to send us more packets before
waiting for corresponding ACKs.
2021-05-12 13:47:07 +02:00
Gunnar Beutner
b83a110174 Kernel: Increase IPv4 buffer size to 256kB
This increases the buffer size for connection-oriented sockets
to 256kB. In combination with the other patches in this series
I was able to receive TCP packets at a rate of about 120Mbps.
2021-05-12 13:47:07 +02:00
Gunnar Beutner
c160c6b035 Kernel: Use correct destination MAC address for multicast packets
Previously we'd incorrectly use the default gateway's MAC address.
Instead we must use destination MAC addresses that are derived from
the multicast IPv4 address.

With this patch applied I can query mDNS on a real network.
2021-05-10 17:26:17 +02:00
Gunnar Beutner
f999d5a91a Kernel: Limit the number of in-flight packet buffers
This fixes an OOM when hitting the VM with lots of UDP packets.

fixes #6907
2021-05-07 16:00:07 +02:00
Gunnar Beutner
9213d1e926 Kernel: Truncate UDP packets on read
When reading UDP packets from userspace with recvmsg()/recv() we
would hit a VERIFY() if the supplied buffer is smaller than the
received UDP packet. Instead we should just return truncated data
to the caller.

This can be reproduced with:

    $ dd if=/dev/zero bs=1k count=1 | nc -u 192.168.3.190 68
2021-05-06 08:49:35 +02:00
Sergey Bugaev
78459b92d5 Kernel: Implement IP multicast support
An IP socket can now join a multicast group by using the
IP_ADD_MEMBERSHIP sockopt, which will cause it to start receiving
packets sent to the multicast address, even though this address does
not belong to this host.
2021-05-05 21:16:17 +02:00
Gunnar Beutner
6cf59b6ae9 Everywhere: Turn #if *_DEBUG into dbgln_if/if constexpr 2021-05-01 21:25:06 +02:00
Gunnar Beutner
cf7df418ed Kernel: Make sure we read all packets
The previous patch already helped with this, however my idea of only
reading a few packets didn't work and we'd still sometimes end up not
receiving any more packets from the E1000 interface.

With this patch applied my NIC seems to receive packets just fine, at
least for now.
2021-05-01 20:08:08 +02:00
Brian Gianforcaro
f0568bff9b Kernel: Harden Socket Vector usage against OOM 2021-05-01 09:10:30 +02:00
Brian Gianforcaro
e8d6d478c4 Kernel: Harden LocalSocket Vector usage against OOM. 2021-05-01 09:10:30 +02:00
Andreas Kling
51f88cb00d Kernel/IPv4: Unbreak raw socket (port allocation failing is OK)
Raw sockets don't need a local port, so we shouldn't fail operations
if allocation yields an ENOPROTOOPT.

I'm not in love with the factoring here, just patching up the bug.
2021-05-01 00:03:33 +02:00
Gunnar Beutner
e0ac611a08 Kernel: Tear down connections when we receive an RST packet 2021-04-30 23:11:56 +02:00
Gunnar Beutner
c03cbf83ab Kernel: Record MAC addresses for incoming IPv4 packets
This way we don't have to do ARP just to send packets back to
an address which just sent us a packet.
2021-04-30 23:11:56 +02:00
Gunnar Beutner
fb2ad94195 Kernel: Remove socket from the listener's accept list when it is closed
Without this patch we end up with sockets in the listener's accept
queue with state 'closed' when doing stealth SYN scans:

Client -> Server: SYN for port 22
Server -> Client: SYN/ACK
Client -> Server: RST (i.e. don't complete the TCP handshake)
2021-04-30 23:11:56 +02:00
Gunnar Beutner
866e577f1d Kernel: Don't put closed/listener sockets into the closing_sockets list 2021-04-30 23:11:56 +02:00
Gunnar Beutner
d8f92bdf96 Kernel: Avoid deadlock when trying to send packets from the NetworkTask
fixes #6758
2021-04-30 23:11:56 +02:00
Andreas Kling
a5f385f052 Kernel: Fix bogus error codes from raw socket protocol_{send,receive}
Since these return KResultOr, we should not negate the error code.
2021-04-30 15:27:41 +02:00
Andreas Kling
71a10eb8e7 Kernel/IPv4: Propagate errors from local port allocation
Remove hacks and assumptions and make the EADDRINUSE propagate all
the way from the point of failure to the syscall layer.
2021-04-30 15:27:41 +02:00
Justin
e6401d65bd Kernel: Add MSG_PEEK support for the IPv4Socket
This commit will add MSG_PEEK support, which allows a package to be
seen without taking it from the buffer, so that a subsequent recv()
without the MSG_PEEK flag can pick it up.
2021-04-29 08:09:53 +02:00
Linus Groh
649d2faeab Everywhere: Use "the SerenityOS developers." in copyright headers
We had some inconsistencies before:

- Sometimes "The", sometimes "the"
- Sometimes trailing ".", sometimes no trailing "."

I picked the most common one (lowecase "the", trailing ".") and applied
it to all copyright headers.

By using the exact same string everywhere we can ensure nothing gets
missed during a global search (and replace), and that these
inconsistencies are not spread any further (as copyright headers are
commonly copied to new files).
2021-04-29 00:59:26 +02:00
Gunnar Beutner
aa792062cb Kernel+LibC: Implement the socketpair() syscall 2021-04-28 14:19:45 +02:00
Gunnar Beutner
bf703ee553 Kernel: Move PCI vendor and device IDs into Kernel/PCI/IDs.h 2021-04-27 11:36:24 +02:00
Gunnar Beutner
eaf8fc90e7 Kernel: Avoid resetting the IRQ mask for E1000 on each interrupt 2021-04-27 11:36:24 +02:00
Gunnar Beutner
897f001076 Kernel: Add logging for E1000 RX buffer overrun 2021-04-27 11:36:24 +02:00
Gunnar Beutner
fa434305a7 Kernel: Use macros instead of hard-coded magic values 2021-04-27 11:36:24 +02:00
Gunnar Beutner
addddb4880 Kernel: Make sure the E1000 network adapter keeps receiving packets
Previously the E1000 network adapter would stop receiving further
packets when an RX buffer overrun occurred. This was the case
when connecting the adapter to a real network where enough broadcast
traffic caused the buffer to be full before the kernel had a chance
to clear the RX buffer.
2021-04-27 11:36:24 +02:00
Gunnar Beutner
4e6a26cbd2 Kernel: Silence a few more network dbgln()s 2021-04-27 08:59:02 +02:00