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

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



Hi Sasha,

Could you post you sources somewhere?

If not, you could look at https://github.com/ellzey/libevhtp/blob/master/evhtp.c from libevhtp project.

On Fri, Jan 25, 2013 at 6:47 AM, Sasha Limanov <szlimanov@xxxxxxxxx> wrote:
> 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.

--
Azat Khuzhin