mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-02 18:22:04 +00:00
BUG/MEDIUM: ssl/fd: unexpected fd close using async engine
Before 2.3, after an async crypto processing or on session close, the engine async file's descriptors were removed from the fdtab but not closed because it is the engine which has created the file descriptor, and it is responsible for closing it. In 2.3 the fd_remove() call was replaced by fd_stop_both() which stops the polling but does not remove the fd from the fdtab and the fd remains indefinitively in the fdtab. A simple replacement by fd_delete() is not a valid fix because fd_delete() removes the fd from the fdtab but also closes the fd. And the fd will be closed twice: by the haproxy's core and by the engine itself. Instead, let's set FD_DISOWN on the FD before calling fd_delete() which will take care of not closing it. This patch must be backported on branches >= 2.3, and it relies on this previous patch: MINOR: fd: add a new FD_DISOWN flag to prevent from closing a deleted FD As mentioned in the patch above, a different flag will be needed in 2.3.
This commit is contained in:
parent
f41a3f6762
commit
7d392a592d
@ -776,8 +776,14 @@ void ssl_async_fd_free(int fd)
|
||||
}
|
||||
|
||||
SSL_get_all_async_fds(ssl, all_fd, &num_all_fds);
|
||||
for (i=0 ; i < num_all_fds ; i++)
|
||||
fd_stop_both(all_fd[i]);
|
||||
for (i=0 ; i < num_all_fds ; i++) {
|
||||
/* We want to remove the fd from the fdtab
|
||||
* but we flag it to disown because the
|
||||
* close is performed by the engine itself
|
||||
*/
|
||||
fdtab[all_fd[i]].state |= FD_DISOWN;
|
||||
fd_delete(all_fd[i]);
|
||||
}
|
||||
|
||||
/* Now we can safely call SSL_free, no more pending job in engines */
|
||||
SSL_free(ssl);
|
||||
@ -807,8 +813,14 @@ static inline void ssl_async_process_fds(struct ssl_sock_ctx *ctx)
|
||||
SSL_get_changed_async_fds(ssl, add_fd, &num_add_fds, del_fd, &num_del_fds);
|
||||
|
||||
/* We remove unused fds from the fdtab */
|
||||
for (i=0 ; i < num_del_fds ; i++)
|
||||
fd_stop_both(del_fd[i]);
|
||||
for (i=0 ; i < num_del_fds ; i++) {
|
||||
/* We want to remove the fd from the fdtab
|
||||
* but we flag it to disown because the
|
||||
* close is performed by the engine itself
|
||||
*/
|
||||
fdtab[del_fd[i]].state |= FD_DISOWN;
|
||||
fd_delete(del_fd[i]);
|
||||
}
|
||||
|
||||
/* We add new fds to the fdtab */
|
||||
for (i=0 ; i < num_add_fds ; i++) {
|
||||
@ -6796,8 +6808,14 @@ void ssl_sock_close(struct connection *conn, void *xprt_ctx) {
|
||||
* because the fd is owned by the engine.
|
||||
* the engine is responsible to close
|
||||
*/
|
||||
for (i=0 ; i < num_all_fds ; i++)
|
||||
fd_stop_both(all_fd[i]);
|
||||
for (i=0 ; i < num_all_fds ; i++) {
|
||||
/* We want to remove the fd from the fdtab
|
||||
* but we flag it to disown because the
|
||||
* close is performed by the engine itself
|
||||
*/
|
||||
fdtab[all_fd[i]].state |= FD_DISOWN;
|
||||
fd_delete(all_fd[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
SSL_free(ctx->ssl);
|
||||
|
Loading…
Reference in New Issue
Block a user