MINOR: action: new '(http-request|tcp-request content) do-resolve' action

The 'do-resolve' action is an http-request or tcp-request content action
which allows to run DNS resolution at run time in HAProxy.
The name to be resolved can be picked up in the request sent by the
client and the result of the resolution is stored in a variable.
The time the resolution is being performed, the request is on pause.
If the resolution can't provide a suitable result, then the variable
will be empty. It's up to the admin to take decisions based on this
statement (return 503 to prevent loops).

Read carefully the documentation concerning this feature, to ensure your
setup is secure and safe to be used in production.

This patch creates a global counter to track various errors reported by
the action 'do-resolve'.
diff --git a/include/proto/action.h b/include/proto/action.h
index 19312db..d0b2c5d 100644
--- a/include/proto/action.h
+++ b/include/proto/action.h
@@ -24,6 +24,9 @@
 
 #include <types/action.h>
 
+int act_resolution_cb(struct dns_requester *requester, struct dns_nameserver *nameserver);
+int act_resolution_error_cb(struct dns_requester *requester, int error_code);
+
 static inline struct action_kw *action_lookup(struct list *keywords, const char *kw)
 {
 	struct action_kw_list *kw_list;
diff --git a/include/proto/dns.h b/include/proto/dns.h
index 3ad79c3..7ce5a09 100644
--- a/include/proto/dns.h
+++ b/include/proto/dns.h
@@ -22,9 +22,11 @@
 #ifndef _PROTO_DNS_H
 #define _PROTO_DNS_H
 
+#include <types/action.h>
 #include <types/dns.h>
 
 extern struct list dns_resolvers;
+extern unsigned int dns_failed_resolutions;
 
 struct dns_resolvers *find_resolvers_by_id(const char *id);
 struct dns_srvrq *find_srvrq_by_name(const char *name, struct proxy *px);
@@ -43,6 +45,8 @@
 int dns_link_resolution(void *requester, int requester_type, int requester_locked);
 void dns_unlink_resolution(struct dns_requester *requester);
 void dns_trigger_resolution(struct dns_requester *requester);
+enum act_parse_ret dns_parse_do_resolve(const char **args, int *orig_arg, struct proxy *px, struct act_rule *rule, char **err);
+int check_action_do_resolve(struct act_rule *rule, struct proxy *px, char **err);
 
 
 #endif // _PROTO_DNS_H
diff --git a/include/types/action.h b/include/types/action.h
index 0367ea9..6c5fccf 100644
--- a/include/types/action.h
+++ b/include/types/action.h
@@ -108,6 +108,13 @@
 	struct applet applet;                  /* used for the applet registration. */
 	union {
 		struct {
+			struct sample_expr *expr;
+			char *varname;
+			char *resolvers_id;
+			struct dns_resolvers *resolvers;
+			struct dns_options dns_opts;
+		} dns;                        /* dns resolution */
+		struct {
 			char *realm;
 		} auth;                        /* arg used by "auth" */
 		struct {
diff --git a/include/types/stats.h b/include/types/stats.h
index 043c377..648b032 100644
--- a/include/types/stats.h
+++ b/include/types/stats.h
@@ -312,6 +312,7 @@
 	INF_CONNECTED_PEERS,
 	INF_DROPPED_LOGS,
 	INF_BUSY_POLLING,
+	INF_FAILED_RESOLUTIONS,
 
 	/* must always be the last one */
 	INF_TOTAL_FIELDS
diff --git a/include/types/stream.h b/include/types/stream.h
index b6a3e84..96a0345 100644
--- a/include/types/stream.h
+++ b/include/types/stream.h
@@ -180,6 +180,15 @@
 	struct list *current_rule_list;         /* this is used to store the current executed rule list. */
 	void *current_rule;                     /* this is used to store the current rule to be resumed. */
 	struct hlua *hlua;                      /* lua runtime context */
+
+	/* Context */
+	struct {
+		struct dns_requester *dns_requester; /* owner of the resolution */
+		char *hostname_dn;              /* hostname being resolve, in domain name format */
+		int hostname_dn_len;            /* size of hostname_dn */
+		/* 4 unused bytes here */
+		struct act_rule *parent;        /* rule which requested this resolution */
+	} dns_ctx;                              /* context information for DNS resolution */
 };
 
 #endif /* _TYPES_STREAM_H */