Commit graph

85 commits

Author SHA1 Message Date
Liav A
7c1f645e27 Kernel/Net: Iron out the locking mechanism across the subsystem
There is a big mix of LockRefPtrs all over the Networking subsystem, as
well as lots of room for improvements with our locking patterns, which
this commit will not pursue, but will give a good start for such work.

To deal with this situation, we change the following things:
- Creating instances of NetworkAdapter should always yield a non-locking
  NonnullRefPtr. Acquiring an instance from the NetworkingManagement
  should give a simple RefPtr,as giving LockRefPtr does not really
  protect from concurrency problems in such case.
- Since NetworkingManagement works with normal RefPtrs we should
  protect all instances of RefPtr<NetworkAdapter> with SpinlockProtected
  to ensure references are gone unexpectedly.
- Protect the so_error class member with a proper spinlock. This happens
  to be important because the clear_so_error() method lacked any proper
  locking measures. It also helps preventing a possible TOCTOU when we
  might do a more fine-grained locking in the Socket code, so this could
  be definitely a start for this.
- Change unnecessary LockRefPtr<PacketWithTimestamp> in the structure
  of OutgoingPacket to a simple RefPtr<PacketWithTimestamp> as the whole
  list should be MutexProtected.
2023-04-14 19:27:56 +02:00
Andreas Kling
03cc45e5a2 Kernel: Use RefPtr instead of LockRefPtr for File and subclasses
This was mostly straightforward, as all the storage locations are
guarded by some related mutex.

The use of old-school associated mutexes instead of MutexProtected
is unfortunate, but the process to modernize such code is ongoing.
2023-03-10 13:15:44 +01:00
Andreas Kling
11eee67b85 Kernel: Make self-contained locking smart pointers their own classes
Until now, our kernel has reimplemented a number of AK classes to
provide automatic internal locking:

- RefPtr
- NonnullRefPtr
- WeakPtr
- Weakable

This patch renames the Kernel classes so that they can coexist with
the original AK classes:

- RefPtr => LockRefPtr
- NonnullRefPtr => NonnullLockRefPtr
- WeakPtr => LockWeakPtr
- Weakable => LockWeakable

The goal here is to eventually get rid of the Lock* classes in favor of
using external locking.
2022-08-20 17:20:43 +02:00
Idan Horowitz
364f6a9bf0 Kernel: Remove the Socket::{protocol,}connect ShouldBlock argument
This argument is always set to description.is_blocking(), but
description is also given as a separate argument, so there's no point
to piping it through separately.
2022-07-21 16:39:22 +02:00
sin-ack
3f3f45580a Everywhere: Add sv suffix to strings relying on StringView(char const*)
Each of these strings would previously rely on StringView's char const*
constructor overload, which would call __builtin_strlen on the string.
Since we now have operator ""sv, we can replace these with much simpler
versions. This opens the door to being able to remove
StringView(char const*).

No functional changes.
2022-07-12 23:11:35 +02:00
Idan Horowitz
4a270c93ed Kernel: Accept NNRP<Socket> instead of RP<Socket> in release_for_accept
This value is always non-null, so let's make it explicit.
2022-04-09 23:46:02 +02:00
Idan Horowitz
086969277e Everywhere: Run clang-format 2022-04-01 21:24:45 +01:00
Idan Horowitz
aabc8d348b Kernel: Add TCPSocket::try_for_each() for fallible iteration
This API will allow users to short circuit iteration and properly
propagate errors.
2022-02-27 20:37:57 +01:00
Idan Horowitz
664ca58746 Kernel: Use u64 instead of size_t for File::can_write offset
This ensures offsets will not be truncated on large files on i686.
2022-01-25 22:41:17 +02:00
Andreas Kling
01b3666894 Kernel: Lock TCPSocket lookup table across destruction
Use the same trick as SlavePTY and override unref() to provide safe
removal from the sockets_by_tuple table when destroying a TCPSocket.

This should fix the TCPSocket::from_tuple() flake seen on CI.
2022-01-06 22:30:40 +01:00
sin-ack
3da0c072f4 Kernel: Return the correct result for FIONREAD on datagram sockets
Before this commit, we only checked the receive buffer on the socket,
which is unused on datagram streams. Now we return the actual size of
the datagram without the protocol headers, which required the protocol
to tell us what the size of the payload is.
2021-12-16 22:21:35 +03:30
Andreas Kling
79fa9765ca Kernel: Replace KResult and KResultOr<T> with Error and ErrorOr<T>
We now use AK::Error and AK::ErrorOr<T> in both kernel and userspace!
This was a slightly tedious refactoring that took a long time, so it's
not unlikely that some bugs crept in.

Nevertheless, it does pass basic functionality testing, and it's just
real nice to finally see the same pattern in all contexts. :^)
2021-11-08 01:10:53 +01:00
Brian Gianforcaro
5f1c98e576 Kernel: Use operator ""sv in all class_name() implementations
Previously there was a mix of returning plain strings and returning
explicit string views using `operator ""sv`. This change switches them
all to standardized on `operator ""sv` as it avoids a call to strlen.
2021-10-03 13:36:10 +02:00
Ali Mohammad Pur
5a0cdb15b0 AK+Everywhere: Reduce the number of template parameters of IntrusiveList
This makes the user-facing type only take the node member pointer, and
lets the compiler figure out the other needed types from that.
2021-09-10 18:05:46 +03:00
Andreas Kling
c69035c630 Kernel: TCPSocket always has a scratch buffer
Let's encode this in the constructor signature.
2021-09-07 15:11:49 +02:00
Andreas Kling
ededd6aac6 Kernel: Make TCPSocket client construction use KResultOr and TRY()
We don't really have anywhere to propagate the error in NetworkTask at
the moment, since it runs in its own kernel thread and has no direct
userspace caller.
2021-09-07 14:44:29 +02:00
Andreas Kling
4a9c18afb9 Kernel: Rename FileDescription => OpenFileDescription
Dr. POSIX really calls these "open file description", not just
"file description", so let's call them exactly that. :^)
2021-09-07 13:53:14 +02:00
sin-ack
566c5d1e99 AK+Kernel: Move KResult.h to Kernel/API for userspace access
This commit moves the KResult and KResultOr objects to Kernel/API to
signify that they may now be freely used by userspace code at points
where a syscall-related error result is to be expected. It also exposes
KResult and KResultOr to the global namespace to make it nicer to use
for userspace code.
2021-09-05 12:54:48 +02:00
Andreas Kling
648c768d81 Kernel: Tidy up TCPSocket creation a bit
- Rename create() => try_create()
- Use adopt_nonnull_ref_or_enomem()
2021-09-04 23:11:04 +02:00
Andreas Kling
c2fc33becd Kernel: Rename ProtectedValue<T> => MutexProtected<T>
Let's make it obvious what we're protecting it with.
2021-08-22 03:34:09 +02:00
Andreas Kling
6a20733fcd Kernel: Convert TCP retransmit queue from HashTable to IntrusiveList 2021-08-15 16:53:03 +02:00
Andreas Kling
0cb6c3c831 Kernel/TCP: Port TCP retransmit queue to ProtectedValue
I had to switch to exclusive locking since ProtectedValue rightly
doesn't allow you to mutate protected data with only a shared lock.
2021-08-07 18:49:27 +02:00
Jean-Baptiste Boric
9216c72bfe Kernel: Migrate TCP socket tables locking to ProtectedValue
Note: TCPSocket::create_client() has a dubious locking process where
the sockets by tuple table is first shared lock to check if the socket
exists and bail out if it does, then unlocks, then exclusively locks to
add the tuple. There could be a race condition where two client
creation requests for the same tuple happen at the same time and both
cleared the shared lock check. When in doubt, lock exclusively the
whole time.
2021-08-07 11:48:00 +02:00
Jean-Baptiste Boric
583abc27d8 Kernel: Migrate IPv4 socket table locking to ProtectedValue 2021-08-07 11:48:00 +02:00
Andreas Kling
af46f2214c Kernel: Make a bunch of "char const* to_string()" return StringView 2021-08-06 00:37:47 +02:00
Brian Gianforcaro
c1a0e379e6 Kernel: Handle OOM when allocating IPv4Socket optional scratch buffer 2021-08-03 18:54:23 +02:00
Brian Gianforcaro
ca94a83337 Kernel: Handle OOM from DoubleBuffer usage in IPv4Socket
The IPv4Socket requires a DoubleBuffer for storage of any data it
received on the socket. However it was previously using the default
constructor which can not observe allocation failure. Address this by
plumbing the receive buffer through the various derived classes.
2021-08-03 18:54:23 +02:00
brapru
9c3e6f3f63 Kernel: Send RST/ACK if no socket is available
Previously there was no way for Serenity to send a packet without an
established socket connection, and there was no way to appropriately
respond to a SYN packet on a non-listening port. This patch will respond
to any non-established socket attempts with the appropraite RST/ACK,
letting the client know to close the connection.
2021-08-02 02:45:56 +02:00
Andreas Kling
cee9528168 Kernel: Rename Lock to Mutex
Let's be explicit about what kind of lock this is meant to be.
2021-07-17 21:10:32 +02:00
Andreas Kling
c9f6786e8b Kernel: Make various T::class_name() and similar return StringView
Instead of returning char const*, we can also give you a StringView.
2021-07-11 01:46:59 +02:00
stelar7
01e5af487f Kernel: Dont try to register ephemeral TCP ports twice 2021-06-01 23:32:27 +04:30
Gunnar Beutner
49dd4e5193 Kernel: Block when writing to TCP sockets when the send window is full
Previously we'd just dump those packets into the network adapter's
send queue and hope for the best. Instead we should wait until the peer
has sent TCP ACK packets.

Ideally this would parse the TCP window size option from the SYN or
SYN|ACK packet, but for now we just assume the window size is 64 kB.
2021-05-26 23:09:28 +02:00
Gunnar Beutner
b436dd138b Kernel: Avoid allocations when sending IP packets
Previously we'd allocate buffers when sending packets. This patch
avoids these allocations by using the NetworkAdapter's packet queue.

At the same time this also avoids copying partially constructed
packets in order to prepend Ethernet and/or IPv4 headers. It also
properly truncates UDP and raw IP packets.
2021-05-26 23:09:28 +02:00
Gunnar Beutner
c6299d1e5d Kernel: Don't try to send TCP packets larger than the MSS
Previously TCPSocket::send_tcp_packet() would try to send TCP packets
which matched whatever size the userspace program specified. We'd try to
break those packets up into smaller fragments, however a much better
approach is to limit TCP packets to the maximum segment size and
avoid fragmentation altogether.
2021-05-25 22:20:37 +02:00
Gunnar Beutner
006f11f23d Kernel: Avoid allocations when handling network packets 2021-05-16 17:49:42 +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
Brian Gianforcaro
879eec6aa8 Kernel: Remove dead TCPSocket::from_endpoints method 2021-05-14 11:32:50 +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
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
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
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
Brian Gianforcaro
1682f0b760 Everything: Move to SPDX license identifiers in all files.
SPDX License Identifiers are a more compact / standardized
way of representing file license information.

See: https://spdx.dev/resources/use/#identifiers

This was done with the `ambr` search and replace tool.

 ambr --no-parent-ignore --key-from-file --rep-from-file key.txt rep.txt *
2021-04-22 11:22:27 +02:00
Ben Wiederhake
5c15ca7b84 Kernel: Make sockets use AK::Time 2021-03-02 08:36:08 +01:00
Andreas Kling
9984201634 Kernel: Use KResult a bit more in the IPv4 networking code 2021-01-31 12:13:16 +01:00
Andreas Kling
8cc81c2953 Kernel/Net: Make IPv4Socket::protocol_receive() take a ReadonlyBytes
The overrides of this function don't need to know how the original
packet was stored, so let's just give them a ReadonlyBytes view of
the raw packet data.
2020-12-18 19:22:26 +01:00
Tom
75f61fe3d9 AK: Make RefPtr, NonnullRefPtr, WeakPtr thread safe
This makes most operations thread safe, especially so that they
can safely be used in the Kernel. This includes obtaining a strong
reference from a weak reference, which now requires an explicit
call to WeakPtr::strong_ref(). Another major change is that
Weakable::make_weak_ref() may require the explicit target type.
Previously we used reinterpret_cast in WeakPtr, assuming that it
can be properly converted. But WeakPtr does not necessarily have
the knowledge to be able to do this. Instead, we now ask the class
itself to deliver a WeakPtr to the type that we want.

Also, WeakLink is no longer specific to a target type. The reason
for this is that we want to be able to safely convert e.g. WeakPtr<T>
to WeakPtr<U>, and before this we just reinterpret_cast the internal
WeakLink<T> to WeakLink<U>, which is a bold assumption that it would
actually produce the correct code. Instead, WeakLink now operates
on just a raw pointer and we only make those constructors/operators
available if we can verify that it can be safely cast.

In order to guarantee thread safety, we now use the least significant
bit in the pointer for locking purposes. This also means that only
properly aligned pointers can be used.
2020-11-10 19:11:52 +01:00
Tom
c8d9f1b9c9 Kernel: Make copy_to/from_user safe and remove unnecessary checks
Since the CPU already does almost all necessary validation steps
for us, we don't really need to attempt to do this. Doing it
ourselves doesn't really work very reliably, because we'd have to
account for other processors modifying virtual memory, and we'd
have to account for e.g. pages not being able to be allocated
due to insufficient resources.

So change the copy_to/from_user (and associated helper functions)
to use the new safe_memcpy, which will return whether it succeeded
or not. The only manual validation step needed (which the CPU
can't perform for us) is making sure the pointers provided by user
mode aren't pointing to kernel mappings.

To make it easier to read/write from/to either kernel or user mode
data add the UserOrKernelBuffer helper class, which will internally
either use copy_from/to_user or directly memcpy, or pass the data
through directly using a temporary buffer on the stack.

Last but not least we need to keep syscall params trivial as we
need to copy them from/to user mode using copy_from/to_user.
2020-09-13 21:19:15 +02:00
Andreas Kling
48a0b76a77 Kernel: Make File weakable
This will be useful for some things. This also removes the need for
TCPSocket to be special about this.
2020-09-06 18:46:46 +02:00