/[smeserver]/rpms/openldap/sme9/openldap-dns-priority.patch
ViewVC logotype

Contents of /rpms/openldap/sme9/openldap-dns-priority.patch

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (show annotations) (download)
Tue Nov 11 00:46:15 2014 UTC (10 years ago) by vip-ire
Branch: MAIN
CVS Tags: openldap-2_4_39-8_el6_sme, HEAD
Import openldap

1 Implement priority/weight for DNS SRV records
2
3 From RFC 2782:
4
5 A client MUST attempt to contact the target host with the
6 lowest-numbered priority it can reach.
7
8 This patch sorts the DNS SRV records by their priority, and
9 additionally gives records with a larger weight a higher probability
10 of appearing earlier. This way, the DNS SRV records are tried in the
11 order of their priority.
12
13 Author: James M Leddy <james.leddy@redhat.com>
14 Upstream ITS: #7027
15 Resolves: #733078
16
17 ---
18 libraries/libldap/dnssrv.c | 106 ++++++++++++++++++++++++++++++++++----------
19 1 files changed, 83 insertions(+), 23 deletions(-)
20
21 diff --git a/libraries/libldap/dnssrv.c b/libraries/libldap/dnssrv.c
22 index 16b1544..40f93b4 100644
23 --- a/libraries/libldap/dnssrv.c
24 +++ b/libraries/libldap/dnssrv.c
25 @@ -174,6 +174,46 @@ int ldap_domain2dn(
26 return LDAP_SUCCESS;
27 }
28
29 +#ifdef HAVE_RES_QUERY
30 +#define DNSBUFSIZ (64*1024)
31 +typedef struct srv_record {
32 + u_short priority;
33 + u_short weight;
34 + u_short port;
35 + char hostname[DNSBUFSIZ];
36 +} srv_record;
37 +
38 +
39 +static int srv_cmp(const void *aa, const void *bb){
40 + srv_record *a=(srv_record *)aa;
41 + srv_record *b=(srv_record *)bb;
42 + u_long total;
43 +
44 + if(a->priority < b->priority) {
45 + return -1;
46 + }
47 + if(a->priority > b->priority) {
48 + return 1;
49 + }
50 + if(a->priority == b->priority){
51 + /* targets with same priority are in psudeo random order */
52 + if (a->weight == 0 && b->weight == 0) {
53 + if (rand() % 2) {
54 + return -1;
55 + } else {
56 + return 1;
57 + }
58 + }
59 + total = a->weight + b->weight;
60 + if (rand() % total < a->weight) {
61 + return -1;
62 + } else {
63 + return 1;
64 + }
65 + }
66 +}
67 +#endif /* HAVE_RES_QUERY */
68 +
69 /*
70 * Lookup and return LDAP servers for domain (using the DNS
71 * SRV record _ldap._tcp.domain).
72 @@ -183,15 +223,16 @@ int ldap_domain2hostlist(
73 char **list )
74 {
75 #ifdef HAVE_RES_QUERY
76 -#define DNSBUFSIZ (64*1024)
77 - char *request;
78 - char *hostlist = NULL;
79 + char *request;
80 + char *hostlist = NULL;
81 + srv_record *hostent_head=NULL;
82 + int i;
83 int rc, len, cur = 0;
84 unsigned char reply[DNSBUFSIZ];
85 + int hostent_count=0;
86
87 assert( domain != NULL );
88 assert( list != NULL );
89 -
90 if( *domain == '\0' ) {
91 return LDAP_PARAM_ERROR;
92 }
93 @@ -223,8 +264,7 @@ int ldap_domain2hostlist(
94 unsigned char *p;
95 char host[DNSBUFSIZ];
96 int status;
97 - u_short port;
98 - /* int priority, weight; */
99 + u_short port, priority, weight;
100
101 /* Parse out query */
102 p = reply;
103 @@ -263,40 +303,56 @@ int ldap_domain2hostlist(
104 size = (p[0] << 8) | p[1];
105 p += 2;
106 if (type == T_SRV) {
107 - int buflen;
108 status = dn_expand(reply, reply + len, p + 6, host, sizeof(host));
109 if (status < 0) {
110 goto out;
111 }
112 - /* ignore priority and weight for now */
113 - /* priority = (p[0] << 8) | p[1]; */
114 - /* weight = (p[2] << 8) | p[3]; */
115 +
116 + /* Get priority weight and port */
117 + priority = (p[0] << 8) | p[1];
118 + weight = (p[2] << 8) | p[3];
119 port = (p[4] << 8) | p[5];
120
121 if ( port == 0 || host[ 0 ] == '\0' ) {
122 goto add_size;
123 }
124
125 - buflen = strlen(host) + STRLENOF(":65355 ");
126 - hostlist = (char *) LDAP_REALLOC(hostlist, cur + buflen + 1);
127 - if (hostlist == NULL) {
128 - rc = LDAP_NO_MEMORY;
129 - goto out;
130 + hostent_head = (srv_record *) LDAP_REALLOC(hostent_head, (hostent_count+1)*(sizeof(srv_record)));
131 + if(hostent_head==NULL){
132 + rc=LDAP_NO_MEMORY;
133 + goto out;
134 +
135 }
136 - if (cur > 0) {
137 - /* not first time around */
138 - hostlist[cur++] = ' ';
139 - }
140 - cur += sprintf(&hostlist[cur], "%s:%hu", host, port);
141 + hostent_head[hostent_count].priority=priority;
142 + hostent_head[hostent_count].weight=weight;
143 + hostent_head[hostent_count].port=port;
144 + strncpy(hostent_head[hostent_count].hostname, host,255);
145 + hostent_count=hostent_count+1;
146 }
147 add_size:;
148 p += size;
149 }
150 }
151 + qsort(hostent_head, hostent_count, sizeof(srv_record), srv_cmp);
152 +
153 + for(i=0; i<hostent_count; i++){
154 + int buflen;
155 + buflen = strlen(hostent_head[i].hostname) + STRLENOF(":65355" );
156 + hostlist = (char *) LDAP_REALLOC(hostlist, cur+buflen+1);
157 + if (hostlist == NULL) {
158 + rc = LDAP_NO_MEMORY;
159 + goto out;
160 + }
161 + if(cur>0){
162 + hostlist[cur++]=' ';
163 + }
164 + cur += sprintf(&hostlist[cur], "%s:%hd", hostent_head[i].hostname, hostent_head[i].port);
165 + }
166 +
167 if (hostlist == NULL) {
168 - /* No LDAP servers found in DNS. */
169 - rc = LDAP_UNAVAILABLE;
170 - goto out;
171 + /* No LDAP servers found in DNS. */
172 + rc = LDAP_UNAVAILABLE;
173 + goto out;
174 }
175
176 rc = LDAP_SUCCESS;
177 @@ -308,8 +364,12 @@ add_size:;
178 if (request != NULL) {
179 LDAP_FREE(request);
180 }
181 + if (hostent_head != NULL) {
182 + LDAP_FREE(hostent_head);
183 + }
184 if (rc != LDAP_SUCCESS && hostlist != NULL) {
185 LDAP_FREE(hostlist);
186 +
187 }
188 return rc;
189 #else
190 --
191 1.7.6
192

admin@koozali.org
ViewVC Help
Powered by ViewVC 1.2.1 RSS 2.0 feed