Bonjour, I'm running into something strange. Here's an extract of my code:
----- [...] { time_t start; BIO *cbio = NULL; if ((cbio = BIO_new(BIO_s_connect())) == NULL) { result = ERR(CMCLIENTERR_CONNEXION); goto done; } BIO_set_conn_hostname(cbio, server_name); BIO_set_conn_port(cbio, server_port); /* Configure the BIO as a non-blocking one */ BIO_set_nbio(cbio, 1); /* We'll mesure time from now */ start = time(NULL); /* Let's try to connect, deal with retries and timeout */ while (difftime(time(NULL), start) < mytimeout) { res = BIO_do_connect(cbio); /* If BIO_do_connect() said it's OK, then get out of this loop */ if (res > 0) break; /* If it failed, check if retrying can be useful */ if ((res <= 0) && !BIO_should_retry(cbio)) { LOGMSG(LOG_ERR, "Unable to connect to CM server"); result = ERR(CMCLIENTERR_CANTCONNECT); goto done; } } [... do something useful, since it's OK now ...] done: [my cleanup code]; } ----- In the normal case, everything works OK. But I found myself trying to connect to a host behind a blocking firewall (with a DROP policy), and the BIO_do_connect() call is performed exactly twice. The first time it returns -1, cbio->flags is set to 12 (BIO_FLAGS_SHOULD_RETRY|BIO_FLAGS_IO_SPECIAL), indicating that I should retry the connect, and cbio->ptr.state is set to 7 (BIO_CONN_S_BLOCKED_CONNECT). The second time it returns something > 0, indicating it's OK, but the connection hasn't been performed, and subsequent reads and writes fail. Reading the bss_conn.c source file, I can track down the BIO_do_connect() code down to conn_state(), and the following code: ----- for (;;) { switch (c->state) { [...] case BIO_CONN_S_BLOCKED_CONNECT: i=BIO_sock_error(b->num); if (i) { BIO_clear_retry_flags(b); SYSerr(SYS_F_CONNECT,i); ERR_add_error_data(4,"host=", c->param_hostname, ":",c->param_port); BIOerr(BIO_F_CONN_STATE,BIO_R_NBIO_CONNECT_ERROR); ret=0; goto exit_loop; } else c->state=BIO_CONN_S_OK; break; case BIO_CONN_S_OK: ret=1; goto exit_loop; default: /* abort(); */ goto exit_loop; } [...] ----- That means that if the BIO is in BIO_CONN_S_BLOCKED_CONNECT state (and in my case it is), any subsequent call to BIO_do_connect() returns OK (state changes to BIO_CONN_S_OK, for() loop is executed once more, and the function return with ret=1). Is that really intended to work like this? I know I could check for BIO_should_io_special() for this, but: - there's no standard action to do (if I want to read or write, I can do a select() call, but here?) - even if I call BIO_should_io_special(), the state of the BIO is already set to BIO_CONN_S_BLOCKED_CONNECT, and the next call to BIO_do_connect() will return 1, I loose. If I don't call BIO_set_nbio(), the call to BIO_do_connect() is blocked at connect() (that's normal), and eventually it'll return back to me. Using blocking BIOs is not an option: - I can't control the timeouts - BIO_set_nbio() should be called before connecting (as per the manpage) -- Erwann ABALEA <[EMAIL PROTECTED]> ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]