patch: fix a bug in TLS code:

- handle recv with both TLS-handshake and Application data in same read
- robust ref-counting; handle mem_deref() in send-handler and estab-handler
This commit is contained in:
Alfred E. Heggestad 2011-11-11 23:58:34 +00:00
parent 386ddff14a
commit 1838b1c844
2 changed files with 51 additions and 23 deletions

View file

@ -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:

View file

@ -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);