transp: deref qent only if qentp is not set #1061
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
If
qentp
is set, the caller ofsip_transp_send
is responsible for derefingqent
.This caused undesirable behavior in the following scenario: A message is sent using
sip_transp_send
and the transport is TLS 1.3. The peer (i.e. server) requests a client certificate from us and then the server terminates the TLS and TCP connection (e.g. due to an invalid ceritificate). In this case, the caller ofsip_transp_send
never gets alerted that there was a transport error and some other timeout mechanism kicks in (e.g. in SIP 64 * T1). In BareSIP, this means e.g. that we start an outgoing call and the call stays in this outgoing call state for 32 seconds while the underlying TCP/TLS connection has long be terminated. Ideally, this transport error would immediately be propagated upwards.This happens due to the abbreviated TLS 1.3 handshake (see RFC 8446): The server sends a
Finished
message in theServerHello
and the client responds with aFinished
message and aCertificate
if requested. After this message, the handshake is considered completed (but the server has not verified our certificate yet, if requested).So in
re
intcp_estab_handler
,tcp_send
is called and it succeeds becauseSSL_write
correctly succeeds intls_tcp.c:305
. Then, intcp_estab_handler
theqent
element is derefed and removed fromconn->ql
. Thisqent
element contains the callback to thetransport_handler
in case there are any transport errors and after we have removedqent
, there is no reference to the transport handler anymore. Finally, we receive a TLSAlert
and the TCP connection is closed. Theconn->ql
is now empty and so inconn_close
there is no transport handler to call and the transport error can no longer be propagated upwards.This can be fixed by not derefing
qent
intransp.c
ifqent->qentp
is set. Because ifqent->qentp
is set, the caller ofsip_transp_send
will have a pointer toqent
and dereference it in its destructor (e.g. thectrans
destructor).I have tested this extensively manually in many different scenarios with valgrind and running BareSIP selftest.