[MEDIUM] proxy: add a PAUSED state to listeners and move socket tricks out of proxy.c

Managing listeners state is difficult because they have their own state
and can at the same time have theirs dictated by their proxy. The pause
is not done properly, as the proxy code is fiddling with sockets. By
introducing new functions such as pause_listener()/resume_listener(), we
make it a bit more obvious how/when they're supposed to be used. The
listen_proxies() function was also renamed to resume_proxies() since
it's only used for pause/resume.

This patch is the first in a series aiming at getting rid of the maintain_proxies
mess. In the end, proxies should not call enable_listener()/disable_listener()
anymore.
diff --git a/include/proto/protocols.h b/include/proto/protocols.h
index d0364c0..e0d6ee4 100644
--- a/include/proto/protocols.h
+++ b/include/proto/protocols.h
@@ -36,6 +36,21 @@
  */
 void disable_listener(struct listener *listener);
 
+/* This function tries to temporarily disable a listener, depending on the OS
+ * capabilities. Linux unbinds the listen socket after a SHUT_RD, and ignores
+ * SHUT_WR. Solaris refuses either shutdown(). OpenBSD ignores SHUT_RD but
+ * closes upon SHUT_WR and refuses to rebind. So a common validation path
+ * involves SHUT_WR && listen && SHUT_RD. In case of success, the FD's polling
+ * is disabled. It normally returns non-zero, unless an error is reported.
+ */
+int pause_listener(struct listener *l);
+
+/* This function tries to resume a temporarily disabled listener.
+ * The resulting state will either be LI_READY or LI_FULL. 0 is returned
+ * in case of failure to resume (eg: dead socket).
+ */
+int resume_listener(struct listener *l);
+
 /* This function adds all of the protocol's listener's file descriptors to the
  * polling lists when they are in the LI_LISTEN state. It is intended to be
  * used as a protocol's generic enable_all() primitive, for use after the
diff --git a/include/proto/proxy.h b/include/proto/proxy.h
index ed29f14..c9bfc02 100644
--- a/include/proto/proxy.h
+++ b/include/proto/proxy.h
@@ -34,7 +34,7 @@
 void pause_proxy(struct proxy *p);
 void stop_proxy(struct proxy *p);
 void pause_proxies(void);
-void listen_proxies(void);
+void resume_proxies(void);
 int  session_set_backend(struct session *s, struct proxy *be);
 
 const char *proxy_cap_str(int cap);
diff --git a/include/types/protocols.h b/include/types/protocols.h
index 3dcb2e7..a333ea2 100644
--- a/include/types/protocols.h
+++ b/include/types/protocols.h
@@ -1,23 +1,23 @@
 /*
-  include/types/protocols.h
-  This file defines the structures used by generic network protocols.
-
-  Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation, version 2.1
-  exclusively.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-*/
+ * include/types/protocols.h
+ * This file defines the structures used by generic network protocols.
+ *
+ * Copyright (C) 2000-2011 Willy Tarreau - w@1wt.eu
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, version 2.1
+ * exclusively.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
 
 #ifndef _TYPES_PROTOCOLS_H
 #define _TYPES_PROTOCOLS_H
@@ -38,12 +38,15 @@
 #define PROTO_NAME_LEN 16
 
 /* listener state */
-#define LI_NEW		0	/* not initialized yet */
-#define LI_INIT		1	/* all parameters filled in, but not assigned yet */
-#define LI_ASSIGNED	2	/* assigned to the protocol, but not listening yet */
-#define LI_LISTEN	3	/* started, listening but not enabled */
-#define LI_READY	4	/* started, listening and enabled */
-#define LI_FULL		5	/* reached its connection limit */
+enum {
+	LI_NEW	= 0,    /* not initialized yet */
+	LI_INIT,        /* all parameters filled in, but not assigned yet */
+	LI_ASSIGNED,    /* assigned to the protocol, but not listening yet */
+	LI_PAUSED,      /* listener was paused, it's bound but not listening  */
+	LI_LISTEN,      /* started, listening but not enabled */
+	LI_READY,       /* started, listening and enabled */
+	LI_FULL,        /* reached its connection limit */
+};
 
 /* Listener transitions
  * calloc()     set()      add_listener()       bind()