From a615a75e81b0ef0b33e69d50c2840a1f1ada7057 Mon Sep 17 00:00:00 2001 From: Gwynne Raskind Date: Thu, 18 Nov 2021 04:22:27 -0600 Subject: [PATCH 1/2] Add `PeerMaximumMessageLength` option for SSH child channels. Fixes #99 --- .../Child Channels/ChildChannelOptions.swift | 10 ++++++++ .../Child Channels/SSHChildChannel.swift | 2 ++ .../ChildChannelMultiplexerTests.swift | 25 +++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/Sources/NIOSSH/Child Channels/ChildChannelOptions.swift b/Sources/NIOSSH/Child Channels/ChildChannelOptions.swift index 4921aad..3210782 100644 --- a/Sources/NIOSSH/Child Channels/ChildChannelOptions.swift +++ b/Sources/NIOSSH/Child Channels/ChildChannelOptions.swift @@ -26,6 +26,9 @@ public struct SSHChildChannelOptions { /// - seealso: `SSHChannelTypeOption`. public static let sshChannelType: SSHChildChannelOptions.Types.SSHChannelTypeOption = .init() + + /// - seealso: `PeerMaximumMessageLengthOption`. + public static let peerMaximumMessageLength: SSHChildChannelOptions.Types.PeerMaximumMessageLengthOption = .init() } extension SSHChildChannelOptions { @@ -53,4 +56,11 @@ extension SSHChildChannelOptions.Types { public init() {} } + + /// `PeerMaximumMessageLengthOption` allows users to query the maximum packet size value reported by the remote peer for a given channel. + public struct PeerMaximumMessageLengthOption: ChannelOption { + public typealias Value = UInt32 + + public init() {} + } } diff --git a/Sources/NIOSSH/Child Channels/SSHChildChannel.swift b/Sources/NIOSSH/Child Channels/SSHChildChannel.swift index 11c27c8..32d2fec 100644 --- a/Sources/NIOSSH/Child Channels/SSHChildChannel.swift +++ b/Sources/NIOSSH/Child Channels/SSHChildChannel.swift @@ -222,6 +222,8 @@ extension SSHChildChannel: Channel, ChannelCore { // This force-unwrap is safe: we set type before we call the initializer, so // users can only get this after this value is set. return self.type! as! Option.Value + case _ as SSHChildChannelOptions.Types.PeerMaximumMessageLengthOption: + return self.peerMaxMessageSize as! Option.Value case _ as ChannelOptions.Types.AutoReadOption: return self.autoRead as! Option.Value case _ as ChannelOptions.Types.AllowRemoteHalfClosureOption: diff --git a/Tests/NIOSSHTests/ChildChannelMultiplexerTests.swift b/Tests/NIOSSHTests/ChildChannelMultiplexerTests.swift index 54a9016..839681d 100644 --- a/Tests/NIOSSHTests/ChildChannelMultiplexerTests.swift +++ b/Tests/NIOSSHTests/ChildChannelMultiplexerTests.swift @@ -1729,6 +1729,31 @@ final class ChildChannelMultiplexerTests: XCTestCase { self.assertChannelOpenConfirmation(harness.flushedMessages.first, recipientChannel: 1) } + + func testChildChannelMaxMessageLengthOption() throws { + let harness = self.harnessForbiddingInboundChannels() + defer { + harness.finish() + } + + var childChannel: Channel? + harness.multiplexer.createChildChannel(channelType: .session) { channel, _ in + childChannel = channel + return channel.eventLoop.makeSucceededFuture(()) + } + + guard let channel = childChannel else { + XCTFail("Did not create child channel") + return + } + + // Activate channel. + let channelID = self.assertChannelOpen(harness.flushedMessages.first) + XCTAssertNoThrow(try harness.multiplexer.receiveMessage(self.openConfirmation(originalChannelID: channelID!, peerChannelID: 1, initialWindowSize: 5, maxPacketSize: 4247))) + XCTAssertTrue(channel.isWritable) + + XCTAssertEqual(try channel.getOption(SSHChildChannelOptions.peerMaximumMessageLength).wait(), 4247) + } } extension ByteBuffer { From eb24beb09086c3972fe92354c65885170f1b361d Mon Sep 17 00:00:00 2001 From: Gwynne Raskind Date: Mon, 22 Nov 2021 07:57:47 -0600 Subject: [PATCH 2/2] Apply formatting fixes from soundness check --- Sources/NIOSSH/Child Channels/ChildChannelOptions.swift | 6 +++--- Tests/NIOSSHTests/ChildChannelMultiplexerTests.swift | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/NIOSSH/Child Channels/ChildChannelOptions.swift b/Sources/NIOSSH/Child Channels/ChildChannelOptions.swift index 3210782..f7ea562 100644 --- a/Sources/NIOSSH/Child Channels/ChildChannelOptions.swift +++ b/Sources/NIOSSH/Child Channels/ChildChannelOptions.swift @@ -26,7 +26,7 @@ public struct SSHChildChannelOptions { /// - seealso: `SSHChannelTypeOption`. public static let sshChannelType: SSHChildChannelOptions.Types.SSHChannelTypeOption = .init() - + /// - seealso: `PeerMaximumMessageLengthOption`. public static let peerMaximumMessageLength: SSHChildChannelOptions.Types.PeerMaximumMessageLengthOption = .init() } @@ -56,11 +56,11 @@ extension SSHChildChannelOptions.Types { public init() {} } - + /// `PeerMaximumMessageLengthOption` allows users to query the maximum packet size value reported by the remote peer for a given channel. public struct PeerMaximumMessageLengthOption: ChannelOption { public typealias Value = UInt32 - + public init() {} } } diff --git a/Tests/NIOSSHTests/ChildChannelMultiplexerTests.swift b/Tests/NIOSSHTests/ChildChannelMultiplexerTests.swift index 839681d..0f816c2 100644 --- a/Tests/NIOSSHTests/ChildChannelMultiplexerTests.swift +++ b/Tests/NIOSSHTests/ChildChannelMultiplexerTests.swift @@ -1751,7 +1751,7 @@ final class ChildChannelMultiplexerTests: XCTestCase { let channelID = self.assertChannelOpen(harness.flushedMessages.first) XCTAssertNoThrow(try harness.multiplexer.receiveMessage(self.openConfirmation(originalChannelID: channelID!, peerChannelID: 1, initialWindowSize: 5, maxPacketSize: 4247))) XCTAssertTrue(channel.isWritable) - + XCTAssertEqual(try channel.getOption(SSHChildChannelOptions.peerMaximumMessageLength).wait(), 4247) } }