3131#include <wolfcert/errors.h>
3232#include "internal.h"
3333
34- #include <wolfssl/wolfio.h>
35- #include <wolfssl/error-ssl.h>
36-
3734#include <errno.h>
3835#include <limits.h>
3936#include <fcntl.h>
@@ -183,26 +180,13 @@ static int posix_wait(int fd, short events, int timeout_ms, int want)
183180 return WOLFCERT_OK ;
184181}
185182
186- /* wolfIO_* return CBIO codes, which carry no direction: WANT_READ and
187- * WANT_WRITE are the same value, so the caller supplies `want`. */
188- static int map_io (int n , int want )
189- {
190- if (n > 0 )
191- return n ;
192- /* wolfSSL passes a 0-length read straight through, so map it here. */
193- if (n == 0 )
194- return WOLFCERT_ERR_CONN_CLOSED ;
195-
196- switch (n ) {
197- case WOLFSSL_CBIO_ERR_WANT_READ : /* == WANT_WRITE */
198- return want ;
199- case WOLFSSL_CBIO_ERR_CONN_CLOSE :
200- case WOLFSSL_CBIO_ERR_CONN_RST :
201- return WOLFCERT_ERR_CONN_CLOSED ;
202- default :
203- return WOLFCERT_ERR_IO ;
204- }
205- }
183+ /* A failed transfer is an I/O error unless it merely would block, so this is
184+ * the one errno the byte path reads. */
185+ #if defined(EWOULDBLOCK ) && EWOULDBLOCK != EAGAIN
186+ #define WOLFCERT_WOULDBLOCK (e ) ((e) == EAGAIN || (e) == EWOULDBLOCK)
187+ #else
188+ #define WOLFCERT_WOULDBLOCK (e ) ((e) == EAGAIN)
189+ #endif
206190
207191/* poll() only promises that one byte can move, so the transfer must never
208192 * block; the wait is poll's job. Sockets the transport owns stay O_NONBLOCK. */
@@ -242,8 +226,8 @@ static int posix_read(void* ctx, void* conn, uint8_t* buf, size_t len,
242226 int timeout_ms )
243227{
244228 int fd = (int )(intptr_t )conn ;
229+ ssize_t n ;
245230 int rc ;
246- int n ;
247231
248232 (void )ctx ;
249233
@@ -257,24 +241,30 @@ static int posix_read(void* ctx, void* conn, uint8_t* buf, size_t len,
257241 if (rc != WOLFCERT_OK )
258242 return rc ;
259243
260- /* TranslateIoReturnCode reports EINTR rather than retrying. */
261244 do {
262- n = wolfIO_Recv (fd , ( char * ) buf , ( int ) len , 0 );
263- } while (n == WOLFSSL_CBIO_ERR_ISR );
245+ n = recv (fd , buf , len , 0 );
246+ } while (n < 0 && errno == EINTR );
264247
265- if (n != WOLFSSL_CBIO_ERR_WANT_READ || timeout_ms >= 0 )
266- break ;
267- }
248+ if (n > 0 )
249+ return (int )n ;
250+ if (n == 0 )
251+ return WOLFCERT_ERR_CONN_CLOSED ;
268252
269- return map_io (n , WOLFCERT_ERR_WANT_READ );
253+ /* poll() can report a readiness the transfer then declines. Only an
254+ * unbounded caller waits again; the others report it. */
255+ if (!WOLFCERT_WOULDBLOCK (errno ))
256+ return WOLFCERT_ERR_IO ;
257+ if (timeout_ms >= 0 )
258+ return WOLFCERT_ERR_WANT_READ ;
259+ }
270260}
271261
272262static int posix_write (void * ctx , void * conn , const uint8_t * buf , size_t len ,
273263 int timeout_ms )
274264{
275265 int fd = (int )(intptr_t )conn ;
266+ ssize_t n ;
276267 int rc ;
277- int n ;
278268
279269 (void )ctx ;
280270
@@ -289,14 +279,19 @@ static int posix_write(void* ctx, void* conn, const uint8_t* buf, size_t len,
289279 return rc ;
290280
291281 do {
292- n = wolfIO_Send (fd , ( char * )( uintptr_t ) buf , ( int ) len , 0 );
293- } while (n == WOLFSSL_CBIO_ERR_ISR );
282+ n = send (fd , buf , len , 0 );
283+ } while (n < 0 && errno == EINTR );
294284
295- if (n != WOLFSSL_CBIO_ERR_WANT_WRITE || timeout_ms >= 0 )
296- break ;
297- }
285+ if (n > 0 )
286+ return (int )n ;
287+ if (n == 0 )
288+ return WOLFCERT_ERR_IO ;
298289
299- return map_io (n , WOLFCERT_ERR_WANT_WRITE );
290+ if (!WOLFCERT_WOULDBLOCK (errno ))
291+ return WOLFCERT_ERR_IO ;
292+ if (timeout_ms >= 0 )
293+ return WOLFCERT_ERR_WANT_WRITE ;
294+ }
300295}
301296
302297static int posix_disconnect (void * ctx , void * conn )
@@ -314,10 +309,11 @@ const WolfCertTransport wolfcert_posix_transport = {
314309};
315310
316311/* Dial through the deprecated connect_cb, keeping every fd detail in this file.
317- * The descriptor becomes ours, so it gets the O_NONBLOCK posix_connect sets. */
312+ * The descriptor belongs to the application, so only a non-blocking session
313+ * changes its mode; a blocking one leaves it exactly as supplied. */
318314int wolfcert_legacy_connect (WolfCertConnectFn cb , void * cb_ctx ,
319315 const char * host , int port , int timeout_ms ,
320- void * * conn )
316+ int nonblocking , void * * conn )
321317{
322318 int fd ;
323319
@@ -328,7 +324,7 @@ int wolfcert_legacy_connect(WolfCertConnectFn cb, void* cb_ctx,
328324 if (fd < 0 )
329325 return WOLFCERT_ERR_IO ;
330326
331- if (set_nonblock (fd ) != WOLFCERT_OK ) {
327+ if (nonblocking && set_nonblock (fd ) != WOLFCERT_OK ) {
332328 (void )close (fd );
333329 return WOLFCERT_ERR_IO ;
334330 }
@@ -338,8 +334,61 @@ int wolfcert_legacy_connect(WolfCertConnectFn cb, void* cb_ctx,
338334}
339335
340336/* Byte path for a connection opened by wolfcert_legacy_connect. */
337+ static int legacy_read (void * ctx , void * conn , uint8_t * buf , size_t len ,
338+ int timeout_ms )
339+ {
340+ int fd = (int )(intptr_t )conn ;
341+ ssize_t n ;
342+
343+ if (timeout_ms >= 0 )
344+ return posix_read (ctx , conn , buf , len , timeout_ms );
345+
346+ if (buf == NULL || len == 0 )
347+ return WOLFCERT_ERR_BAD_ARG ;
348+ if (len > INT_MAX )
349+ len = INT_MAX ;
350+
351+ do {
352+ n = recv (fd , buf , len , 0 );
353+ } while (n < 0 && errno == EINTR );
354+
355+ if (n > 0 )
356+ return (int )n ;
357+ if (n == 0 )
358+ return WOLFCERT_ERR_CONN_CLOSED ;
359+
360+ /* A would-block here is the descriptor's own timeout expiring. */
361+ return WOLFCERT_ERR_IO ;
362+ }
363+
364+ static int legacy_write (void * ctx , void * conn , const uint8_t * buf , size_t len ,
365+ int timeout_ms )
366+ {
367+ int fd = (int )(intptr_t )conn ;
368+ ssize_t n ;
369+
370+ if (timeout_ms >= 0 )
371+ return posix_write (ctx , conn , buf , len , timeout_ms );
372+
373+ if (buf == NULL || len == 0 )
374+ return WOLFCERT_ERR_BAD_ARG ;
375+ if (len > INT_MAX )
376+ len = INT_MAX ;
377+
378+ do {
379+ n = send (fd , buf , len , 0 );
380+ } while (n < 0 && errno == EINTR );
381+
382+ if (n > 0 )
383+ return (int )n ;
384+ if (n == 0 )
385+ return WOLFCERT_ERR_IO ;
386+
387+ return WOLFCERT_ERR_IO ;
388+ }
389+
341390const WolfCertTransport wolfcert_legacy_transport = {
342- NULL , posix_read , posix_write , posix_disconnect , NULL
391+ NULL , legacy_read , legacy_write , posix_disconnect , NULL
343392};
344393
345394int wolfcert_transport_is_fd_backed (const WolfCertTransport * t )
0 commit comments