Commit graph

170 commits

Author SHA1 Message Date
Andreas Kling
5646a95161 Kernel: Make Socket::absolute_path() pure virtual
This is overridden by all subclasses, so can just be pure virtual.
2020-01-07 10:24:45 +01:00
erf
53733be5fd Kernel: Make LocalSocket pre-bind GID be gid_t (#1012) 2020-01-04 10:05:01 +01:00
Andreas Kling
d84299c7be Kernel: Allow fchmod() and fchown() on pre-bind() local sockets
In order to ensure a specific owner and mode when the local socket
filesystem endpoint is instantiated, we need to be able to call
fchmod() and fchown() on a socket fd between socket() and bind().

This is because until we call bind(), there is no filesystem inode
for the socket yet.
2020-01-03 20:14:56 +01:00
Andreas Kling
9026598999 Kernel: Add a more expressive API for getting random bytes
We now have these API's in <Kernel/Random.h>:

    - get_fast_random_bytes(u8* buffer, size_t buffer_size)
    - get_good_random_bytes(u8* buffer, size_t buffer_size)
    - get_fast_random<T>()
    - get_good_random<T>()

Internally they both use x86 RDRAND if available, otherwise they fall
back to the same LCG we had in RandomDevice all along.

The main purpose of this patch is to give kernel code a way to better
express its needs for random data.

Randomness is something that will require a lot more work, but this is
hopefully a step in the right direction.
2020-01-03 12:43:07 +01:00
Liav A
e5ffa960d7 Kernel: Create support for PCI ECAM
The new PCI subsystem is initialized during runtime.
PCI::Initializer is supposed to be called during early boot, to
perform a few tests, and initialize the proper configuration space
access mechanism. Kernel boot parameters can be specified by a user to
determine what tests will occur, to aid debugging on problematic
machines.
After that, PCI::Initializer should be dismissed.

PCI::IOAccess is a class that is derived from PCI::Access
class and implements PCI configuration space access mechanism via x86
IO ports.
PCI::MMIOAccess is a class that is derived from PCI::Access
and implements PCI configurtaion space access mechanism via memory
access.

The new PCI subsystem also supports determination of IO/MMIO space
needed by a device by checking a given BAR.
In addition, Every device or component that use the PCI subsystem has
changed to match the last changes.
2020-01-02 00:50:09 +01:00
Conrad Pankoff
bbb536ebed Kernel: Fix code locked behind NETWORK_TASK_DEBUG 2019-12-28 02:03:49 +01:00
Conrad Pankoff
5ca7ae4585 Kernel: Route all loopback traffic through the loopback adapter 2019-12-28 02:03:38 +01:00
Conrad Pankoff
876323fd7a Kernel: Move incoming packet buffer off the NetworkTask stack 2019-12-28 00:24:43 +01:00
Andreas Kling
8874ad7946 Net: Shrink the NetworkTask packet buffer
This thing was overflowing the NetworkTask's kernel stack. Oops!
2019-12-22 14:54:37 +01:00
Andreas Kling
8de5a0be41 TCP: Log packet metadata when receiving a TCP packet with no socket 2019-12-14 13:03:26 +01:00
Andreas Kling
9d67a6ba34 E1000: Disable interrupts while getting ready to wait on TX completion 2019-12-14 13:02:40 +01:00
Andreas Kling
8b2280c374 Kernel: Allow buffering up to 128 KB in an IPv4Socket before refusing 2019-12-14 12:17:37 +01:00
Andreas Kling
ac215ca601 Net: Try to reuse incoming packet buffers to avoid allocation churn
The majority of the time in NetworkTask was being spent in allocating
and deallocating KBuffers for each incoming packet.

We'll now keep up to 100 buffers around and reuse them for new packets
if the next incoming packet fits in an old buffer. This is pretty
naively implemented but definitely cuts down on time spent here.
2019-12-14 11:07:37 +01:00
Andreas Kling
39246fb621 E1000: Use a WaitQueue to sleep while waiting for a transmit IRQ 2019-12-14 10:47:17 +01:00
Andreas Kling
77cb5594b0 IPv4: Only buffer payload bytes for SOCK_STREAM sockets
Since stream sockets don't actually need to deliver packets-at-a-time
data in recvfrom(), they can just buffer the payload bytes instead.
This avoids keeping one KBuffer per incoming packet in the receive
queue, which was a big performance issue in ProtocolServer.

This code is definitely not perfect and is something we should keep
improving over time.
2019-12-14 09:43:31 +01:00
Andreas Kling
7248c34e35 AK: SinglyLinkedList::size_slow() should return size_t 2019-12-09 17:51:21 +01:00
Andreas Kling
6f4c380d95 AK: Use size_t for the length of strings
Using int was a mistake. This patch changes String, StringImpl,
StringView and StringBuilder to use size_t instead of int for lengths.
Obviously a lot of code needs to change as a result of this.
2019-12-09 17:51:21 +01:00
Andreas Kling
23e802518d Kernel: Add getsockopt(SO_PEERCRED) for local sockets
This sockopt gives you a struct with the PID, UID and GID of a socket's
peer process.
2019-12-06 18:38:36 +01:00
Andreas Kling
5a45376180 Kernel+SystemMonitor: Log amounts of I/O per thread
This patch adds these I/O counters to each thread:

- (Inode) file read bytes
- (Inode) file write bytes
- Unix socket read bytes
- Unix socket write bytes
- IPv4 socket read bytes
- IPv4 socket write bytes

These are then exposed in /proc/all and seen in SystemMonitor.
2019-12-01 17:40:27 +01:00
Andreas Kling
a18aa8fd5f Kernel: Use a WaitQueue in NetworkTask 2019-12-01 16:47:49 +01:00
Andreas Kling
75ed262fe5 Kernel+ifconfig: Add an MTU value to NetworkAdapter
This defaults to 1500 for all adapters, but LoopbackAdapter increases
it to 65536 on construction.

If an IPv4 packet is larger than the MTU, we'll need to break it into
smaller fragments before transmitting it. This part is a FIXME. :^)
2019-11-28 14:14:26 +01:00
Andreas Kling
61f611bf3c IPv4: Protect the list of unacked TCP packets with a lock
Otherwise things get racy and crashy.
2019-11-23 21:44:47 +01:00
Andreas Kling
0e9e70ca4f IPv4: Disconnected non-blocking sockets were not signalling EOF
After a socket has disconnected, we shouldn't return -EAGAIN. Instead
we should allow userspace to read/recvfrom the socket until its packet
queue has been exhausted.

At that point, we now return 0, signalling EOF.

It might be even better to start returning -ENOTCONN after signalling
EOF once. I'm not sure how that should work, needs looking into.
2019-11-18 17:37:54 +01:00
Andreas Kling
06a80bcf69 Kernel+SystemMonitor: Publish can_read/write state for open files
The can_read() and can_write() states for file descriptions are now
published in /proc, allowing SystemMonitor to display it.
2019-11-09 22:42:19 +01:00
Andreas Kling
1b2ef8582c Kernel: Make File's can_read/can_write take a const FileDescription&
Asking a File if we could possibly read or write it will never mutate
the asking FileDescription&, so it should be const.
2019-11-04 14:03:14 +01:00
Andreas Kling
ecd23ce1a1 IPv4: Non-blocking IPv4 sockets should return -EAGAIN in recvfrom()
...if there are no packets in the receive queue.
2019-11-04 13:42:25 +01:00
Andreas Kling
e08991319a Net: Put a bunch of socket debug logging behind FOO_DEBUG
Also remove an unused Socket::listen() implementation.
2019-10-18 16:50:23 +02:00
Andreas Kling
ec65b8db2e Revert "Kernel: Make DoubleBuffer use a KBuffer instead of kmalloc()ing"
This reverts commit 1cca5142af.

This appears to be causing intermittent triple-faults and I don't know
why yet, so I'll just revert it to keep the tree in decent shape.
2019-10-18 15:58:06 +02:00
Andreas Kling
1cca5142af Kernel: Make DoubleBuffer use a KBuffer instead of kmalloc()ing
Background: DoubleBuffer is a handy buffer class in the kernel that
allows you to keep writing to it from the "outside" while the "inside"
reads from it. It's used for things like LocalSocket and PTY's.
Internally, it has a read buffer and a write buffer, but the two will
swap places when the read buffer is exhausted (by reading from it.)

Before this patch, it was internally implemented as two Vector<u8>
that we would swap between when the reader side had exhausted the data
in the read buffer. Now instead we preallocate a large KBuffer (64KB*2)
on DoubleBuffer construction and use that throughout its lifetime.

This removes all the kmalloc heap traffic caused by DoubleBuffers :^)
2019-10-18 14:55:04 +02:00
Andreas Kling
340b524c0d Kernel: Minor cleanup in TCPSocket::send_tcp_packet() 2019-10-17 23:39:31 +02:00
Andreas Kling
9bb0374d7d Kernel: Delay moving accepted sockets to SetupState::Completed a bit
Make sure we don't move accepted sockets to the Completed setup state
until we've actually constructed a FileDescription for them.

This is important, since this state transition will trigger connect()
to unblock on the client side, and the client may try writing to the
socket right away.

This makes DNS lookups way more reliable since we don't just fail to
write() right after connect()ing to LookupServer sometimes. :^)
2019-10-08 21:44:50 +02:00
Andreas Kling
3aa27b5b0e Kernel: Don't put LocalSocket in SetupState::Completed in bind()
This was causing connect() to unblock immediately for local sockets,
since that's exactly what ConnectBlocker checks for.

Instead, just move to SetupState::Completed when it's accept()ed.
2019-10-08 21:32:04 +02:00
Andreas Kling
3f2c1a2e3d Kernel: Add SIOCGIFHWADDR ioctl to get the MAC address of an adapter 2019-10-02 18:20:11 +02:00
Andreas Kling
8f45a259fc ByteBuffer: Remove pointer() in favor of data()
We had two ways to get the data inside a ByteBuffer. That was silly.
2019-09-30 08:57:01 +02:00
Andreas Kling
2482fc3538 IPv4: Implement socket ioctls SIOCGIFADDR and SIOCSIFADDR
This allows userspace programs to get and set (superuser-only) the IPv4
address of a network adapter. :^)
2019-09-23 19:06:03 +02:00
Andreas Kling
65409e8f04 LocalSocket: Teach recvfrom() how to block if needed, and simplify it
If we can't already read when we enter recvfrom() on a LocalSocket,
we'll now block the current thread until we can.

Also added a buffer_for(FileDescription&) helper so that the client
and server can share some of the code. :^)
2019-09-22 21:30:30 +02:00
Andreas Kling
8cfb859368 IPv4: Support overriding the default TTL (64)
Made getsockopt() and setsockopt() virtual so we can handle them in the
various Socket subclasses. The subclasses map kinda nicely to "levels".

This will allow us to implement things like "traceroute", although..
I spent some time trying to do that, but then hit a wall when it turned
out that the user-mode networking in QEMU doesn't preserve TTL in the
ICMP packets passing through.
2019-09-19 21:42:59 +02:00
Andreas Kling
1c692e87a6 Kernel: Move kmalloc() into a Kernel/Heap/ directory 2019-09-16 09:01:44 +02:00
Andreas Kling
54caeb1f1a RTL8139: Fix bogus (but harmless) TX buffer index in send_raw()
This was getting fixed up by the loop that chooses the next TX buffer
anyway, but let's do this correctly.

Fixes #522.
2019-09-09 08:51:08 +02:00
Conrad Pankoff
c983e96664 Kernel: Use timeval_sub for TCP retransmissions and lower timer to 500ms 2019-09-08 12:34:20 +02:00
Conrad Pankoff
3f1c3a341b Kernel: Handle listening socket disappearing during incoming handshake 2019-09-08 12:34:20 +02:00
Conrad Pankoff
feb6d1afe0 Kernel: Use a WeakPtr instead of a RefPtr for TCP socket originator 2019-09-08 12:34:20 +02:00
Conrad Pankoff
a2b61e30c5 Kernel: Put some network log messages behind debug flags 2019-09-08 12:34:20 +02:00
Conrad Pankoff
328d52b323 Kernel: Send ACK/FIN in response to FIN packets on active connections
This is to work around our lack of a shutdown() implementation.
2019-09-08 12:34:20 +02:00
Conrad Pankoff
117d8db2a2 Kernel: Implement outgoing TCP retransmission and better ACK handling
This approach is a bit naiive - whenever we send a packet out, we
check to see if there are any other packets we should try to send.
This works well enough for a busy connection but not very well for a
quiet one. Ideally we would check for not-acked packets on some kind
of timer, and use the length of this not-acked list as feedback to
throttle the writes coming from userspace.
2019-09-08 12:34:20 +02:00
Conrad Pankoff
b8e3c7ef01 Kernel: Remember all ARP replies, even ones we didn't request
This allows us to take advantage of unsolicited ARP replies, such as
those that are emitted by many systems after their network interfaces
are enabled, or after their DHCP client sets their IP.

This also makes us a bit more vulnerable to ARP flooding, but we need
some kind of eviction strategy anyway, so we can deal with that later.
2019-09-08 12:34:20 +02:00
Conrad Pankoff
b45cfae7f4 Kernel: Don't mark incoming sockets as connected in NetworkTask
An incoming socket should only be considered connected after a
program has received it from accept(). Before that point, it's only
"half" open, and it might not ever actually be served to a program.

Socket::accept is where m_connected is correctly set.
2019-09-08 12:34:20 +02:00
Conrad Pankoff
72f728b0d6 Kernel: Hold socket back from accept() until it's fully set up 2019-09-08 12:34:20 +02:00
Conrad Pankoff
d53c9d4416 Kernel: Use RefPtr instead of SocketHandle for TCPSocket clients
Using a SocketHandle takes a lock on the socket, which we don't want
to do.
2019-09-08 12:34:20 +02:00
Conrad Pankoff
cfcb53fe77 Kernel: Don't set sequence manually; send_tcp_packet will do it 2019-09-08 12:34:20 +02:00