[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[Libevent-users] How to properly shutdown openssl filter?



Greetings all,

First I apologize for my previous failure to finish typing the message
before clicking send.

I have read through Diwaker's and Nick's past email relating to
bufferevent_openssl, but can't find the answer I'm looking for - if
it's been answered before, please point me to it.

What is the proper way to shutdown a bufferevent_openssl filter?
Specifically in the case where my app is a server, and the client
suddenly looses connectivity, thus no proper ssl shutdown handshake.

I have followed the lazy shutdown recommendation at
http://www.wangafu.net/~nickm/libevent-book/Ref6a_advanced_bufferevents.html
but I am still having trouble.

Specifically, I get a SIGSEGV after the bufferevent ssl filter has
been freed, and the SSL *ctx freed also. The bufferevent_free() call
is made from within the event callback that signals BEV_EVENT_ERROR.
The bufferevent filter itself is created with
BUFFEREVENT_SSL_ACCEPTING and without BEV_OPT_DEFER_CALLBACKS
(although enabling this option doesn't help avoid the SEGV).

#0  SSL_get_error (s=0x8071758, i=0) at ssl_lib.c:2366
#1  0x00134085 in do_read (bev_ssl=0x8073290, n_to_read=<value
optimized out>) at bufferevent_openssl.c:598
#2  0x00134701 in consider_reading (bev_ssl=0x8073290) at
bufferevent_openssl.c:783
#3  0x00134982 in be_openssl_enable (bev=0x8073290, events=2) at
bufferevent_openssl.c:1147
#4  0x0014d1b1 in bufferevent_unsuspend_read (bufev=0x8073290,
what=16) at bufferevent.c:85
#5  0x001508a8 in be_filter_destruct (bev=0x80739f8) at bufferevent_filter.c:239
#6  0x0014de91 in _bufferevent_decref_and_unlock (bufev=0x80739f8) at
bufferevent.c:622
#7  0x0015031e in be_filter_eventcb (underlying=0x8073290, what=32,
_me=0x80739f8) at bufferevent_filter.c:467
#8  0x0014e986 in _bufferevent_run_eventcb (bufev=0x8073290, what=32)
at bufferevent.c:267
#9  0x001328de in be_openssl_eventcb (bev_base=0x80701b0, what=17,
ctx=0x8073290) at bufferevent_openssl.c:926
#10 0x0014e986 in _bufferevent_run_eventcb (bufev=0x80701b0, what=17)
at bufferevent.c:267
#11 0x0014f397 in bufferevent_readcb (fd=16, event=2, arg=0x80701b0)
at bufferevent_sock.c:195
#12 0x001465e8 in event_process_active_single_queue (base=0x805df58,
flags=0) at event.c:1350
#13 event_process_active (base=0x805df58, flags=0) at event.c:1420
#14 event_base_loop (base=0x805df58, flags=0) at event.c:1621
#15 0x00147216 in event_base_dispatch (event_base=0x805df58) at event.c:1450
#16 0x0804c188 in main (argc=3, argv=0xbffff5c4) at main.c:155

It seems that the event dispatcher loop does not acknowledge that the
bev has been freed. Is it not correct to bufferevent_free() from
within the event callback?

The event callback I use does the following:

static void event_error_cb(struct bufferevent *buffev, short what, void *_arg)
{
    if (what == BEV_EVENT_ERROR) {
        struct bufferevent *underlying = bufferevent_get_underlying(bev);
        SSL *ssl= bufferevent_openssl_get_ssl(bev);
        int state = SSL_get_shutdown(ssl);

        if (state == 0) SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN);
        SSL_shutdown(ssl);
        bufferevent_free(bev);
        SSL_free(ssl);

        // this frees the stack of filters below "underlying"
        cleanup_ev_stack(underlying);

        // when this cb handler returns, all the bufferevents
        // have been freed
    }
}

Thank you
Sasha
***********************************************************************
To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
unsubscribe libevent-users    in the body.