56
getsrv(const char *name,struct srventry **list)
63
getsrv (const char *name,struct srventry **list)
58
unsigned char answer[2048];
60
unsigned char *pt,*emsg;
62
HEADER *header=(HEADER *)answer;
66
r=res_query(name,C_IN,T_SRV,answer,2048);
67
if(r<sizeof(HEADER) || r>2048)
70
if(header->rcode==NOERROR && (count=ntohs(header->ancount)))
75
pt=&answer[sizeof(HEADER)];
77
/* Skip over the query */
79
rc=dn_skipname(pt,emsg);
85
while(count-->0 && pt<emsg)
87
struct srventry *srv=NULL;
90
*list=xrealloc(*list,(srvcount+1)*sizeof(struct srventry));
91
memset(&(*list)[srvcount],0,sizeof(struct srventry));
92
srv=&(*list)[srvcount];
95
rc=dn_skipname(pt,emsg); /* the name we just queried for */
100
/* Truncated message? */
106
/* We asked for SRV and got something else !? */
112
/* We asked for IN and got something else !? */
119
srv->priority=*pt++ << 8;
120
srv->priority|=*pt++;
121
srv->weight=*pt++ << 8;
123
srv->port=*pt++ << 8;
126
/* Get the name. 2782 doesn't allow name compression, but
127
dn_expand still works to pull the name out of the
129
rc=dn_expand(answer,emsg,pt,srv->target,MAXDNAME);
130
if(rc==1 && srv->target[0]==0) /* "." */
135
/* Corrupt packet? */
140
printf("count=%d\n",srvcount);
141
printf("priority=%d\n",srv->priority);
142
printf("weight=%d\n",srv->weight);
143
printf("port=%d\n",srv->port);
144
printf("target=%s\n",srv->target);
148
/* Now we have an array of all the srv records. */
150
/* Order by priority */
151
qsort(*list,srvcount,sizeof(struct srventry),priosort);
153
/* For each priority, move the zero-weighted items first. */
154
for(i=0;i<srvcount;i++)
158
for(j=i;j<srvcount && (*list)[i].priority==(*list)[j].priority;j++)
160
if((*list)[j].weight==0)
165
struct srventry temp;
167
memcpy(&temp,&(*list)[j],sizeof(struct srventry));
168
memcpy(&(*list)[j],&(*list)[i],sizeof(struct srventry));
169
memcpy(&(*list)[i],&temp,sizeof(struct srventry));
177
/* Run the RFC-2782 weighting algorithm. We don't need very
178
high quality randomness for this, so regular libc srand/rand
180
srand(time(NULL)*getpid());
182
for(i=0;i<srvcount;i++)
185
float prio_count=0,chose;
187
for(j=i;j<srvcount && (*list)[i].priority==(*list)[j].priority;j++)
189
prio_count+=(*list)[j].weight;
190
(*list)[j].run_count=prio_count;
193
chose=prio_count*rand()/RAND_MAX;
195
for(j=i;j<srvcount && (*list)[i].priority==(*list)[j].priority;j++)
197
if(chose<=(*list)[j].run_count)
202
struct srventry temp;
204
memcpy(&temp,&(*list)[j],sizeof(struct srventry));
205
memcpy(&(*list)[j],&(*list)[i],sizeof(struct srventry));
206
memcpy(&(*list)[i],&temp,sizeof(struct srventry));
74
adns_answer *answer = NULL;
76
rc = adns_init (&state, adns_if_noerrprint, NULL);
79
log_error ("error initializing adns: %s\n", strerror (errno));
83
rc = adns_synchronous (state, name, adns_r_srv, adns_qf_quoteok_query,
87
log_error ("DNS query failed: %s\n", strerror (errno));
91
if (answer->status != adns_s_ok
92
|| answer->type != adns_r_srv || !answer->nrrs)
94
/* log_error ("DNS query returned an error or no records: %s (%s)\n", */
95
/* adns_strerror (answer->status), */
96
/* adns_errabbrev (answer->status)); */
102
for (count = 0; count < answer->nrrs; count++)
104
struct srventry *srv = NULL;
105
struct srventry *newlist;
107
if (strlen (answer->rrs.srvha[count].ha.host) >= MAXDNAME)
109
log_info ("hostname in SRV record too long - skipped\n");
113
newlist = xtryrealloc (*list, (srvcount+1)*sizeof(struct srventry));
117
memset (&(*list)[srvcount], 0, sizeof(struct srventry));
118
srv = &(*list)[srvcount];
121
srv->priority = answer->rrs.srvha[count].priority;
122
srv->weight = answer->rrs.srvha[count].weight;
123
srv->port = answer->rrs.srvha[count].port;
124
strcpy (srv->target, answer->rrs.srvha[count].ha.host);
132
unsigned char answer[2048];
133
HEADER *header = (HEADER *)answer;
134
unsigned char *pt, *emsg;
138
r = res_query (name, C_IN, T_SRV, answer, sizeof answer);
139
if (r < sizeof (HEADER) || r > sizeof answer)
141
if (header->rcode != NOERROR || !(count=ntohs (header->ancount)))
142
return 0; /* Error or no record found. */
145
pt = &answer[sizeof(HEADER)];
147
/* Skip over the query */
148
rc = dn_skipname (pt, emsg);
154
while (count-- > 0 && pt < emsg)
156
struct srventry *srv=NULL;
158
struct srventry *newlist;
160
newlist = xtryrealloc (*list, (srvcount+1)*sizeof(struct srventry));
164
memset(&(*list)[srvcount],0,sizeof(struct srventry));
165
srv=&(*list)[srvcount];
168
rc = dn_skipname(pt,emsg); /* the name we just queried for */
173
/* Truncated message? */
179
/* We asked for SRV and got something else !? */
185
/* We asked for IN and got something else !? */
192
srv->priority=*pt++ << 8;
193
srv->priority|=*pt++;
194
srv->weight=*pt++ << 8;
196
srv->port=*pt++ << 8;
199
/* Get the name. 2782 doesn't allow name compression, but
200
dn_expand still works to pull the name out of the
202
rc = dn_expand(answer,emsg,pt,srv->target,MAXDNAME);
203
if (rc == 1 && srv->target[0] == 0) /* "." */
212
/* Corrupt packet? */
219
/* Now we have an array of all the srv records. */
221
/* Order by priority */
222
qsort(*list,srvcount,sizeof(struct srventry),priosort);
224
/* For each priority, move the zero-weighted items first. */
225
for (i=0; i < srvcount; i++)
229
for (j=i;j < srvcount && (*list)[i].priority == (*list)[j].priority; j++)
231
if((*list)[j].weight==0)
236
struct srventry temp;
238
memcpy (&temp,&(*list)[j],sizeof(struct srventry));
239
memcpy (&(*list)[j],&(*list)[i],sizeof(struct srventry));
240
memcpy (&(*list)[i],&temp,sizeof(struct srventry));
248
/* Run the RFC-2782 weighting algorithm. We don't need very high
249
quality randomness for this, so regular libc srand/rand is
250
sufficient. Fixme: It is a bit questionaly to reinitalize srand
251
- better use a gnupg fucntion for this. */
252
srand(time(NULL)*getpid());
254
for (i=0; i < srvcount; i++)
257
float prio_count=0,chose;
259
for (j=i; j < srvcount && (*list)[i].priority == (*list)[j].priority; j++)
261
prio_count+=(*list)[j].weight;
262
(*list)[j].run_count=prio_count;
265
chose=prio_count*rand()/RAND_MAX;
267
for (j=i;j<srvcount && (*list)[i].priority==(*list)[j].priority;j++)
269
if (chose<=(*list)[j].run_count)
274
struct srventry temp;
276
memcpy(&temp,&(*list)[j],sizeof(struct srventry));
277
memcpy(&(*list)[j],&(*list)[i],sizeof(struct srventry));
278
memcpy(&(*list)[i],&temp,sizeof(struct srventry));