Проблемы с 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 байт (тогда я получу все)....

0 ответов

Другие вопросы по тегам