Skip to content

Commit d87eac9

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

7 files changed

Lines changed: 2478 additions & 77 deletions

File tree

Sources/SwiftNetwork/EndpointFlow/EndpointFlowExtension.swift

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -76,26 +76,48 @@ 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+
guard let reference = TCPProtocol().newProtocolInstance(context: context) else {
82+
throw NetworkError.posix(EINVAL)
83+
}
84+
options.setProtocolInstance(reference)
85+
let linkage = OutboundStreamLinkage(reference: reference)
86+
let flow = try StreamEndpointFlowProtocol(
87+
identifier: String(self.identifier),
88+
local: effectiveLocalEndpoint,
89+
remote: effectiveRemoteEndpoint,
90+
parameters: self.parameters,
91+
path: path,
92+
context: context,
93+
lowerStreamProtocol: linkage
94+
)
95+
self.flowProtocol = .stream(flow)
96+
options.setLogID(
97+
prefix: "C",
98+
parent: String(self.identifier),
99+
protocolLogIDNumber: Int(self.identifier)
100+
)
101+
} else {
102+
let socketReference = SocketStreamProtocol.instance(context: context)
103+
options.setProtocolInstance(socketReference)
104+
let linkage = OutboundStreamLinkage(reference: socketReference)
105+
let flow = try StreamEndpointFlowProtocol(
106+
identifier: String(self.identifier),
107+
local: effectiveLocalEndpoint,
108+
remote: effectiveRemoteEndpoint,
109+
parameters: self.parameters,
110+
path: path,
111+
context: context,
112+
lowerStreamProtocol: linkage
113+
)
114+
self.flowProtocol = .stream(flow)
115+
options.setLogID(
116+
prefix: "C",
117+
parent: String(self.identifier),
118+
protocolLogIDNumber: Int(self.identifier)
119+
)
81120
}
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-
)
99121
case .udp(let options):
100122
if case .custom(let linkOptions) = stack.link,
101123
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)