MINOR: fd: add a new FD_DISOWN flag to prevent from closing a deleted FD

Some FDs might be offered to some external code (external libraries)
which will deal with them until they close them. As such we must not
close them upon fd_delete() but we need to delete them anyway so that
they do not appear anymore in the fdtab. This used to be handled by
fd_remove() before 2.3 but we don't have this anymore.

This patch introduces a new flag FD_DISOWN to let fd_delete() know that
the core doesn't own the fd and it must not be closed upon removal from
the fd_tab. This way it's totally unregistered from the poller but still
open.

This patch must be backported on branches >= 2.3 because it will be
needed to fix a bug affecting SSL async. it should be adapted on 2.3
because state flags were stored in a different way (via bits in the
structure).
diff --git a/include/haproxy/fd-t.h b/include/haproxy/fd-t.h
index 433a3f3..64416d6 100644
--- a/include/haproxy/fd-t.h
+++ b/include/haproxy/fd-t.h
@@ -69,6 +69,7 @@
 #define FD_ET_POSSIBLE_BIT 19  /* edge-triggered is possible on this FD */
 #define FD_EXPORTED_BIT    20  /* FD is exported and must not be closed */
 #define FD_EXCL_SYSCALL_BIT 21 /* a syscall claims exclusivity on this FD */
+#define FD_DISOWN_BIT      22  /* this fd will be closed by some external code */
 
 
 /* and flag values */
@@ -109,6 +110,7 @@
 #define FD_ET_POSSIBLE      (1U << FD_ET_POSSIBLE_BIT)
 #define FD_EXPORTED         (1U << FD_EXPORTED_BIT)
 #define FD_EXCL_SYSCALL     (1U << FD_EXCL_SYSCALL_BIT)
+#define FD_DISOWN           (1U << FD_DISOWN_BIT)
 
 /* FD update status after fd_update_events() */
 enum {
diff --git a/src/fd.c b/src/fd.c
index 4fbdaef..079df15 100644
--- a/src/fd.c
+++ b/src/fd.c
@@ -306,6 +306,9 @@
  */
 void _fd_delete_orphan(int fd)
 {
+	uint fd_disown;
+
+	fd_disown = fdtab[fd].state & FD_DISOWN;
 	if (fdtab[fd].state & FD_LINGER_RISK) {
 		/* this is generally set when connecting to servers */
 		DISGUISE(setsockopt(fd, SOL_SOCKET, SO_LINGER,
@@ -327,7 +330,8 @@
 	/* perform the close() call last as it's what unlocks the instant reuse
 	 * of this FD by any other thread.
 	 */
-	close(fd);
+	if (!fd_disown)
+		close(fd);
 	_HA_ATOMIC_DEC(&ha_used_fds);
 }