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:
parent
386ddff14a
commit
1838b1c844
2 changed files with 51 additions and 23 deletions
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue