On Wed, Feb 01, 2006 at 09:49:26AM +0100, Nils Larsch wrote: > >This is chnaging the beahavior of static long conn_ctrl(BIO *b, int cmd, > >long num, void > >*ptr) function. > >I think it is a typo (just like some other epople using openssl). > >Nils, could you please confirm me that, or explain me the reason why > >changing this? > > well "if (!data->state != BIO_CONN_S_OK)" obviously doesn't make > much sense as BIO_CONN_S_OK (== 6) is always unequal to 0 or 1, > but looking at the code again I think it really should be > "if (data->state != BIO_CONN_S_OK)" as conn_state() does nothing > if the BIO is already in the BIO_CONN_S_OK state.
"fixing" this typo like that still breaks the state machine at connect time. let's say we add some debug around the if statement: ----snip----snip----snip----snip----snip----snip----snip----snip---- case BIO_C_DO_STATE_MACHINE: /* use this one to start the connection */ fprintf(stderr, "data->state = %d\n", data->state); if (!(data->state != BIO_CONN_S_OK)) { fprintf(stderr, "called conn_state()\n"); ret=(long)conn_state(b,data); } else { fprintf(stderr, "whoops! wrong turn!\n"); ret=1; } break; ----snip----snip----snip----snip----snip----snip----snip----snip---- and use this trivial code for testing: ----snip----snip----snip----snip----snip----snip----snip----snip---- #include <openssl/bio.h> main() { BIO *b = BIO_new(BIO_s_connect()); int fd, res; BIO_set_conn_hostname(b, "127.0.0.1:4242"); res = BIO_do_connect(b); fprintf(stderr, "do_connect: %d\n", res); fd = BIO_get_fd(b, &fd); fprintf(stderr, "fd = %d\n", fd); BIO_puts(b, "test\n"); fd = BIO_get_fd(b, &fd); fprintf(stderr, "fd = %d\n", fd); return 0; } ----snip----snip----snip----snip----snip----snip----snip----snip---- prior to the incriminated commit, we got this at execution (assuming some server is listening on 127.0.0.1:4242): ----snip----snip----snip----snip----snip----snip----snip----snip---- $ ./test data->state = 1 called conn_state() do_connect: 1 fd = 3 fd = 3 ----snip----snip----snip----snip----snip----snip----snip----snip---- everything looks okay. notice the value of data->state before the BIO_do_connect() call, which is NOT BIO_CONN_S_OK ! just in case, let's test without anyone listening on 127.0.0.1:4242. ----snip----snip----snip----snip----snip----snip----snip----snip---- $ ./test data->state = 1 called conn_state() do_connect: -1 fd = 3 fd = 3 ----snip----snip----snip----snip----snip----snip----snip----snip---- BIO_do_connect() returned -1, as expected from a refused connection to a closed port... now let's look at what happens with the parentheses from the commit: ----snip----snip----snip----snip----snip----snip----snip----snip---- $ ./test data->state = 1 whoops! wrong turn! do_connect: 1 fd = -1 fd = 3 ----snip----snip----snip----snip----snip----snip----snip----snip---- uh-oh! conn_state() is obviously not called (noticed the "use this one to *start* the connection" just above the if in the code ?). just to be sure, let's try again with a closed port on the other side: ----snip----snip----snip----snip----snip----snip----snip----snip---- $ ./test data->state = 1 whoops! wrong turn! do_connect: 1 fd = -1 fd = 3 ----snip----snip----snip----snip----snip----snip----snip----snip---- same result, and no error reported. not exactly what I call consistent behavior... what's interesting is the fd value. before the BIO_puts() it's -1, which is normal since *nothing* was done yet due to the "wrong turn". after the BIO_puts() call, the connection is established, because of this code in conn_write() (the same is also true if we do a read instead): ----snip----snip----snip----snip----snip----snip----snip----snip---- if (data->state != BIO_CONN_S_OK) { ret=conn_state(b,data); if (ret <= 0) return(ret); } ----snip----snip----snip----snip----snip----snip----snip----snip---- this effectively establishes the connection, but a bit too late. I don't know if you're like that, but when I do a connect(2) call on unix sockets, I like to have my socket right now, not just after the first read() or write() :P IMHO, the negation in your commit should be removed, and the if statement (which looks like it's been some "miraculously-working" typo since a few years from now) should just be like the ones in conn_read() and conn_write(). Cheers, -- Gabriel Forté <[EMAIL PROTECTED]> ______________________________________________________________________ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager [EMAIL PROTECTED]