/[ Further below I quote my first two messages including my original questions and tentative code,// // since Cc'ing to openssl-users did not work when I tried first. In this way I hope to get further, // // more detailed responses by people with specific experience on the issues I mentioned,// // possibly even concrete feedback how to enhance my code or where to find a better solution. ]/
On 09/01/2017 06:32 PM, Salz, Rich via openssl-users wrote: > > FWIW, there’s a ‘libtls’ library from the libre folks that might be > worth looking at. > This looks very nice. Yet is this of any practical benefit when using OpenSSL? > If you come up with useful snippets we can start by posting them to > the wiki, for example > Which wiki do you mean? I could not find anything related on https://wiki.openssl.org/ Anyway, most people (including me) would not search through wikis for finding useful code, and it would be much more useful if code like the bio_connect() function I mentioned below was readily available within the OpenSSL libraries, in an official high-level API. /[ Since this is worth a topic of its own, I'll write more on this in my next email. ]/ More low-level code that is already used by the crypto lib itself (e.g., using select() in rand_unix.c) would be better packaged into abstractions within that library, for instance the socket_wait() function for waiting on a socket with a timeout that I proposed below. I'd contribute pull requests for those I'm aware of. On 29.08.2017 16:15, Salz, Rich via openssl-dev wrote: >> Getting the client connect right appears surprisingly messy when one >> needs to cope with all kinds of network error situations including >> domain name resolution issues and temporarily unreachable servers. >> Both indefinitely blocking and non-blocking behavior (i.e., connection >> attempts with and without a timeout) should be supported. > It is a complicated issue and hard to get right for all definitions of right > for all applications ☺ Hmm - on the one hand, good to get confirmation that I did not just miss a simple way of out the maze, ... > A set of API’s that set up all the TLS “metadata”, and took a connected > socket might be a way through the maze. For example: > SSL *SSL_connection(int socket, const char *servername, …whatever…) ... on the other hand, it's a pity that such a high-level API does not (yet) exist, at least not in OpenSSL. How about adding at least some clearly useful abstractions like the below socket_wait() function, which would reduce code duplication in the OpenSSL crypto lib and apps and help application developers? Maybe other OpenSSL users have specific experience on error and timeout handling for BIO_do_connect() etc. and can comment in more detail on the (approximate) solution, bio_connect(), that I gave below? On 28.08.2017 13:46, David von Oheimb wrote: > Hi all, > > I'm currently enhancing HTTP(S) clients based on OpenSSL in several > flavors, in particular a CMP client, which in turn uses simple HTTP > clients for contacting CRL distribution points or OCSP responders. > > Getting the client connect right appears surprisingly messy when one > needs to cope with all kinds of network error situations including > domain name resolution issues and temporarily unreachable servers. > Both indefinitely blocking and non-blocking behavior (i.e., connection > attempts with and without a timeout) should be supported. > > Since these are pretty general problems I wonder why there there is > rather limited support via generic higher-level OpenSSL or C library > functions, or at least I was unable to find it. Instead, the OpenSSL > apps contain code that calls BIO_do_connect directly (or the equivalent > BIO_do_handshake), in particular query_responder() in apps/ocsp.c. > (The situation is similar for the subsequent exchange of data via the > BIO, optionally with a timeout). > > So I constructed my own abstraction, called bio_connect, which took > quite some effort testing network error situations. Please see below its > code including comments on some strange behavior I experienced and my > workarounds for that. Does this code make sense, or do I miss anything? > > How about adding such a function for instance to crypto/bio/bio_lib.c? > > BTW, my code uses a handy generic helper function, socket_wait, for > waiting for read/write form/to a socket, with a given timeout. Since > several instances of that pretty common code pattern using select() are > spread over the OpenSSL apps (and crypto lib), I suggest adding this > function to the library. Where would be a good place to put it? > > Thanks, > David >> /* returns -1 on error, 0 on timeout, 1 on success */ >> int bio_connect(BIO *bio, int timeout) { >> int blocking; >> time_t max_time; >> int rv; >> >> blocking = timeout == 0; >> max_time = timeout != 0 ? time(NULL) + timeout : 0; >> >> if (!blocking) >> BIO_set_nbio(bio, 1); >> retry: >> rv = BIO_do_connect(bio); >> if (rv <= 0 && (errno == ETIMEDOUT /* in blocking case, >> despite blocking BIO, BIO_do_connect() timed out */ || >> ERR_GET_REASON(ERR_peek_error()) == ETIMEDOUT/* when non-blocking, >> BIO_do_connect() timed out early with rv == -1 and errno == 0 */)) >> { >> ERR_clear_error(); >> (void)BIO_reset(bio); /* otherwise, blocking next connect() may crash >> and non-blocking next BIO_do_connect() will >> fail */ >> goto retry; >> } >> if (!blocking && rv <= 0 && BIO_should_retry(bio)) { >> int fd; >> if (BIO_get_fd(bio, &fd) <= 0) >> return -1; >> rv = socket_wait(fd, 1, max_time - time(NULL)); >> if (rv > 0) >> /* for some reason, select() may wrongly have returned success */ >> goto retry; >> } >> return rv; >> } >> /* returns < 0 on error, 0 on timeout, >0 on success */ >> int socket_wait(int fd, int for_read, int timeout) >> { >> fd_set confds; >> struct timeval tv; >> >> if (timeout <= 0) >> return 0; >> >> FD_ZERO(&confds); >> openssl_fdset(fd, &confds); >> tv.tv_usec = 0; >> tv.tv_sec = timeout; >> return select(fd + 1, for_read ? &confds : NULL, >> for_read ? NULL : &confds, NULL, &tv); >> }
-- openssl-users mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users