diff --git a/src/tcp/tcp.c b/src/tcp/tcp.c index 502b260..784c1f8 100644 --- a/src/tcp/tcp.c +++ b/src/tcp/tcp.c @@ -299,7 +299,19 @@ static void tcp_recv_handler(int flags, void *arg) if (tc->connected) { + uint32_t nrefs; + + mem_ref(tc); + err = dequeue(tc); + + nrefs = mem_nrefs(tc); + mem_deref(tc); + + /* check if connection was deref'd from send handler */ + if (nrefs == 1) + return; + if (err) { conn_close(tc, err); return; @@ -371,31 +383,52 @@ static void tcp_recv_handler(int flags, void *arg) le = tc->helpers.head; while (le) { struct tcp_helper *th = le->data; - bool hdld; + bool hdld = false; le = le->next; - if (!hlp_estab) - hdld = th->recvh(&err, mb, &hlp_estab, th->arg); - else - hdld = th->estabh(&err, tc->active, th->arg); + if (hlp_estab) { - if (hdld || err) { - if (err) + hdld |= th->estabh(&err, tc->active, th->arg); + if (err) { conn_close(tc, err); - goto out; + goto out; + } } + + if (mb->pos < mb->end) { + + hdld |= th->recvh(&err, mb, &hlp_estab, th->arg); + if (err) { + conn_close(tc, err); + goto out; + } + } + + if (hdld) + goto out; } mbuf_trim(mb); - if (!hlp_estab) { - if (tc->recvh) - tc->recvh(mb, tc->arg); + if (hlp_estab && tc->estabh) { + + uint32_t nrefs; + + mem_ref(tc); + + tc->estabh(tc->arg); + + nrefs = mem_nrefs(tc); + mem_deref(tc); + + /* check if connection was deref'ed from establish handler */ + if (nrefs == 1) + goto out; } - else { - if (tc->estabh) - tc->estabh(tc->arg); + + if (mb->pos < mb->end && tc->recvh) { + tc->recvh(mb, tc->arg); } out: diff --git a/src/tls/openssl/tls_tcp.c b/src/tls/openssl/tls_tcp.c index d96dc98..158cf1e 100644 --- a/src/tls/openssl/tls_tcp.c +++ b/src/tls/openssl/tls_tcp.c @@ -214,13 +214,11 @@ static bool recv_handler(int *err, struct mbuf *mb, bool *estab, void *arg) DEBUG_INFO("state=0x%04x\n", SSL_state(tc->ssl)); /* TLS connection is established */ - if (SSL_state(tc->ssl) == SSL_ST_OK) { - *estab = true; - tc->up = true; - return false; - } + if (SSL_state(tc->ssl) != SSL_ST_OK) + return true; - return true; + *estab = true; + tc->up = true; } mbuf_set_pos(mb, 0); @@ -256,9 +254,6 @@ static bool recv_handler(int *err, struct mbuf *mb, bool *estab, void *arg) mb->pos += n; } - if (!mb->pos) - return true; - mbuf_set_end(mb, mb->pos); mbuf_set_pos(mb, 0);