Motivation:
The recently added UDP GRO tests fail on some older Linux Kernel
versions. We believe that UDP GRO support on loopback was limited in
early versions so we should tolerate those failures.
However, we've verified that on 5.15 and newer that GRO is supported so
we should not tolerate failure in those cases.
Modifications:
- Add shims to CNIOLinux to get system info via uname
- Verify GRO works before running GRO tests and if it doesn't then
validate the kernel version isn't greater than 5.15.
Results:
Less flaky tests.
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.
Motivation:
I (foolishly) didn't validate the test fix in #2382, instead I validated
that the original test passed with 61 segments (rather than 64). The
channel needs to be recreated first.
Modifications:
- Rebuild the channel before trying again if 64 segments is too many.
Result:
Test passes.
Motivation:
On older kernel versions testWriteBufferAtGSOSegmentCountLimit fails
because the write fails with EINVAL. This appears to be a kernel bug as
it passes on more recent versions.
Modifications:
- Try again with a lower segment limit if the write fails with EINVAL.
Result:
Less flaky test.
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>
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.
* 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`
Motivation:
#fileID introduced in Swift 5.3, so no longer need to use #file anywhere
Modifications:
Changed #file to #filePath or #fileID depending on the situation
* 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>
* DatagramChannelTests: Handle receiving datagrams out-of-order in ECN tests
Signed-off-by: Si Beaumont <beaumont@apple.com>
* fixup: Simplify calls to write and read integer in payload
Signed-off-by: Si Beaumont <beaumont@apple.com>
* fixup: Iterate through expected reads, not actual reads
Signed-off-by: Si Beaumont <beaumont@apple.com>
* fixup: Order reads by seq payload and use array equality
* Update Tests/NIOPosixTests/DatagramChannelTests.swift
Co-authored-by: Cory Benfield <lukasa@apple.com>
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.