Clears SSL error state.
Updates tport_tls.c to clear the SSL error state after an error occurs.
OpenSSL puts errors into a queue that is kept in thread local storage.
In some cases, such as when SSL_ERROR_SSL is returned by SSL_get_errror(),
OpenSSL will queue multiple errors for a single event. When this occurs,
OpenSSL will report an error the next time I/O is performed if the queue
is not cleared first, which can result in TLS connections being torn down
prematurely.
This fixes the following compile-time warning:
cc1: note: someone does not honour COPTS correctly, passed 2 times
LTCOMPILE tport_type_connect.lo
cc1: note: someone does not honour COPTS correctly, passed 2 times
LTCOMPILE tport_type_ws.lo
cc1: note: someone does not honour COPTS correctly, passed 2 times
LTCOMPILE ws.lo
cc1: note: someone does not honour COPTS correctly, passed 2 times
ws.c: In function 'hton64':
ws.c:730:14: error: implicit declaration of function '__bswap_64' [-Werror=implicit-function-declaration]
else return __bswap_64(val);
^
cc1: all warnings being treated as errors
Makefile:1465: recipe for target 'ws.lo' failed
make[12]: *** [ws.lo] Error 1
Fix by including byteswap.h, which is available on Linux and also
everywhere glibc is used (wpa_supplicant includes this header the same
way).
Signed-off-by: Sebastian Kemper <sebastian_ml@gmx.net>
Sofia will unpredictably close a tls transport during call setup. This
occurs when the epoll event loop wakes up the socket reader and SSL_read
returns an error because there is no packet on the socket. Normally
sofia will read the last error using SSL_get_error and return
SSL_ERROR_WANT_READ. Sofia gracefully handles this error and the
transport stays open. Sometimes, however, the worker thread will call
SSL_shutdown for a different transport, which can write an error to the
internal openssl error queue. If that error is not read off the queue,
the next time that SSL_get_error is called, it will read that unrelated
error.
The documentation for SSL_shutdown explains that there are three
possible results -1, 0 and 1 with, oddly, 1 indicating success. The -1
result code occurs when there is no handshake callback registered on the
connection. It can return 0 when there is still work to be done. The
documentation suggest that it is insufficient to call it just once. This
is why I added the do {} while () construct.
Although just the fix to SSL_shutdown was enough to resolve my issue, I
a also audited other calls to SSL_* functions and found a few other
cases where an error may be generated, but was not handled.