Skip to content

Commit 27f4de0

Browse files
committed
Adds a new Socket Stream Protocol implementation that lets us use kernel TCP
1 parent 5fed088 commit 27f4de0

7 files changed

Lines changed: 2566 additions & 71 deletions

File tree

Sources/SwiftNetwork/EndpointFlow/EndpointFlowExtension.swift

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -76,26 +76,49 @@ extension EndpointFlow {
7676

7777
switch transport {
7878
case .tcp(let options):
79-
guard let reference = TCPProtocol().newProtocolInstance(context: context) else {
80-
throw NetworkError.posix(EINVAL)
79+
if case .custom(let linkOptions) = stack.link,
80+
linkOptions.identifier == BridgeDatagramProtocol.identifier
81+
{
82+
guard let reference = TCPProtocol().newProtocolInstance(context: context) else {
83+
throw NetworkError.posix(EINVAL)
84+
}
85+
options.setProtocolInstance(reference)
86+
let linkage = OutboundStreamLinkage(reference: reference)
87+
let flow = try StreamEndpointFlowProtocol(
88+
identifier: String(self.identifier),
89+
local: effectiveLocalEndpoint,
90+
remote: effectiveRemoteEndpoint,
91+
parameters: self.parameters,
92+
path: path,
93+
context: context,
94+
lowerStreamProtocol: linkage
95+
)
96+
self.flowProtocol = .stream(flow)
97+
options.setLogID(
98+
prefix: "C",
99+
parent: String(self.identifier),
100+
protocolLogIDNumber: Int(self.identifier)
101+
)
102+
} else {
103+
let socketReference = SocketStreamProtocol.instance(context: context)
104+
options.setProtocolInstance(socketReference)
105+
let linkage = OutboundStreamLinkage(reference: socketReference)
106+
let flow = try StreamEndpointFlowProtocol(
107+
identifier: String(self.identifier),
108+
local: effectiveLocalEndpoint,
109+
remote: effectiveRemoteEndpoint,
110+
parameters: self.parameters,
111+
path: path,
112+
context: context,
113+
lowerStreamProtocol: linkage
114+
)
115+
self.flowProtocol = .stream(flow)
116+
options.setLogID(
117+
prefix: "C",
118+
parent: String(self.identifier),
119+
protocolLogIDNumber: Int(self.identifier)
120+
)
81121
}
82-
options.setProtocolInstance(reference)
83-
let linkage = OutboundStreamLinkage(reference: reference)
84-
let flow = try StreamEndpointFlowProtocol(
85-
identifier: String(self.identifier),
86-
local: effectiveLocalEndpoint,
87-
remote: effectiveRemoteEndpoint,
88-
parameters: self.parameters,
89-
path: path,
90-
context: context,
91-
lowerStreamProtocol: linkage
92-
)
93-
self.flowProtocol = .stream(flow)
94-
options.setLogID(
95-
prefix: "C",
96-
parent: String(self.identifier),
97-
protocolLogIDNumber: Int(self.identifier)
98-
)
99122
case .udp(let options):
100123
if case .custom(let linkOptions) = stack.link,
101124
linkOptions.identifier == BridgeDatagramProtocol.identifier

Sources/SwiftNetwork/EndpointFlow/EndpointFlowProtocols.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,13 @@ class EndpointFlowProtocol<LinkageType: InboundDataLinkage>: ProtocolInstanceCon
165165

166166
func handleInboundDataAvailableEvent(_ from: ProtocolInstanceReference) {
167167
log.debug("Received inbound data available event")
168+
// Clear the slot before invoking: the completion may synchronously
169+
// re-arm the waiter (when receiveStreamData returns nil because the
170+
// requested minimum spans more than one segment). Clearing afterwards
171+
// would clobber that re-registration and drop later notifications.
168172
if let inboundDataAvailableCompletion = self.completions.inboundDataAvailable {
169-
inboundDataAvailableCompletion(true)
170173
self.completions.inboundDataAvailable = nil
174+
inboundDataAvailableCompletion(true)
171175
}
172176
}
173177

0 commit comments

Comments
 (0)