Overview
Comment: | OFTLSStream: wrappedStream -> underlyingStream |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
3ed8cf7a5236bf395a6185a412f22ad3 |
User & Date: | js on 2021-11-21 10:40:27 |
Other Links: | manifest | tags |
Context
2021-11-21
| ||
20:50 | Fix building with GnuTLS support on Windows check-in: 2bdee7e97d user: js tags: trunk | |
10:40 | OFTLSStream: wrappedStream -> underlyingStream check-in: 3ed8cf7a52 user: js tags: trunk | |
10:18 | OFSecureTransportTLSStream: Fix EWOULDBLOCK check-in: 8cd4bd9fdd user: js tags: trunk | |
Changes
Modified src/OFTLSStream.h from [b3a209020a] to [d05dc14c91].
︙ | ︙ | |||
61 62 63 64 65 66 67 | * if available. * * Subclasses need to override @ref lowlevelReadIntoBuffer:length:, * @ref lowlevelWriteBuffer:length: and * @ref asyncPerformClientHandshakeWithHost:runLoopMode:. The method * @ref hasDataInReadBuffer should be overridden to return `true` if the TLS * stream has cached unprocessed data internally, while returning | | | | | | | | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | * if available. * * Subclasses need to override @ref lowlevelReadIntoBuffer:length:, * @ref lowlevelWriteBuffer:length: and * @ref asyncPerformClientHandshakeWithHost:runLoopMode:. The method * @ref hasDataInReadBuffer should be overridden to return `true` if the TLS * stream has cached unprocessed data internally, while returning * `self.underlyingStream.hasDataInReadBuffer` if it does not have any * unprocessed data. In order to get access to the underlying stream, * @ref underlyingStream can be used. */ @interface OFTLSStream: OFStream <OFReadyForReadingObserving, OFReadyForWritingObserving> { OFStream <OFReadyForReadingObserving, OFReadyForWritingObserving> *_underlyingStream; bool _verifiesCertificates; OF_RESERVE_IVARS(OFTLSStream, 4) } /** * @brief The underlying stream. */ @property (readonly, nonatomic) OFStream <OFReadyForReadingObserving, OFReadyForWritingObserving> *underlyingStream; /** * @brief The delegate for asynchronous operations on the stream. * * @note The delegate is retained for as long as asynchronous operations are * still ongoing. */ |
︙ | ︙ |
Modified src/OFTLSStream.m from [659fa26933] to [de0cb549c8].
︙ | ︙ | |||
68 69 70 71 72 73 74 | { _done = true; _exception = [exception retain]; } @end @implementation OFTLSStream | | | 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | { _done = true; _exception = [exception retain]; } @end @implementation OFTLSStream @synthesize underlyingStream = _underlyingStream; @dynamic delegate; @synthesize verifiesCertificates = _verifiesCertificates; + (instancetype)alloc { if (self == [OFTLSStream class]) { if (OFTLSStreamImplementation != Nil) |
︙ | ︙ | |||
102 103 104 105 106 107 108 | - (instancetype)initWithStream: (OFStream <OFReadyForReadingObserving, OFReadyForWritingObserving> *)stream { self = [super init]; @try { | | | | | | | | | | 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | - (instancetype)initWithStream: (OFStream <OFReadyForReadingObserving, OFReadyForWritingObserving> *)stream { self = [super init]; @try { _underlyingStream = [stream retain]; _verifiesCertificates = true; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_underlyingStream release]; [super dealloc]; } - (void)close { [_underlyingStream release]; _underlyingStream = nil; [super close]; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length { OF_UNRECOGNIZED_SELECTOR } - (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length { OF_UNRECOGNIZED_SELECTOR } - (bool)hasDataInReadBuffer { return (super.hasDataInReadBuffer || _underlyingStream.hasDataInReadBuffer); } - (bool)lowlevelIsAtEndOfStream { return _underlyingStream.atEndOfStream; } - (int)fileDescriptorForReading { return _underlyingStream.fileDescriptorForReading; } - (int)fileDescriptorForWriting { return _underlyingStream.fileDescriptorForWriting; } - (void)asyncPerformClientHandshakeWithHost: (OFString *)host { [self asyncPerformClientHandshakeWithHost: host runLoopMode: OFDefaultRunLoopMode]; } |
︙ | ︙ |
Modified src/tls/OFGnuTLSTLSStream.m from [633e4da737] to [72367f1922].
︙ | ︙ | |||
33 34 35 36 37 38 39 | @implementation OFGnuTLSTLSStream static ssize_t readFunc(gnutls_transport_ptr_t transport, void *buffer, size_t length) { OFGnuTLSTLSStream *stream = (OFGnuTLSTLSStream *)transport; @try { | | | | | | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | @implementation OFGnuTLSTLSStream static ssize_t readFunc(gnutls_transport_ptr_t transport, void *buffer, size_t length) { OFGnuTLSTLSStream *stream = (OFGnuTLSTLSStream *)transport; @try { length = [stream.underlyingStream readIntoBuffer: buffer length: length]; } @catch (OFReadFailedException *e) { gnutls_transport_set_errno(stream->_session, e.errNo); return -1; } if (length == 0 && !stream.underlyingStream.atEndOfStream) { gnutls_transport_set_errno(stream->_session, EWOULDBLOCK); return -1; } return length; } static ssize_t writeFunc(gnutls_transport_ptr_t transport, const void *buffer, size_t length) { OFGnuTLSTLSStream *stream = (OFGnuTLSTLSStream *)transport; @try { [stream.underlyingStream writeBuffer: buffer length: length]; } @catch (OFWriteFailedException *e) { gnutls_transport_set_errno(stream->_session, e.errNo); if (e.errNo == EWOULDBLOCK) return e.bytesWritten; return -1; |
︙ | ︙ | |||
90 91 92 93 94 95 96 | - (instancetype)initWithStream: (OFStream <OFReadyForReadingObserving, OFReadyForWritingObserving> *)stream { self = [super initWithStream: stream]; @try { | | | 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | - (instancetype)initWithStream: (OFStream <OFReadyForReadingObserving, OFReadyForWritingObserving> *)stream { self = [super initWithStream: stream]; @try { _underlyingStream.delegate = self; } @catch (id e) { [self release]; @throw e; } return self; } |
︙ | ︙ | |||
234 235 236 237 238 239 240 | if (_verifiesCertificates) gnutls_session_set_verify_cert(_session, _host.UTF8String, 0); status = gnutls_handshake(_session); if (status == GNUTLS_E_INTERRUPTED || status == GNUTLS_E_AGAIN) { if (gnutls_record_get_direction(_session) == 1) | | | | | | 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 | if (_verifiesCertificates) gnutls_session_set_verify_cert(_session, _host.UTF8String, 0); status = gnutls_handshake(_session); if (status == GNUTLS_E_INTERRUPTED || status == GNUTLS_E_AGAIN) { if (gnutls_record_get_direction(_session) == 1) [_underlyingStream asyncWriteData: [OFData dataWithItems: "" count: 0] runLoopMode: runLoopMode]; else [_underlyingStream asyncReadIntoBuffer: (void *)"" length: 0 runLoopMode: runLoopMode]; [_delegate retain]; return; } if (status != GNUTLS_E_SUCCESS) /* FIXME: Map to better errors */ |
︙ | ︙ | |||
277 278 279 280 281 282 283 | if (status == GNUTLS_E_INTERRUPTED || status == GNUTLS_E_AGAIN) { if (gnutls_record_get_direction(_session) == 1) { OFData *data = [OFData dataWithItems: "" count: 0]; OFRunLoopMode runLoopMode = [OFRunLoop currentRunLoop].currentMode; | | | | 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 | if (status == GNUTLS_E_INTERRUPTED || status == GNUTLS_E_AGAIN) { if (gnutls_record_get_direction(_session) == 1) { OFData *data = [OFData dataWithItems: "" count: 0]; OFRunLoopMode runLoopMode = [OFRunLoop currentRunLoop].currentMode; [_underlyingStream asyncWriteData: data runLoopMode: runLoopMode]; return false; } else return true; } if (status != GNUTLS_E_SUCCESS) exception = [OFTLSHandshakeFailedException |
︙ | ︙ | |||
319 320 321 322 323 324 325 | if (status == GNUTLS_E_INTERRUPTED || status == GNUTLS_E_AGAIN) { if (gnutls_record_get_direction(_session) == 1) return data; else { OFRunLoopMode runLoopMode = [OFRunLoop currentRunLoop].currentMode; | | | 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 | if (status == GNUTLS_E_INTERRUPTED || status == GNUTLS_E_AGAIN) { if (gnutls_record_get_direction(_session) == 1) return data; else { OFRunLoopMode runLoopMode = [OFRunLoop currentRunLoop].currentMode; [_underlyingStream asyncReadIntoBuffer: (void *)"" length: 0 runLoopMode: runLoopMode]; return nil; } } |
︙ | ︙ |
Modified src/tls/OFSecureTransportTLSStream.m from [e80afd9547] to [446883c227].
︙ | ︙ | |||
30 31 32 33 34 35 36 | static OSStatus readFunc(SSLConnectionRef connection, void *data, size_t *dataLength) { bool incomplete; size_t length; @try { | | | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | static OSStatus readFunc(SSLConnectionRef connection, void *data, size_t *dataLength) { bool incomplete; size_t length; @try { length = [((OFTLSStream *)connection).underlyingStream readIntoBuffer: data length: *dataLength]; } @catch (OFReadFailedException *e) { if (e.errNo == EWOULDBLOCK) { *dataLength = 0; return errSSLWouldBlock; } |
︙ | ︙ | |||
52 53 54 55 56 57 58 | return (incomplete ? errSSLWouldBlock : noErr); } static OSStatus writeFunc(SSLConnectionRef connection, const void *data, size_t *dataLength) { @try { | | | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | return (incomplete ? errSSLWouldBlock : noErr); } static OSStatus writeFunc(SSLConnectionRef connection, const void *data, size_t *dataLength) { @try { [((OFTLSStream *)connection).underlyingStream writeBuffer: data length: *dataLength]; } @catch (OFWriteFailedException *e) { *dataLength = e.bytesWritten; if (e.errNo == EWOULDBLOCK) return errSSLWouldBlock; |
︙ | ︙ | |||
87 88 89 90 91 92 93 | - (instancetype)initWithStream: (OFStream <OFReadyForReadingObserving, OFReadyForWritingObserving> *)stream { self = [super initWithStream: stream]; @try { | | | 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | - (instancetype)initWithStream: (OFStream <OFReadyForReadingObserving, OFReadyForWritingObserving> *)stream { self = [super initWithStream: stream]; @try { _underlyingStream.delegate = self; } @catch (id e) { [self release]; @throw e; } return self; } |
︙ | ︙ | |||
215 216 217 218 219 220 221 | * Theoretically it is possible we block because Secure * Transport cannot write without blocking. But unfortunately, * Secure Transport does not tell us whether it's blocked on * reading or writing. Waiting for the stream to be either * readable or writable doesn't work either, as the stream is * almost always at least ready for one of the two. */ | | | | | 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | * Theoretically it is possible we block because Secure * Transport cannot write without blocking. But unfortunately, * Secure Transport does not tell us whether it's blocked on * reading or writing. Waiting for the stream to be either * readable or writable doesn't work either, as the stream is * almost always at least ready for one of the two. */ [_underlyingStream asyncReadIntoBuffer: (void *)"" length: 0 runLoopMode: runLoopMode]; [_delegate retain]; return; } if (status != noErr) /* FIXME: Map to better errors */ exception = [OFTLSHandshakeFailedException |
︙ | ︙ |