diff --git a/crypto/bio/bio_test.cc b/crypto/bio/bio_test.cc index ee35dc3bb3..9266581381 100644 --- a/crypto/bio/bio_test.cc +++ b/crypto/bio/bio_test.cc @@ -696,4 +696,31 @@ TEST_P(BIOPairTest, TestCallbacks) { ASSERT_EQ(param_len_ex[0], 0u); } +namespace { + static int callback_invoked = 0; + + static long callback(BIO *b, int state, int res) { + callback_invoked = 1; + EXPECT_EQ(state, 0); + EXPECT_EQ(res, -1); + return 0; + } + + TEST(BIOTest, InvokeConnectCallback) { + + ASSERT_EQ(callback_invoked, 0); + BIO *bio = BIO_new(BIO_s_connect()); + ASSERT_NE(bio, nullptr); + + ASSERT_TRUE(BIO_set_conn_hostname(bio, "localhost")); + ASSERT_TRUE(BIO_set_conn_port(bio, "8080")); + ASSERT_TRUE(BIO_callback_ctrl(bio, BIO_CTRL_SET_CALLBACK, callback)); + + ASSERT_EQ(BIO_do_connect(bio), 0); + ASSERT_EQ(callback_invoked, 1); + + ASSERT_TRUE(BIO_free(bio)); + } +} + INSTANTIATE_TEST_SUITE_P(All, BIOPairTest, testing::Values(false, true)); diff --git a/crypto/bio/connect.c b/crypto/bio/connect.c index c19f1c4e65..ae730b8795 100644 --- a/crypto/bio/connect.c +++ b/crypto/bio/connect.c @@ -105,7 +105,7 @@ typedef struct bio_connect_st { // info_callback is called when the connection is initially made // callback(BIO,state,ret); The callback should return 'ret', state is for // compatibility with the SSL info_callback. - int (*info_callback)(const BIO *bio, int state, int ret); + bio_info_cb info_callback; } BIO_CONNECT; #if !defined(OPENSSL_WINDOWS) @@ -168,7 +168,7 @@ static int split_host_and_port(char **out_host, char **out_port, static int conn_state(BIO *bio, BIO_CONNECT *c) { int ret = -1, i; - int (*cb)(const BIO *, int, int) = NULL; + bio_info_cb cb = NULL; if (c->info_callback != NULL) { cb = c->info_callback; @@ -467,7 +467,7 @@ static long conn_ctrl(BIO *bio, int cmd, long num, void *ptr) { case BIO_CTRL_FLUSH: break; case BIO_CTRL_GET_CALLBACK: { - int (**fptr)(const BIO *bio, int state, int xret) = ptr; + bio_info_cb *fptr = ptr; *fptr = data->info_callback; } break; default: @@ -485,13 +485,7 @@ static long conn_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp) { switch (cmd) { case BIO_CTRL_SET_CALLBACK: - // This is the actual type signature of |fp|. The caller is expected to - // cast it to |bio_info_cb| due to the |BIO_callback_ctrl| calling - // convention. - OPENSSL_MSVC_PRAGMA(warning(push)) - OPENSSL_MSVC_PRAGMA(warning(disable : 4191)) - data->info_callback = (int (*)(const struct bio_st *, int, int))fp; - OPENSSL_MSVC_PRAGMA(warning(pop)) + data->info_callback = fp; break; default: ret = 0; diff --git a/include/openssl/bio.h b/include/openssl/bio.h index cb8902edf2..b0e8694737 100644 --- a/include/openssl/bio.h +++ b/include/openssl/bio.h @@ -244,13 +244,12 @@ OPENSSL_EXPORT int BIO_method_type(const BIO *bio); // The BIO_CB_RETURN flag indicates if it is after the call #define BIO_CB_RETURN 0x80 -// bio_info_cb is the type of a callback function that can be called for most -// BIO operations. The |event| argument is one of |BIO_CB_*| and can be ORed -// with |BIO_CB_RETURN| if the callback is being made after the operation in -// question. In that case, |return_value| will contain the return value from -// the operation. -typedef long (*bio_info_cb)(BIO *bio, int event, const char *parg, int cmd, - long larg, long return_value); +// |bio_info_cb| is a type of callback function providing information about a +// BIO operation. |state| identifies the current state of the BIO +// object, such as |BIO_CONN_S_BEFORE|. |res| represent the result of the +// operation that triggered the callback. This can be a positive value, zero, +// or a negative value depending on the operation and its outcome. +typedef long (*bio_info_cb)(BIO *b, int state, int res); // |BIO_callback_fn_ex| parameters have the following meaning: // |bio| the bio that made the call