From 978227dcd225948d58fdb00b501da7e8c230f9fd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Thu, 1 Aug 2013 16:15:58 +0200
Subject: [PATCH 2/5] fo_discover_srv_send: allow custom ordering function

https://fedorahosted.org/sssd/ticket/2001
---
 src/providers/ad/ad_srv.c     |  5 +++--
 src/providers/fail_over_srv.c | 35 +++++++++++++++++++++++++++++------
 src/providers/fail_over_srv.h | 19 +++++++++++++++++--
 src/providers/ipa/ipa_srv.c   |  3 ++-
 4 files changed, 51 insertions(+), 11 deletions(-)

diff --git a/src/providers/ad/ad_srv.c b/src/providers/ad/ad_srv.c
index 861ae3dbd3dba9ea00449b6d1dd1a02baa094917..dfb15b30c634f2fc672d1072425dc48bdf6b7740 100644
--- a/src/providers/ad/ad_srv.c
+++ b/src/providers/ad/ad_srv.c
@@ -79,7 +79,7 @@ static struct tevent_req *ad_get_dc_servers_send(TALLOC_CTX *mem_ctx,
                               domain));
 
     subreq = fo_discover_srv_send(state, ev, resolv_ctx,
-                                  "ldap", FO_PROTO_TCP, domains);
+                                  "ldap", FO_PROTO_TCP, domains, NULL, NULL);
     if (subreq == NULL) {
         ret = ENOMEM;
         goto immediately;
@@ -719,7 +719,8 @@ static void ad_srv_plugin_site_done(struct tevent_req *subreq)
     subreq = fo_discover_servers_send(state, state->ev,
                                       state->ctx->be_res->resolv,
                                       state->service, state->protocol,
-                                      primary_domain, backup_domain);
+                                      primary_domain, backup_domain,
+                                      NULL, NULL);
     if (subreq == NULL) {
         ret = ENOMEM;
         goto done;
diff --git a/src/providers/fail_over_srv.c b/src/providers/fail_over_srv.c
index 7fca2668977a2231c7669f6b4b8302876712e95d..e374604ab2e3f0001a36ec1839417e6d43f8f7fa 100644
--- a/src/providers/fail_over_srv.c
+++ b/src/providers/fail_over_srv.c
@@ -27,6 +27,9 @@
 #include "providers/fail_over_srv.h"
 
 struct fo_discover_srv_state {
+    fo_sort_srv_list_t sort_srv_fn;
+    void *sort_srv_pvt;
+
     char *dns_domain;
     struct fo_server_info *servers;
     size_t num_servers;
@@ -39,7 +42,9 @@ struct tevent_req *fo_discover_srv_send(TALLOC_CTX *mem_ctx,
                                         struct resolv_ctx *resolv_ctx,
                                         const char *service,
                                         const char *protocol,
-                                        const char **discovery_domains)
+                                        const char **discovery_domains,
+                                        fo_sort_srv_list_t sort_srv_fn,
+                                        void *sort_srv_pvt)
 {
     struct fo_discover_srv_state *state = NULL;
     struct tevent_req *req = NULL;
@@ -52,6 +57,9 @@ struct tevent_req *fo_discover_srv_send(TALLOC_CTX *mem_ctx,
         return NULL;
     }
 
+    state->sort_srv_fn = sort_srv_fn;
+    state->sort_srv_pvt = sort_srv_pvt;
+
     subreq = resolv_discover_srv_send(state, ev, resolv_ctx, service,
                                       protocol, discovery_domains);
     if (subreq == NULL) {
@@ -98,7 +106,11 @@ static void fo_discover_srv_done(struct tevent_req *subreq)
     DEBUG(SSSDBG_TRACE_FUNC, ("Got answer. Processing...\n"));
 
     /* sort and store the answer */
-    ret = resolv_sort_srv_reply(&reply_list);
+    if (state->sort_srv_fn == NULL) {
+        ret = resolv_sort_srv_reply(&reply_list);
+    } else {
+        ret = state->sort_srv_fn(&reply_list, state->sort_srv_pvt);
+    }
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE, ("Could not sort the answers from DNS "
                                     "[%d]: %s\n", ret, strerror(ret)));
@@ -172,6 +184,8 @@ struct fo_discover_servers_state {
     const char *protocol;
     const char *primary_domain;
     const char *backup_domain;
+    fo_sort_srv_list_t sort_srv_fn;
+    void *sort_srv_pvt;
 
     char *dns_domain;
     struct fo_server_info *primary_servers;
@@ -189,7 +203,9 @@ struct tevent_req *fo_discover_servers_send(TALLOC_CTX *mem_ctx,
                                             const char *service,
                                             const char *protocol,
                                             const char *primary_domain,
-                                            const char *backup_domain)
+                                            const char *backup_domain,
+                                            fo_sort_srv_list_t sort_srv_fn,
+                                            void *sort_srv_pvt)
 {
     struct fo_discover_servers_state *state = NULL;
     struct tevent_req *req = NULL;
@@ -222,6 +238,8 @@ struct tevent_req *fo_discover_servers_send(TALLOC_CTX *mem_ctx,
 
     state->ev = ev;
     state->resolv_ctx = resolv_ctx;
+    state->sort_srv_fn = sort_srv_fn;
+    state->sort_srv_pvt = sort_srv_pvt;
 
     state->service = talloc_strdup(state, service);
     if (state->service == NULL) {
@@ -259,7 +277,9 @@ struct tevent_req *fo_discover_servers_send(TALLOC_CTX *mem_ctx,
     domains[1] = state->backup_domain;
 
     subreq = fo_discover_srv_send(state, ev, resolv_ctx,
-                                  state->service, state->protocol, domains);
+                                  state->service, state->protocol,
+                                  domains, state->sort_srv_fn,
+                                  state->sort_srv_pvt);
     if (subreq == NULL) {
         ret = ENOMEM;
         goto immediately;
@@ -326,7 +346,9 @@ static void fo_discover_servers_primary_done(struct tevent_req *subreq)
     domains[0] = state->backup_domain;
 
     subreq = fo_discover_srv_send(state, state->ev, state->resolv_ctx,
-                                  state->service, state->protocol, domains);
+                                  state->service, state->protocol,
+                                  domains, state->sort_srv_fn,
+                                  state->sort_srv_pvt);
     if (subreq == NULL) {
         ret = ENOMEM;
         goto done;
@@ -612,7 +634,8 @@ static errno_t fo_resolve_srv_dns_discover(struct tevent_req *req)
     }
 
     subreq = fo_discover_srv_send(state, state->ev, ctx->resolv_ctx,
-                                  state->service, state->protocol, domains);
+                                  state->service, state->protocol, domains,
+                                  NULL, NULL);
     if (subreq == NULL) {
         ret = ENOMEM;
         goto done;
diff --git a/src/providers/fail_over_srv.h b/src/providers/fail_over_srv.h
index 0c824f46386e07bb76f57064c07d028e9013b355..4d9f0c94cf624ea5899715d05e809e0849418eca 100644
--- a/src/providers/fail_over_srv.h
+++ b/src/providers/fail_over_srv.h
@@ -69,12 +69,25 @@ typedef errno_t
                                struct fo_server_info **_backup_servers,
                                size_t *_num_backup_servers);
 
+/*
+ * in/out list - list of SRV records
+ * in pvt - private data
+ *
+ * Returns:
+ *   EOK - if successful
+ *   other code on error
+ */
+typedef errno_t
+(*fo_sort_srv_list_t)(struct ares_srv_reply **list, void *pvt);
+
 struct tevent_req *fo_discover_srv_send(TALLOC_CTX *mem_ctx,
                                         struct tevent_context *ev,
                                         struct resolv_ctx *resolv_ctx,
                                         const char *service,
                                         const char *protocol,
-                                        const char **discovery_domains);
+                                        const char **discovery_domains,
+                                        fo_sort_srv_list_t sort_srv_fn,
+                                        void *sort_srv_pvt);
 
 errno_t fo_discover_srv_recv(TALLOC_CTX *mem_ctx,
                              struct tevent_req *req,
@@ -88,7 +101,9 @@ struct tevent_req *fo_discover_servers_send(TALLOC_CTX *mem_ctx,
                                             const char *service,
                                             const char *protocol,
                                             const char *primary_domain,
-                                            const char *backup_domain);
+                                            const char *backup_domain,
+                                            fo_sort_srv_list_t sort_srv_fn,
+                                            void *sort_srv_pvt);
 
 errno_t fo_discover_servers_recv(TALLOC_CTX *mem_ctx,
                                  struct tevent_req *req,
diff --git a/src/providers/ipa/ipa_srv.c b/src/providers/ipa/ipa_srv.c
index 9b1c39945aac422360467a8291d6d138f0b64062..ea0d2cd58bf9e2b1b97eb6f384d139f4558ac7bc 100644
--- a/src/providers/ipa/ipa_srv.c
+++ b/src/providers/ipa/ipa_srv.c
@@ -136,7 +136,8 @@ struct tevent_req *ipa_srv_plugin_send(TALLOC_CTX *mem_ctx,
                               "backup servers\n"));
 
     subreq = fo_discover_servers_send(state, ev, ctx->resolv_ctx, service,
-                                      protocol, primary_domain, backup_domain);
+                                      protocol, primary_domain, backup_domain,
+                                      NULL, NULL);
     if (subreq == NULL) {
         ret = ENOMEM;
         goto immediately;
-- 
1.7.11.7

