Commit Graph
30 Commits
Author SHA1 Message Date
Si BeaumontandAgam Dua b0e024792a Add opt-in API for channels to expose their underlying transport (#3509)
## Motivation

NIO channels abstract over an underlying transport mechanisms (sockets,
pipes, etc.), which users typically need not interact with. However,
there are scenarios where users need direct access to the underlying
transport for low-level operations that work outside NIOs abstraction.
One example is performing out out-of-band operations on the underlying
file descriptor for a socket-based channel.

This PR adds a structured way to access the underlying transport of a
channel, for channels that choose to implement it.

## Modifications

- Add a new `public protocol
NIOTransportAccessibleChannelCore<Transport>` which provides a scoped
`withUnsafeTransport(_:)`, used for channel implementations to opt-in.
- Add conformance to
`NIOTransportAccessibleChannel<NIOBSDSocket.Handle>` for
`BaseSocketChannel`, to make this API available for all socket-based
channels, including channels returned from the socket-based bootstrap
public APIs.
- Add public API
`ChannelPipeline.SynchronousOperations.withUnsafeTransportIfAvailable(_:)`

Note that not all channels need to or should their transport, which is
why this was added as an additional protocol that refines `ChannelCore`,
vs. extending `Channel` or `ChannelCore` with a default implementation.

The protocol uses a primary associated type allowing channels to provide
typed access to the transport. E.g. this could be used in NIO Transport
Services to expose the underlying `NWConnection`, if desired.

The method itself is spelled with "unsafe", uses scoped access, and has
clear documentation that users must not violated any of NIOs assumptions
about the state of the underlying transport. It's very much not intended
for every day use. It being on `ChannelCore` should defer users of the
low-level API, since `Channel._channelCore` is marked as for NIO
internal use, and the public `withUnsafeTransportIfAvailable(_:)` will
take care of the runtime checks for channels that have opted into this
API.

## Result

- New opt-in API for channel implementations to expose their underlying
transport
- All socket-based channels from NIOPosix now expose the underlying
socket file descriptor
- New API
`ChannelPipeline.SynchronousOperations.withUnsafeTransportIfAvailable(_:)`
for users

---------

Co-authored-by: Agam Dua <agam_dua@apple.com>
2026-02-17 16:12:58 +00:00
3405691582andRick Newton-Rogers 2bc71a6aff Partial OpenBSD support. (#3394)
### Motivation:

Additional partial platform support.

### Modifications: 

* Create a new CNIOBSD module for OpenBSD, for general cleanliness, and
make use of it throughout. Some of the changes are borrowed directly
from CNIOLinux; some may technically be unnecessary; I am erring
somewhat on expediency to functionality.

* Since `malloc_size` is unavailable on OpenBSD, and some of the helpers
make use of ManagedBufferPointer which makes use of it, mark some of
this as unavailable as well.

* Usual pthread optional typing changes, since pthread types are
pointers on this platform.

* Add conditionals to exclude other functionality not available here,
like IP_RECVPKTINFO or IP_PKTINFO.

* d_ino is a backwards-compatibility macro valued token for dirent, so
instead, just expand with a conditional.

* Use kqueue on OpenBSD. This necessitates adding some conditionals for
type and feature compatibility.

* The vsock API is unavailable on OpenBSD.

### Result:

Tested the NIOTCPEchoClient and NIOTCPEchoServer appears to work and
that swift-nio-ssh (hopefully wlog) builds with a local repository with
these changes.

Because NIOFS/_NIOFileSystem depend on some non-portable components,
such as extended attributes, sendfile, non-portable linkat flags, and
renameat2, this is only just partial OpenBSD support, which means that
`swift build` on the full swift-nio project won't build cleanly, but at
least the portable parts can be used to build servers and clients. This
commit will mark the linked bug as fixed; I will open a new bug for file
system support.

Fixes #3383.

---------

Co-authored-by: Rick Newton-Rogers <rnro@apple.com>
2025-11-26 09:07:02 +00:00
Fabian FettandCory Benfield a3ed8e10ab Drop Swift 5.10 (#3393)
This PR drops Swift 5.10 and enables Swift 6 language mode.

---------

Co-authored-by: Cory Benfield <lukasa@apple.com>
2025-10-06 10:58:33 +01:00
Cory Benfield abe4f1bcb6 Replace almost all public static lets with computed vars (#3229)
Motivation:

Public static lets can serve a bunch of roles, but one of them is to
store simple constants: integers, and other trivial types, for example.
This is a nice pattern and for internal and private static lets it works
well, but for public ones it produces some inefficient code.

In particular, it has two downsides. First, it allocates storage for
that value. We don't actually need to allocate a few hundred extra
megabytes for the various integers we want to store.

Secondly, it forces calling code to access the address and call the
dispatch_once code in order to get hold of the value. For trivial types
we don't need that cost: they can just know what the value is directly.

Inlinable computed vars avoid all of these costs: they have no size
overhead for storage, and they are visible to all clients so their
values can be directly assembled.

While I'm here, I added a bunch of other inlinable annotations for a few
trivial data types I stumbled onto.

Modifications:

- Added loads of inlinables. Like, loads.
- Swapped many static lets to static vars.

Result:

Better codegen, smaller memory footprints, more attributes.
2025-05-02 16:08:10 +01:00
Johannes Weiss 40ee44c6b9 always @preconcurrency import Glibc/Musl/Android/Bionic/WASILibc (#3153)
### Motivation:

The non-`Darwin` libcs don't have the correct concurrency annotations.
But due to these Swift bugs, it's important that the _first_ importer
uses `@preconcurrency`:

- https://github.com/swiftlang/swift/issues/79414
- https://github.com/swiftlang/swift/issues/77866

### Modifications:

Much like the Foundation (& corelibs) PRs such as
https://github.com/swiftlang/swift-foundation/pull/1175 , use
`@preconcurrency import` for the non-`Darwin` libcs.

### Result:

Fewer bad warnings/errors in user code.
2025-03-21 15:35:05 +00:00
Cory Benfield 37b31b95c2 Complete NIOCore strict concurrency (#2959)
Motivation:

With our earlier big refactors, NIOCore is now currently strict
concurrency clean. Let's lock in the win by adopting the relevant Swift
settings and fixing up the tests.

Modifications:

- Adopt our strict concurrency settings in NIOCore and NIOCoreTests
- Clean up the tests

Result:

One step closer to a world without warnings.
2024-10-31 20:35:57 +00:00
Jeff 8666af5d5f Fix Windows build for NIOCore. (#2938)
Fix build failures in `NIOCore` on Windows.

### Motivation:

I'd like it to build on Windows. 

### Modifications:

* Add missing `WinSDK` imports.
* Add missing `#elseif os(Windows)` branch for UDP.

### Result:

```
c:\users\jeff\src\swift-nio> swift build -Xcc -DBYTE_ORDER=LITTLE_ENDIAN --target NIOCore
Building for debugging...
[1/1] Write auxiliary file c:\users\jeff\src\swift-nio\.build\x86_64-unknown-windows-msvc\debug\swift-version--15FA6356563A8EA6.txt
Build of target: 'NIOCore' complete! (1.14s)
```
2024-10-22 07:09:28 +00:00
John ZhouandCory Benfield ac6d905654 Add new ChannelOption to get the amount of buffered outbound data in the Channel (#2849)
Add ability to get the amount of buffered outbound data from `Channel`

### Motivation:
Right now, SwiftNIO does not have the API to answer the question "how
much data is buffered in the Channel". Applications focusing on
performance may need to fine-tune the amount of outbound data that will
be sent to optimize data throughput, adjust sending rate to avoid
overflow, and potentially reduce latency.

SwiftNIO currently provides some backpressure mechanism. This new API
will be a good addition. By knowing how much data is buffered directly,
applications can make informed decision to adjust for optimal buffer
sizes and send rates.

### Modifications:
- Expose current buffer size through ChannelOptions so that users can
read the value out. StreamSocketChannel, DatagramSocketChannel,
EmbeddedChannel, and AsyncTestingChannel have the same API interface.
- Various modifications to the existing tests to make sure the new API
is working correctly.
- Add a new `so_sndbuf` socket option so that users can easily adjust
the send buffer size.

### Result:

Users can get the amount of outbound bytes currently buffered in the
`Channel` through the new `BufferedWritableBytesOption` channel option.

---------

Co-authored-by: Cory Benfield <lukasa@apple.com>
2024-09-23 10:12:48 +00:00
Max DesiatovandFranz Busch 730713e47f Add support for WASILibc (#2671)
Dispatch is not supported on WASI, and only Unix domain sockets are
supported, which means we have to exclude those APIs on this platform.

There's work in progress to enable tests for this on CI, but nothing I
can provide for this PR at the current moment.

---------

Co-authored-by: Franz Busch <f.busch@apple.com>
2024-09-12 13:18:25 +01:00
finagolfin 4feff3c2f6 Use the new Android overlay and Bionic module from Swift 6 (#2784)
Motivation:

Get this repo building again for Android with the new overlay

Modifications:

- Import the new module or overlay wherever `Glibc` is used
- Keep this repo building with Swift 5 by duplicating some declarations

Result:

All the same tests keep passing on my Android CI, finagolfin/swift-android-sdk#158
2024-07-22 09:58:09 +00:00
Franz Busch c9756e1083 Adopt swift-format (#2794)
* Apply formatting

* Apply no block comments rule

* Apply OmitExplicitReturns

* Apple OnlyOneTrailingClosureArgument

* Apply NoAssignmentInExpressions

* Fix up DontRepeatTypeInStaticProperties lint errors

* Apply `OrderedImports`

* Apply `ReplaceForEachWithForLoop`

* format file

* Enable the formatting pipeline

* Adopt `AmbiguousTrailingClosureOverload`

* Fix license header

* Fix format check

* Fix `EndOfLineComment`

* Fix CI

* Adapt CI script to check if changes when running formatting

* Separate lint and format into to steps

* Fix format

* Adopt `UseEarlyExits`

* Revert "Adopt `UseEarlyExits`"

This reverts commit d1ac5bbe12.
2024-07-19 11:48:17 +02:00
Rauhul Varma dc296f2ff7 Add NIOBSDSocket.Option for SO_BROADCAST (#2678)
This change allows users to setup a broadcast socket using a NIO owned
constant instead of directly using a C constant.

```diff
- .channelOption(ChannelOptions.socket(SOL_SOCKET, SO_BROADCAST), value: 1)
+ .channelOption(ChannelOptions.socketOption(.so_broadcast), value: 1)
```

Fixes #2674
2024-03-11 21:33:36 +00:00
finagolfin 4223cb3776 Build for Android with NDK 26, by accounting for the new nullability annotations (#2600)
Motivation:

Fix build for the latest LTS NDK 26

Modifications:

- Update C declarations
- Add force unwraps where needed

Result:

Everything works on Android with NDK 26b
2023-11-27 09:05:30 +00:00
finagolfin 231902a295 Correct a few Musl additions from #2449 for Android, plus error if libc not found (#2451)
Motivation

Fix build errors on Android

Modifications

- Fix previous Musl modifications that assumed Glibc wasn't imported on Android
- Add errors for all libc imports, so new platform ports error out early

Result

NIO builds natively on Android again, with all the same tests passing
2023-06-26 02:52:18 -07:00
Max Desiatov 43b1f59fde Add support for Musl libc (#2449)
* Add support for Musl libc

Since Musl is sufficiently different from Glibc (see https://wiki.musl-libc.org/functional-differences-from-glibc.html), it requires a different import, which now should be applied to files that have `import Glibc` in them.

* Fix `msghdr` initialization

* Fix msghdr mutability

* Fix `UnsafeMutableRawPointer` type conversions
2023-06-23 08:20:14 +01:00
Franz Busch e865f6163f Use #if canImport(Darwin) where possible (#2446) 2023-06-22 10:12:01 +01: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 BarnettandCory Benfield 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
Saleem Abdulrasool cd0aa5907b NIOCore: repair the Windows build of NIOCore (#2339)
The addition of the new IP constant resulted in a build failure on
Windows.  Add the import for the equivalent constant to repair the
build.
2022-12-22 16:37:54 -05:00
David Nadoba 810544ec41 Add RawSocketBootstrap (#2320) 2022-12-01 15:35:04 +01: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
David Nadoba 16b5b2b793 Replace NIOSendable with Sendable (#2291) 2022-10-13 15:56:27 +01:00
fae6522f6d NIOCore: adjust the BSDSocketAPI for Windows (#2164)
Windows does not provide a definition for `socklen_t`.  Create an
internal typealias for it to provide source stability to the internal
interfaces.

Co-authored-by: George Barnett <gbarnett@apple.com>
Co-authored-by: Cory Benfield <lukasa@apple.com>
2022-06-07 06:39:48 -07:00
Saleem Abdulrasool e109615309 NIOCore: import WSAGetLastError, GetLastError (#2131)
We use these functions to report errors from WinSock.  This was likely
excluded accidentally from previous commits.
2022-05-30 11:00:34 -07:00
Saleem Abdulrasool 0f93ed145b NIOCore: adjust for label change on Windows (#2130)
`NIOBSDSocket.inet_pton` and `NIOBSDSocket.inet_ntop` altered the label
for the family parameter but failed to update the Windows path.  Adjust
the name accordingly.
2022-05-30 10:32:30 -07:00
David Nadoba 4fb6bf135b Adopt Sendable for CircularBuffer, MarkedCircularBuffer and types in NIOBSDSocket namespace (#2097)
* Adopt `Sendable` for types in `BSDSocket` namespace

* Adopt `Sendable` for `CircularBuffer` and `MarkedCircularBuffer`

and also `Endianness`

* move `NIOSendable` into its own file and copy it over to syscall integration tests
2022-05-06 12:34:31 +01:00
buttafaceandCory Benfield 0467886d0b Get Android constants used by Channel from Bionic instead (#2026)
Motivation:

An upcoming pull, apple/swift#35707, moves Android to the same single-header
modulemap for Bionic as used on linux, but that doesn't work unless this is
changed. This approach works both with the current release toolchain and
with that new modulemap.

Modifications:

Change how these Bionic constants are imported.

Result:

This repo compiles for Android and the tests pass with both modulemap approaches.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2022-01-06 09:45:46 +00:00
buttaface 74b3a8d6a0 Copy Android constants needed by Channel over to NIOCore too (#1924)
Motivation:

Unbreak Android build from NIOCore not having these constants defined.

Modifications:

Copy the same constants that Channel was using in NIO over.

Result:

Android compiles again and the same tests pass.
2021-08-03 20:12:21 +01:00
Cory Benfield 8b06e8f996 Fix the missing socket options for 32-bit. (#1918)
Motivation:

When pulling out the NIOBSDSocket later in #1907 we dropped some of the
socket option fixes for 32 bit platforms, which broke them.

Modifications:

Restore the socket options.

Result:

32-bit build should be working again.
2021-07-26 17:24:18 +01:00
Cory Benfield 4bb6acf57d Move SocketAddress and NIOBSDSocket to NIOCore (#1907)
Motivation:

This is the next stage of our move of common interchange objects to
NIOCore and out of the NIO module. This time around we need
SocketAddress, which is part of the Channel API. Sadly, SocketAddress is
not as clean as some of the other ports, because it leaks a number of
POSIX-y concepts. This also forces us to bring along NIOBSDSocket, which
ideally we would not move, but we foolishly exposed as API on
SocketAddress.

Modifications:

- Move NIOBSDSocket API components into NIOCore.
- Split out the internal abstractions for NIOBSDSocket and leave those
  in NIO.
- Move SocketAddress into NIOCore.

Result:

SocketAddress will be sitting in NIOCore.
2021-07-22 17:48:14 +01:00