Skip to content

Commit 2c404e9

Browse files
committed
agnosticdev/SpinBitVariance: Added first byte observer to protocol options
1 parent 2f32370 commit 2c404e9

3 files changed

Lines changed: 32 additions & 33 deletions

File tree

Sources/SwiftNetwork/Protocols/BridgeProtocol.swift

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ public struct DatagramDrops: Equatable {
6666
}
6767
}
6868

69+
public typealias BridgeObserveFirstByteHandler = ((UInt8) -> Void)?
70+
6971
@_spi(Essentials)
7072
@available(Network 0.1.0, *)
7173
public struct BridgeDatagramProtocol: NetworkProtocol {
@@ -75,6 +77,7 @@ public struct BridgeDatagramProtocol: NetworkProtocol {
7577

7678
public struct BridgeOptions: PerProtocolOptions {
7779
public var linkDelay: NetworkDuration = .zero
80+
public var observeFirstByteHandler: BridgeObserveFirstByteHandler = nil
7881
var datagramDrops: DatagramDrops?
7982

8083
init() {}
@@ -96,6 +99,10 @@ public struct BridgeDatagramProtocol: NetworkProtocol {
9699
self == other
97100
}
98101

102+
static public func == (lhs: BridgeOptions, rhs: BridgeOptions) -> Bool {
103+
lhs.linkDelay == rhs.linkDelay && lhs.datagramDrops == rhs.datagramDrops
104+
}
105+
99106
var isDefault: Bool {
100107
self == BridgeOptions()
101108
}
@@ -142,7 +149,7 @@ public struct BridgeDatagramProtocol: NetworkProtocol {
142149

143150
var linkDelay: NetworkDuration = .zero
144151
var datagramDrops: DatagramDrops? = nil
145-
var observeFirstByte: ((UInt8) -> Void)? = nil
152+
var observeFirstByteHandler: BridgeObserveFirstByteHandler = nil
146153

147154
private var timerSet = false
148155
func deliverInboundDataAvailableEvent() {
@@ -184,6 +191,7 @@ public struct BridgeDatagramProtocol: NetworkProtocol {
184191
{
185192
self.linkDelay = bridgeOptions.linkDelay
186193
self.datagramDrops = bridgeOptions.datagramDrops
194+
self.observeFirstByteHandler = bridgeOptions.observeFirstByteHandler
187195
}
188196
#endif
189197

@@ -276,10 +284,10 @@ public struct BridgeDatagramProtocol: NetworkProtocol {
276284
datagrams = remainingDatagrams
277285
}
278286
log.datapath("forwarding \(datagrams.count) datagrams to port: \(remotePort)")
279-
if let observeFirstByte {
287+
if let observeFirstByteHandler {
280288
datagrams.iterateMutableFrames { frame in
281289
if let bytes = frame.bytes, bytes.byteCount > 0 {
282-
observeFirstByte(bytes[0])
290+
observeFirstByteHandler(bytes[0])
283291
}
284292
return true
285293
}
@@ -332,6 +340,11 @@ extension ProtocolOptions<BridgeDatagramProtocol> {
332340
set { perProtocolOptions!.linkDelay = newValue }
333341
}
334342

343+
public var observeFirstByteHandler: BridgeObserveFirstByteHandler {
344+
get { perProtocolOptions!.observeFirstByteHandler }
345+
set { perProtocolOptions!.observeFirstByteHandler = newValue }
346+
}
347+
335348
public var datagramDrops: DatagramDrops? {
336349
get { perProtocolOptions!.datagramDrops }
337350
set { perProtocolOptions!.datagramDrops = newValue }

Tests/SwiftNetworkTests/QUICTestHarness.swift

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,6 @@ final class QUICTestHarness {
7676

7777
let clientInstance: QUICProtocol.Instance
7878
let serverInstance: QUICProtocol.Instance
79-
80-
let clientBridge: BridgeDatagramProtocol.Instance
81-
let serverBridge: BridgeDatagramProtocol.Instance
8279
}
8380
var state: QUICHarnessState? = nil
8481

@@ -141,7 +138,8 @@ final class QUICTestHarness {
141138
serverDrops: DatagramDrops? = nil,
142139
timeout: TimeInterval = 5.0,
143140
clientOptions: ProtocolOptions<QUICProtocol> = QUICProtocol.options(),
144-
serverOptions: ProtocolOptions<QUICProtocol> = QUICProtocol.options()
141+
serverOptions: ProtocolOptions<QUICProtocol> = QUICProtocol.options(),
142+
bridgeObserveFirstByteHandler: BridgeObserveFirstByteHandler = nil
145143
) throws(NetworkError) {
146144
var clientConnected = false
147145
var serverConnected = false
@@ -168,9 +166,9 @@ final class QUICTestHarness {
168166
clientOptions.setProtocolInstance(clientReference)
169167
clientParameters.defaultStack.transport = .quic(clientOptions)
170168

171-
let clientBridgeInstance = BridgeDatagramProtocol.Instance(context: self.context)
172-
let clientBridge = clientBridgeInstance.reference
169+
let clientBridge = BridgeDatagramProtocol.instance(context: self.context)
173170
let clientBridgeOptions = BridgeDatagramProtocol.options()
171+
clientBridgeOptions.observeFirstByteHandler = bridgeObserveFirstByteHandler
174172
clientBridgeOptions.setProtocolInstance(clientBridge)
175173
clientBridgeOptions.linkDelay = clientLinkDelay
176174
clientBridgeOptions.datagramDrops = clientDrops
@@ -196,9 +194,9 @@ final class QUICTestHarness {
196194
serverOptions.setProtocolInstance(serverReference)
197195
serverParameters.defaultStack.transport = .quic(serverOptions)
198196

199-
let serverBridgeInstance = BridgeDatagramProtocol.Instance(context: self.context)
200-
let serverBridge = serverBridgeInstance.reference
197+
let serverBridge = BridgeDatagramProtocol.instance(context: self.context)
201198
let serverBridgeOptions = BridgeDatagramProtocol.options()
199+
serverBridgeOptions.observeFirstByteHandler = bridgeObserveFirstByteHandler
202200
serverBridgeOptions.setProtocolInstance(serverBridge)
203201
serverBridgeOptions.linkDelay = serverLinkDelay
204202
serverBridgeOptions.datagramDrops = serverDrops
@@ -297,9 +295,7 @@ final class QUICTestHarness {
297295
clientReference: clientReference,
298296
serverReference: serverReference,
299297
clientInstance: clientInstance,
300-
serverInstance: serverInstance,
301-
clientBridge: clientBridgeInstance,
302-
serverBridge: serverBridgeInstance
298+
serverInstance: serverInstance
303299
)
304300

305301
clientHarness.waitForError { error in
@@ -550,18 +546,6 @@ final class QUICTestHarness {
550546
wait(for: [stopCompleteExpectation], timeout: 5.0)
551547
}
552548

553-
// Installs a callback on the client and server bridge that fires passing the raw first byte to the
554-
// caller for a short header packet. Used to detect a spin bit passing between the client and server.
555-
func observeFirstByteForOutboundShortHeaderPacket(handler: @escaping (_ firstByte: UInt8) -> Void) {
556-
guard let state else { return }
557-
let observe: ((UInt8) -> Void) = { firstByte in
558-
guard (firstByte & 0xC0) == 0x40 else { return }
559-
handler(firstByte)
560-
}
561-
state.clientBridge.observeFirstByte = observe
562-
state.serverBridge.observeFirstByte = observe
563-
}
564-
565549
func echoDataOnStream(
566550
dataGenerator: TestDataGenerator,
567551
streamIndex: Int,
@@ -933,6 +917,7 @@ final class QUICTestHarness {
933917
extraServerCIDs: [(QUICConnectionID, QUICStatelessResetToken)] = .init(),
934918
afterHandshake: ((QUICTestHarness) -> Void)? = nil, // Block to run after handshake is complete
935919
afterData: ((QUICTestHarness) -> Void)? = nil, // Block to run after handshake is complete
920+
bridgeObserveFirstByteHandler: BridgeObserveFirstByteHandler = nil
936921
) {
937922
// Start with the handshake
938923
Logger.test.debug("Test phase: Handshake")
@@ -952,7 +937,8 @@ final class QUICTestHarness {
952937
serverDrops: serverDrops,
953938
timeout: timeout,
954939
clientOptions: clientOptions,
955-
serverOptions: serverOptions
940+
serverOptions: serverOptions,
941+
bridgeObserveFirstByteHandler: bridgeObserveFirstByteHandler
956942
)
957943
} catch {
958944
if expectHandshakeError == nil {

Tests/SwiftNetworkTests/SwiftNetworkQUICSpinBitTests.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ final class SwiftNetworkQUICSpinBitTests: NetTestCase {
6161

6262
var hasSpinBit = true
6363
var observedSpinBitValues: Set<Bool> = []
64+
let observeFirstByteHandler: BridgeObserveFirstByteHandler = { firstByte in
65+
guard (firstByte & 0xC0) == 0x40 else { return }
66+
observedSpinBitValues.insert((firstByte & 0x20) != 0)
67+
}
6468
QUICTestHarness().runQUICTest(
6569
dataBlock: Array("Hello World!".utf8),
6670
afterHandshake: { harness in
@@ -79,11 +83,6 @@ final class SwiftNetworkQUICSpinBitTests: NetTestCase {
7983
hasSpinBit = false
8084
return
8185
}
82-
// If we have made it this far we should at least be able to detect at least one spin bit value going back and forth
83-
// Detect at least 1 outbound datagram sending a spin bit value
84-
harness.observeFirstByteForOutboundShortHeaderPacket { firstByte in
85-
observedSpinBitValues.insert((firstByte & 0x20) != 0)
86-
}
8786
}
8887
self.wait(for: [expectation], timeout: 5.0)
8988
},
@@ -104,7 +103,8 @@ final class SwiftNetworkQUICSpinBitTests: NetTestCase {
104103
"BridgeDatagramProtocol should have observed at least one packet with spin bit set"
105104
)
106105
}
107-
}
106+
},
107+
bridgeObserveFirstByteHandler: observeFirstByteHandler
108108
)
109109
}
110110

0 commit comments

Comments
 (0)