Проблемы с SSLRead: чтение больше / меньше размера буфера
У меня проблема с SSLRead
от Apple SecureTransport. Я создал оболочку Swift для POSIX-Socket, и это прекрасно работает. Но я также хочу иметь поддержку TLS. Это также хорошо работает, пока входящие данные не будут меньше, чем буфер. Если он больше, чем я получаю данные, кроме последних, это не заполняет размер буфера.
Например: у меня размер буфера 2048. Если я отправил 2519 байтов (см. Комментарии в коде), я получу одно чтение с 2048 байтами, а остальное приходит при следующем чтении, если я отправил больше данных от клиента. Если я изменю размер буфера на 1024, я получу два чтения (а не три). В чем проблема?
Вот мой код:
Функция принятия
if let newClient = try s.accept() {
try newClient.startTLS(config: config)
let size = 2048
var bytesRead = 1
while bytesRead > 0 {
let buffer = UnsafeMutablePointer<Int8>.allocate(capacity: size)
do {
bytesRead = try newClient.read(buffer: buffer, size: size)
let readData = Data(bytes: buffer, count: bytesRead)
if let str = String(data: readData, encoding: .utf8) {
dataHandler(str, newClient)
}
}
}
}
Функция чтения
func read(buffer: UnsafeMutablePointer<Int8>, size: Int) throws -> Int {
if let fd = self.fileDescriptor {
if self.tls != nil {
return try self.readTLS(buffer: buffer, size: size)
}
...
}
fileprivate func readTLS(buffer: UnsafeMutablePointer<Int8>, size: Int) throws -> Int {
guard let context = self.tls?.sslContext else { return -1 }
var received = 0
let status = SSLRead(context, buffer, size, &received)
// this prints: status readTLS: 0, size: 2048, received: 2048
print("status readTLS: \(status), size: \(size), received: \(received)")
if status != noErr {
// error handling
}
return received
}
SSLReadFunc
private func sslRead(connection: SSLConnectionRef, data: UnsafeMutableRawPointer, dataLength: UnsafeMutablePointer<Int>) -> OSStatus {
// Extract the socket file descriptor from the context...
let socketfd = connection.assumingMemoryBound(to: Int32.self).pointee
// Now the bytes to read...
let bytesRequested = dataLength.pointee
// Read the data from the socket...
let bytesRead = recv(socketfd, data, bytesRequested, 0)
// prints: SSL: bytesRead: 2519, bytesRequested: 2519
print("SSL: bytesRead: \(bytesRead), bytesRequested: \(bytesRequested)")
if bytesRead > 0 {
dataLength.initialize(to: bytesRead)
if bytesRequested > bytesRead {
return OSStatus(errSSLWouldBlock)
} else {
return noErr
}
} else if bytesRead == 0 {
dataLength.initialize(to: 0)
return OSStatus(errSSLClosedGraceful)
} else {
dataLength.initialize(to: 0)
switch errno {
case ENOENT:
return OSStatus(errSSLClosedGraceful)
case EAGAIN:
return OSStatus(errSSLWouldBlock)
case ECONNRESET:
return OSStatus(errSSLClosedAbort)
default:
return OSStatus(errSecIO)
}
}
}
ОБНОВИТЬ
Увеличение буфера до 32768 как минимум, похоже, решит проблему, даже если я отправлю больше 32768 байт (тогда я получу все)....