]>
git.saurik.com Git - apt.git/blob - apt-pkg/contrib/srvrec.cc
352a569704c23a5d41eeb5be8e3fc4b5d68f21d8
1 // -*- mode: cpp; mode: fold -*-
3 /* ######################################################################
7 ##################################################################### */
11 #include <netinet/in.h>
12 #include <arpa/nameser.h>
17 #include <apt-pkg/error.h>
20 bool GetSrvRecords(std::string name
, std::vector
<SrvRec
> &Result
)
22 unsigned char answer
[PACKETSZ
];
23 int answer_len
, compressed_name_len
;
27 return _error
->Errno("res_init", "Failed to init resolver");
29 answer_len
= res_query(name
.c_str(), C_IN
, T_SRV
, answer
, sizeof(answer
));
30 if (answer_len
< (int)sizeof(HEADER
))
31 return _error
->Warning("Not enough data from res_query (%i)", answer_len
);
34 HEADER
*header
= (HEADER
*)answer
;
35 if (header
->rcode
!= NOERROR
)
36 return _error
->Warning("res_query returned rcode %i", header
->rcode
);
37 answer_count
= ntohs(header
->ancount
);
38 if (answer_count
<= 0)
39 return _error
->Warning("res_query returned no answers (%i) ", answer_count
);
42 compressed_name_len
= dn_skipname(answer
+sizeof(HEADER
), answer
+answer_len
);
43 if(compressed_name_len
< 0)
44 return _error
->Warning("dn_skipname failed %i", compressed_name_len
);
46 // pt points to the first answer record, go over all of them now
47 unsigned char *pt
= answer
+sizeof(HEADER
)+compressed_name_len
+QFIXEDSZ
;
48 while ((int)Result
.size() < answer_count
&& pt
< answer
+answer_len
)
51 u_int16_t type
, klass
, priority
, weight
, port
, dlen
;
54 compressed_name_len
= dn_skipname(pt
, answer
+answer_len
);
55 if (compressed_name_len
< 0)
56 return _error
->Warning("dn_skipname failed (2): %i",
58 pt
+= compressed_name_len
;
59 if (((answer
+answer_len
) - pt
) < 16)
60 return _error
->Warning("packet too short");
62 // extract the data out of the result buffer
63 #define extract_u16(target, p) target = *p++ << 8; target |= *p++;
65 extract_u16(type
, pt
);
67 return _error
->Warning("Unexpected type excepted %x != %x",
69 extract_u16(klass
, pt
);
71 return _error
->Warning("Unexpected class excepted %x != %x",
74 extract_u16(dlen
, pt
);
75 extract_u16(priority
, pt
);
76 extract_u16(weight
, pt
);
77 extract_u16(port
, pt
);
81 compressed_name_len
= dn_expand(answer
, answer
+answer_len
, pt
, buf
, sizeof(buf
));
82 if(compressed_name_len
< 0)
83 return _error
->Warning("dn_expand failed %i", compressed_name_len
);
84 pt
+= compressed_name_len
;
86 // add it to our class
87 rec
.priority
= priority
;
91 Result
.push_back(rec
);
95 std::stable_sort(Result
.begin(), Result
.end());
97 // FIXME: implement weight selection as specified in RFC-2782