Commit Graph

12 Commits

Author SHA1 Message Date
ser 6213ba7a06
Pooled control message storage. (#2422) 2023-05-31 06:06:23 -07:00
ser 8193940b9a
Buffer pool for message headers and addresses. (#2378)
* Pool buffers for messages and addresses.

* Revert changes related to controlMessageStorage

* Cosmetic fix.

---------

Co-authored-by: Cory Benfield <lukasa@apple.com>
2023-03-10 16:06:02 +00:00
George Barnett d1fa3e29bf
Add support for UDP_GRO (#2385)
Motivation:

Support was added for UDP_SEGMENT in #2372 which allows for large UDP
datagrams to be written to a socket by letting the kernel or NIC segment
the data across multiple datagrams. This reduces traversals across the
network stack which can lead to performance improvements. UDP_GRO is the
receive-side counterpart allowing the kernel/NIC to aggregate datagrams
and reduce network stack traversals.

Modifications:

- Add a function in CNIOLinux to check whether UDP_GRO is supported
- Add the relevant socket and channel options
- Add tests

Result:

- UDP_GRO can be enabled where supported and applications may receive
  large buffers.
2023-03-06 07:12:09 -08:00
George Barnett 19b878f461
Add support for UDP_SEGMENT (#2372)
Motivation:

On Linux, the UDP_SEGMENT socket option allows for large buffers to be
written to the kernel and segmented by the kernel (or in some cases the
NIC) into smaller datagrams. This can substantially decrease the number
of syscalls.

This can be set on a per message basis on a per socket basis. This
change adds per socket configuration.

Modifications:

- Add a CNIOLinux function to check whether UDP_SEGMENT is supported on
  that particular Linux.
- Add a helper to `System` to check whether UDP_SEGMENT is supported on
  the current platform.
- On Linux only:
  - add the udp socket option level
  - add the udp_segment socket option
- Add the `DatagramSegmentSize` channel option.
- Get/Set the option in `DatagramChannel`

Results:

UDP GSO is supported on Linux.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2023-02-27 13:18:58 +00:00
George Barnett 4dfae01cc6
Add a pooled recv buffer allocator (#2362)
Motivation:

Channels can read `ChannelOptions.maxMessagesPerRead` times from a
socket in each read cycle. They typically re-use the same buffer for
each read and rely on it CoWing if necessary. If we read more than once
in a cycle then we may CoW the buffer. Instead of reusing one buffer we
can reuse a pool of buffers limited by `maxMessagesPerRead` and cycle
through each, reducing the chance of CoWing the buffers.

Modifications:

- Extend `RecvByteBufferAllocator` to provide the size of the next
  buffer with a default implementation returning `nil`.
- Add an recv buffer pool which lazily grows up to a fixed size and
  attempts to reuse buffers where possible if doing so avoids CoWing.

Results:

Fewer allocations
2023-02-20 17:00:19 +00:00
ser 1e7ad9a0db
Pool buffers for ivecs and storage refs in the event loop. (#2358)
* Pool buffers for ivecs and storage refs in the event loop.

* Introduce PoolElement for poolable objects and add some bounds checks for the pooled buffers.

* Some polishes.

* Fix build failure with Swift 5.5/5.6

* User raw pointers instead of typed.
2023-02-07 13:48:26 +00:00
Ahmad Alhashemi 91e5b3b609
Allow writing and reading empty datagrams (#2341)
Motivation:

Empty UDP datagrams could be used to have a meaning.
Empty datagrams were being silently dropped on write.
Receiving an empty diagram causes an assertion failure (possible DDoS).

Modifications:

Remove early exit when writing empty datagrams and non-empty assertion when reading them.

Result:

We can now write and read empty datagrams.
2023-01-09 02:45:15 -08:00
David Nadoba 0b4edd8329
Add `NIOBSDSocket.ProtocolSubtype` (#2317)
* RawSocket prototype

* Conform `ProtocolSubtype` to `Hashable`

* Add public `NIOIPProtocol` type

Make `ProtocolSubtype` internal

* Subset of IANA protocols with an RFC

* Add `CustomStringConvertible` to `NIOIPProtocol`

* Add `init(_ rawValue: Int)`

* Rename `NIOBSDSocket.ProtocolSubtype.ip` to `.default`

* Add `NIOBSDSocket.ProtocolSubtype.mptcp`

and remove `NIOBSDSocket.mptcpProtocolSubtype`
2022-11-22 06:01:52 -08:00
Cory Benfield 558e4f2fb8
MPTCP support on Linux (#2308)
Motivation

MPTCP provides multipath capability for TCP connections. This
allows TCP connections to consume multiple independent network
paths, providing devices with a number of capabilities to
improve throughput, latency, or reliability.

MPTCP is not totally transparent, and requires servers to support
the functionality as well as clients. To that end, we should expose
some MPTCP capability.

Importantly, MPTCP uses a number of new socket flags and options.
To enable us to support this when it is available but gracefully fail
when it is not, we've hardcoded a number of Linux kernel constants
instead of relying on libc to expose them. This is safe to do on Linux
because its syscall layer is ABI stable.

Modifications

- Add ClientBootstrap and ServerBootstrap flags for MPTCP
- Plumb MPTCP through the stack
- Add new socket options for MPTCP

Result

MPTCP is supported on Linux
2022-11-09 11:02:45 +00:00
Saleem Abdulrasool 59cd8ff038
NIOPosix: import additional interfaces from WinSDK (#2189)
Import additional interfaces from WinSDK to enable additional paths to
build for Windows.
2022-06-14 10:56:44 +01:00
Si Beaumont 9bf5075241
Add initial support for connected datagram sockets (#2084)
* socket: Make destinationPtr param optional in sendmsg(...)

Signed-off-by: Si Beaumont <beaumont@apple.com>

* pdwm: Fixup documentation: scalar writes use sendmsg, not sendto

Signed-off-by: Si Beaumont <beaumont@apple.com>

* pdwm: Make sockaddr pointer param optional in scalarWriteOperation

Signed-off-by: Si Beaumont <beaumont@apple.com>

* pdwm: Add isConnected property to PendingDatagramWritesState

Signed-off-by: Si Beaumont <beaumont@apple.com>

* pdwm: If socket is connected use NULL msg_name in sendmsg(2)

Signed-off-by: Si Beaumont <beaumont@apple.com>

* BaseSocketChannel: Support connect after bind

Signed-off-by: Si Beaumont <beaumont@apple.com>

* DatagramChannel: Implement connectSocket(to:)

Signed-off-by: Si Beaumont <beaumont@apple.com>

* bootstrap: Rename bind0(makeChannel:registerAndBind:) to withNewChannel(makeChannel:bringup:)

Signed-off-by: Si Beaumont <beaumont@apple.com>

* bootstrap: Add set of DatagramBootstrap.connect(...) APIs

Signed-off-by: Si Beaumont <beaumont@apple.com>

* test: Remove DatagramChannelTests.testConnectionFails

Signed-off-by: Si Beaumont <beaumont@apple.com>

* test: Add ConnectedDatagramChannelTests, inheriting from DatagramChannelTests

Signed-off-by: Si Beaumont <beaumont@apple.com>

* NIOUDPEchoClient: Use connected-mode UDP

Signed-off-by: Si Beaumont <beaumont@apple.com>

* soundness: Update copyright notice

Signed-off-by: Si Beaumont <beaumont@apple.com>

* fixup: cleanup bootstrap APIs

Signed-off-by: Si Beaumont <beaumont@apple.com>

* pdwm: Check address of pending write if connected and add test

Signed-off-by: Si Beaumont <beaumont@apple.com>

* Revert "pdwm: Check address of pending write if connected and add test"

This reverts commit a4ee0756d5.

* channel: Fail buffered writes on connect and validate writes when connected

Signed-off-by: Si Beaumont <beaumont@apple.com>

* Run soundness.sh to get linux tests generated

Signed-off-by: Si Beaumont <beaumont@apple.com>

* NIOUDPEchoClient: Connect socket to remote only if --connect is used

Signed-off-by: Si Beaumont <beaumont@apple.com>

* socket: Support ByteBuffer (without AddressedEnvelope) for DatagramChannel

Signed-off-by: Si Beaumont <beaumont@apple.com>

* test: Simplify some test code

Signed-off-by: Si Beaumont <beaumont@apple.com>

* pdwm: Factor out common, private add(_ pendingWrite:)

Signed-off-by: Si Beaumont <beaumont@apple.com>

* channel: Support AddressedEnvelope on connected socket for control messages

Signed-off-by: Si Beaumont <beaumont@apple.com>

* channel: Defer to common unwrapData for error handling

Signed-off-by: Si Beaumont <beaumont@apple.com>

* channel: Throw more specific (new) errors, instead of IOError

Signed-off-by: Si Beaumont <beaumont@apple.com>

* SocketChannelLifecycleManager: Add supportsReconnect boolean property, used in DatagramChannel

Signed-off-by: Si Beaumont <beaumont@apple.com>
2022-05-31 13:21:41 +01:00
Cory Benfield b05c6f2206
Move NIO to NIOPosix, make NIO a shell. (#1936)
Motivation:

The remaining NIO code really conceptually belongs in a module called
NIOPosix, and NIOCore should really be called NIO. We can't really do
that last step, but we can prepare by pushing the bulk of the remaining
code into a module called NIOPosix.

Modifications:

- Move NIO to NIOPosix
- Make NIO an umbrella module.

Result:

NIOPosix exists.
2021-08-16 16:50:40 +01:00