Commit graph

66 commits

Author SHA1 Message Date
Andreas Kling
ceec1a7d38 AK: Make Vector use size_t for its size and capacity 2020-02-25 14:52:35 +01:00
Andreas Kling
48f7c28a5c Kernel: Replace "current" with Thread::current and Process::current
Suggested by Sergey. The currently running Thread and Process are now
Thread::current and Process::current respectively. :^)
2020-02-17 15:04:27 +01:00
Andreas Kling
a356e48150 Kernel: Move all code into the Kernel namespace 2020-02-16 01:27:42 +01:00
Andreas Kling
3891e6d739 IPv4: Sockets should say can_read() after reading is shut down
This allows clients to get their EOF after shutting down reading.
2020-02-08 16:04:31 +01:00
Andreas Kling
228a1e9099 IPv4: Basic implementation of TCP socket shutdown
We can now participate in the TCP connection closing handshake. :^)
This implementation is definitely not complete and needs to handle a
bunch of other cases. But it's a huge improvement over not being able
to close connections at all.

Note that we hold on to pending-close sockets indefinitely, until they
are moved into the Closed state. This should also have a timeout but
that's still a FIXME. :^)

Fixes #428.
2020-02-08 16:04:27 +01:00
Andreas Kling
48f13f2a81 IPv4: Split IPv4Socket::recvfrom() into packet/byte buffered functions
This code was really hard to follow since it handles two separate modes
of buffering the data.
2020-02-08 13:09:37 +01:00
Andreas Kling
0c12d9a618 IPv4: Drop incoming packets on sockets that are shut down for reading 2020-02-08 00:58:11 +01:00
Andreas Kling
d04fcccc90 Kernel: Truncate addresses stored by getsockname() and getpeername()
If there's not enough space in the output buffer for the whole sockaddr
we now simply truncate the address instead of returning EINVAL.

This patch also makes getpeername() actually return the peer address
rather than the local address.. :^)
2020-02-07 23:43:32 +01:00
Andreas Kling
137a45dff2 Kernel: read()/write() should respect timeouts when used on a sockets
Move timeout management to the ReadBlocker and WriteBlocker classes.
Also get rid of the specialized ReceiveBlocker since it no longer does
anything that ReadBlocker can't do.
2020-01-26 17:54:23 +01:00
Andreas Kling
388d40d755 IPv4: Fix bitrot in IPv4Socket debug logging 2020-01-26 14:42:44 +01:00
Andreas Kling
22d563b1aa IPv4: Don't hold IPv4Socket lock when blocking on byte-buffered receive 2020-01-26 10:26:27 +01:00
Andreas Kling
03d73cbaae Kernel: Allow Socket subclasses to fail construction
For example, socket(AF_INET) should only succeed for valid SOCK_TYPEs.
2020-01-23 21:33:15 +01:00
Andreas Kling
f4f958f99f 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 TTY'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 :^)
2020-01-20 16:08:49 +01:00
Andreas Kling
94ca55cefd Meta: Add license header to source files
As suggested by Joshua, this commit adds the 2-clause BSD license as a
comment block to the top of every source file.

For the first pass, I've just added myself for simplicity. I encourage
everyone to add themselves as copyright holders of any file they've
added or modified in some significant way. If I've added myself in
error somewhere, feel free to replace it with the appropriate copyright
holder instead.

Going forward, all new source files should include a license header.
2020-01-18 09:45:54 +01:00
Andreas Kling
35c84504cd IPv4: Require "inet" promise for ioctl() on an IPv4Socket 2020-01-12 13:28:07 +01:00
Andreas Kling
1434f30f92 Kernel: Remove SmapDisabler in bind() 2020-01-11 12:07:45 +01:00
Andreas Kling
8c5cd97b45 Kernel: Fix kernel null deref on process crash during join_thread()
The join_thread() syscall is not supposed to be interruptible by
signals, but it was. And since the process death mechanism piggybacked
on signal interrupts, it was possible to interrupt a pthread_join() by
killing the process that was doing it, leading to confusing due to some
assumptions being made by Thread::finalize() for threads that have a
pending joiner.

This patch fixes the issue by making "interrupted by death" a distinct
block result separate from "interrupted by signal". Then we handle that
state in join_thread() and tidy things up so that thread finalization
doesn't get confused by the pending joiner being gone.

Test: Tests/Kernel/null-deref-crash-during-pthread_join.cpp
2020-01-10 19:23:45 +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
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
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
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
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
3f2c1a2e3d Kernel: Add SIOCGIFHWADDR ioctl to get the MAC address of an adapter 2019-10-02 18:20:11 +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
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
Conrad Pankoff
a2b61e30c5 Kernel: Put some network log messages behind debug flags 2019-09-08 12:34:20 +02:00
Conrad Pankoff
e8a10848b5 Kernel: Make sure IPv4Socket is marked as listening in listen() 2019-09-08 12:34:20 +02:00
Conrad Pankoff
749719b4d0 Kernel: Fix debug messages in IPv4Socket 2019-09-08 12:34:20 +02:00
Andreas Kling
c82627aae2 Kernel: Don't allow non-superusers to bind TCP/UDP ports < 1024 2019-09-02 18:49:54 +02:00
Conrad Pankoff
b15a7c435f Kernel: Implement is_zero for RoutingDecision 2019-08-29 06:25:06 +02:00
Conrad Pankoff
6d1418aa7a Kernel: Add simple ARP routing layer
This replaces the previous placeholder routing layer with a real one!
It's still very primitive, doesn't deal with things like timeouts very
well, and will probably need several more iterations to support more
normal networking things.

I haven't confirmed that this works with anything other than the QEMU
user networking layer, but I suspect that's what nearly everybody is
using at this point, so that's the important target to keep working.
2019-08-29 06:25:06 +02:00
Sergey Bugaev
dadf6337ef Kernel: Customize absolute_path() for more file types 2019-08-11 16:30:43 +02:00
Sergey Bugaev
43ce6c5474 Kernel: Move socket role tracking to the Socket class itself
This is more logical and allows us to solve the problem of
non-blocking TCP sockets getting stuck in SocketRole::None.

The only complication is that a single LocalSocket may be shared
between two file descriptions (on the connect and accept sides),
and should have two different roles depending from which side
you look at it. To deal with it, Socket::role() is made a
virtual method that accepts a file description, and LocalSocket
internally tracks which FileDescription is the which one and
returns a correct role.
2019-08-11 16:30:43 +02:00
Conrad Pankoff
bd6d2c0819 Kernel: Use a more detailed state machine for socket setup 2019-08-10 09:07:11 +02:00
Conrad Pankoff
5c0f1f9834 Kernel: Fix get{sock,peer}name port endianness 2019-08-10 08:49:31 +02:00
Conrad Pankoff
5c66c67f32 Kernel: Improve some network-related log messages 2019-08-09 07:09:26 +02:00
Conrad Pankoff
4fcbbd24f7 Kernel: Support binding to INADDR_ANY (all IPs) 2019-08-09 07:09:26 +02:00
Conrad Pankoff
54ceabd48d Kernel: Use WeakPtr<NetworkAdapter> instead of NetworkAdapter* in net code 2019-08-09 07:09:26 +02:00
Conrad Pankoff
73c998dbfc Kernel: Refactor TCP/IP stack
This has several significant changes to the networking stack.

* Significant refactoring of the TCP state machine. Right now it's
  probably more fragile than it used to be, but handles quite a lot
  more of the handshake process.
* `TCPSocket` holds a `NetworkAdapter*`, assigned during `connect()` or
  `bind()`, whichever comes first.
* `listen()` is now virtual in `Socket` and intended to be implemented
  in its child classes
* `listen()` no longer works without `bind()` - this is a bit of a
  regression, but listening sockets didn't work at all before, so it's
  not possible to observe the regression.
* A file is exposed at `/proc/net_tcp`, which is a JSON document listing
  the current TCP sockets with a bit of metadata.
* There's an `ETHERNET_VERY_DEBUG` flag for dumping packet's content out
  to `kprintf`. It is, indeed, _very debug_.
2019-08-06 16:21:17 +02:00
Andreas Kling
605975adb5 Kernel: Make KBuffer a value-type wrapper around a KBufferImpl
A KBuffer always contains a valid KBufferImpl. If you need a "null"
state buffer, use Optional<KBuffer>.

This makes KBuffer very easy to work with and pass around, just like
ByteBuffer before it.
2019-08-05 11:07:45 +02:00
Andreas Kling
52cfe9ebae IPv4: Remove an unnecessary copy of each outgoing IPv4 payload
There's no need for send_ipv4() to take a ByteBuffer&&, the data is
immediately cooked into a packet and transmitted. Instead, just pass
it the address+length of whatever buffer we've been using locally.

The more we can reduce the pressure on kmalloc the better. :^)
2019-08-05 10:43:22 +02:00
Andreas Kling
6347e3aa51 Net: Let Socket have read/write wrappers around sendto/recvfrom
The situations in IPv4Socket and LocalSocket were mirrors of each other
where one had implemented read/write as wrappers and the other had
sendto/recvfrom as wrappers.

Instead of this silliness, move read and write up to the Socket base.
Then mark them final, so subclasses have no choice but to implement
sendto and recvfrom.
2019-08-05 10:03:19 +02:00
Andreas Kling
72798519cb IPv4: Use KBuffer instead of ByteBuffer for socket receive queues
This drastically reduces the pressure on the kernel heap when receiving
data from IPv4 sockets.
2019-08-04 21:09:38 +02:00
Andreas Kling
c06993b7cf Kernel: Remove more unused members of IPv4Socket.
I thought I had included these in the previous commit, but it turns out
I hadn't, duh.
2019-08-04 20:39:59 +02:00
Andreas Kling
675aa550a4 Kernel: Put IPv4 and TCP related debug spam behind flags
...and turn those flags off for now, to make it possible to write some
networking code without being spammed to death.
2019-08-04 10:04:06 +02:00
Robin Burchell
833d444cd8 Thread: Return a result from block() indicating why the block terminated
And use this to return EINTR in various places; some of which we were
not handling properly before.

This might expose a few bugs in userspace, but should be more compatible
with other POSIX systems, and is certainly a little cleaner.
2019-07-20 12:15:24 +02:00