in Sources/NIOSSH/SSHPacketParser.swift [57:106]
mutating func nextPacket() throws -> SSHMessage? {
// This parser has a slightly strange strategy: we leave the packet length field in the buffer until we're done.
// This is necessary because some transport protection schemes need the length field for MACing purposes, and can
// benefit from us maintaining the state instead of having to do it themselves.
defer {
self.reclaimBytes()
}
switch self.state {
case .initialized:
if let version = try self.readVersion() {
self.state = .cleartextWaitingForLength
return .version(version)
}
return nil
case .cleartextWaitingForLength:
if let length = self.buffer.getInteger(at: self.buffer.readerIndex, as: UInt32.self) {
if let message = try self.parsePlaintext(length: length) {
self.state = .cleartextWaitingForLength
return message
}
self.state = .cleartextWaitingForBytes(length)
return nil
}
return nil
case .cleartextWaitingForBytes(let length):
if let message = try self.parsePlaintext(length: length) {
self.state = .cleartextWaitingForLength
return message
}
return nil
case .encryptedWaitingForLength(let protection):
guard let length = try self.decryptLength(protection: protection) else {
return nil
}
if let message = try self.parseCiphertext(length: length, protection: protection) {
self.state = .encryptedWaitingForLength(protection)
return message
}
self.state = .encryptedWaitingForBytes(length, protection)
return nil
case .encryptedWaitingForBytes(let length, let protection):
if let message = try self.parseCiphertext(length: length, protection: protection) {
self.state = .encryptedWaitingForLength(protection)
return message
}
return nil
}
}