Add a shutdown method to luasec. This is needed to do a nonblocking

shutdown of the TLS connection, which is observed as a hang in prosody.
Prosody already has its part incorperated in version 13.0.

OK tb@ caspar@
Go ahead lucas@
This commit is contained in:
martijn
2025-05-29 19:53:24 +00:00
parent 69050275cd
commit b4c26d7403
4 changed files with 112 additions and 0 deletions
+1
View File
@@ -3,6 +3,7 @@ COMMENT= lua binding to OpenSSL to provide TLS/SSL communication
GH_ACCOUNT= brunoos
GH_PROJECT= luasec
GH_TAGNAME= v1.2.0
REVISION= 0
CATEGORIES= security
@@ -0,0 +1,12 @@
https://github.com/lunarmodules/luasec/pull/203
Index: src/luasocket/usocket.c
--- src/luasocket/usocket.c.orig
+++ src/luasocket/usocket.c
@@ -82,7 +82,6 @@ int socket_close(void) {
\*-------------------------------------------------------------------------*/
void socket_destroy(p_socket ps) {
if (*ps != SOCKET_INVALID) {
- socket_setblocking(ps);
close(*ps);
*ps = SOCKET_INVALID;
}
+87
View File
@@ -0,0 +1,87 @@
https://github.com/lunarmodules/luasec/pull/203
Index: src/ssl.c
--- src/ssl.c.orig
+++ src/ssl.c
@@ -87,7 +87,8 @@ static int meth_destroy(lua_State *L)
{
p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
if (ssl->state == LSEC_STATE_CONNECTED) {
- socket_setblocking(&ssl->sock);
+ if (!ssl->shutdown)
+ socket_setblocking(&ssl->sock);
SSL_shutdown(ssl->ssl);
}
if (ssl->sock != SOCKET_INVALID) {
@@ -305,6 +306,7 @@ static int meth_create(lua_State *L)
return luaL_argerror(L, 1, "invalid context");
}
ssl->state = LSEC_STATE_NEW;
+ ssl->shutdown = 0;
SSL_set_fd(ssl->ssl, (int)SOCKET_INVALID);
SSL_set_mode(ssl->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE |
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
@@ -341,6 +343,56 @@ static int meth_receive(lua_State *L) {
}
/**
+ * SSL shutdown function
+ */
+static int meth_shutdown(lua_State *L) {
+ p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
+ int err;
+ p_timeout tm = timeout_markstart(&ssl->tm);
+
+ ssl->shutdown = 1;
+ if (ssl->state == LSEC_STATE_CLOSED) {
+ lua_pushboolean(L, 1);
+ return 1;
+ }
+
+ err = SSL_shutdown(ssl->ssl);
+ switch (err) {
+ case 0:
+ lua_pushboolean(L, 0);
+ lua_pushnil(L);
+ return 2;
+ case 1:
+ lua_pushboolean(L, 1);
+ lua_pushnil(L);
+ ssl->state = LSEC_STATE_CLOSED;
+ return 2;
+ case -1:
+ lua_pushboolean(L, 0);
+ ssl->error = SSL_get_error(ssl->ssl, err);
+ switch (ssl->error) {
+ case SSL_ERROR_WANT_READ:
+ err = socket_waitfd(&ssl->sock, WAITFD_R, tm);
+ lua_pushstring(L, ssl_ioerror((void *)ssl, err == IO_TIMEOUT ? LSEC_IO_SSL : err));
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ err = socket_waitfd(&ssl->sock, WAITFD_W, tm);
+ lua_pushstring(L, ssl_ioerror((void *)ssl, err == IO_TIMEOUT ? LSEC_IO_SSL : err));
+ break;
+ case SSL_ERROR_SYSCALL:
+ if (ERR_peek_error())
+ ssl->error = SSL_ERROR_SSL;
+ lua_pushstring(L, ssl_ioerror((void *)ssl, LSEC_IO_SSL));
+ break;
+ default:
+ lua_pushstring(L, ssl_ioerror((void *)ssl, LSEC_IO_SSL));
+ break;
+ }
+ return 2;
+ }
+}
+
+/**
* Get the buffer's statistics.
*/
static int meth_getstats(lua_State *L) {
@@ -904,6 +956,7 @@ static int meth_tlsa(lua_State *L)
*/
static luaL_Reg methods[] = {
{"close", meth_close},
+ {"shutdown", meth_shutdown},
{"getalpn", meth_getalpn},
{"getfd", meth_getfd},
{"getfinished", meth_getfinished},
+12
View File
@@ -0,0 +1,12 @@
https://github.com/lunarmodules/luasec/pull/203
Index: src/ssl.h
--- src/ssl.h.orig
+++ src/ssl.h
@@ -32,6 +32,7 @@ typedef struct t_ssl_ {
t_timeout tm;
SSL *ssl;
int state;
+ int shutdown;
int error;
} t_ssl;
typedef t_ssl* p_ssl;