this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Support getaddrinfo() in darling-resolver

+159 -5
+159 -5
src/libinfo/darling-resolver/resolver.c
··· 20 20 #include <dispatch/dispatch.h> 21 21 #include <resolv.h> 22 22 #include <stdio.h> 23 + #include <stdbool.h> 23 24 24 25 static int 25 26 dr_is_valid(si_mod_t *si, si_item_t *item) ··· 35 36 static si_item_t * 36 37 dr_hostbyname(si_mod_t *si, const char *name, int af, const char *interface, uint32_t *err) 37 38 { 38 - int type, l, i, elem_length; 39 + int type, l, i, j, elem_length; 39 40 unsigned char buf[4096]; 40 41 ns_msg msg; 41 42 ns_rr rr; ··· 67 68 addr_ptrs = (void**) __builtin_alloca((l+1) * sizeof(void*)); 68 69 addr_ptrs[l] = NULL; 69 70 70 - for (i = 0; i < l; i++) 71 + for (i = 0, j = 0; i < l; i++) 71 72 { 72 73 const unsigned char* data; 73 74 int type; ··· 79 80 if ((af == AF_INET && type == ns_t_a) 80 81 || (af == AF_INET6 && type == ns_t_aaaa)) 81 82 { 82 - memcpy(addr_buf + (i*elem_length), data, elem_length); 83 - addr_ptrs[i] = addr_buf + (i*elem_length); 83 + memcpy(addr_buf + (j*elem_length), data, elem_length); 84 + addr_ptrs[j] = addr_buf + (j*elem_length); 85 + j++; 84 86 } 85 87 } 88 + addr_ptrs[j] = NULL; 86 89 87 90 ttl_end = time(NULL) + rr.ttl; 88 91 if (af == AF_INET) ··· 171 174 static si_list_t * 172 175 dr_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, const char *interface, uint32_t *err) 173 176 { 174 - return NULL; 177 + bool resolveV4, resolveV6; 178 + int servPort = 0; 179 + 180 + if (err != NULL) *err = SI_STATUS_NO_ERROR; 181 + 182 + switch (family) 183 + { 184 + case AF_INET6: 185 + resolveV4 = (flags & AI_V4MAPPED) != 0; 186 + resolveV6 = true; 187 + break; 188 + case AF_INET: 189 + resolveV4 = true; 190 + resolveV6 = false; 191 + break; 192 + case AF_UNSPEC: 193 + resolveV4 = true; 194 + resolveV6 = true; 195 + break; 196 + default: 197 + return NULL; 198 + } 199 + 200 + if (flags & AI_NUMERICSERV) 201 + servPort = *(uint16_t *)serv; 202 + else 203 + { 204 + if (_gai_serv_to_port(serv, proto, &servPort) != 0) 205 + { 206 + if (err) 207 + *err = SI_STATUS_EAI_NONAME; 208 + return NULL; 209 + } 210 + } 211 + 212 + if (flags & AI_NUMERICHOST) 213 + { 214 + char* cname = NULL; 215 + struct in_addr addr4; 216 + struct in6_addr addr6; 217 + 218 + if (family == AF_INET) { 219 + memcpy(&addr4, node, sizeof(addr4)); 220 + } else if (family == AF_INET6) { 221 + memcpy(&addr6, node, sizeof(addr6)); 222 + } 223 + 224 + return si_addrinfo_list(si, flags, socktype, proto, 225 + (family == AF_INET) ? &addr4 : NULL, 226 + (family == AF_INET6) ? &addr6 : NULL, 227 + servPort, 0, cname, cname); 228 + } 229 + else 230 + { 231 + int i, l; 232 + ns_msg msg; 233 + ns_rr rr; 234 + unsigned char buf[4096]; 235 + si_list_t *out = NULL; 236 + si_list_t *list; 237 + 238 + if (resolveV6) 239 + { 240 + l = res_query((const char*) node, ns_c_any, ns_t_aaaa, buf, sizeof(buf)); 241 + if (l < 0) 242 + goto after_v6; 243 + 244 + ns_initparse(buf, l, &msg); 245 + l = ns_msg_count(msg, ns_s_an); 246 + 247 + for (i = 0; i < l; i++) 248 + { 249 + const unsigned char* data; 250 + int type; 251 + 252 + ns_parserr(&msg, ns_s_an, i, &rr); 253 + data = ns_rr_rdata(rr); 254 + type = ns_rr_type(rr); 255 + 256 + if (type == ns_t_aaaa) 257 + { 258 + list = si_addrinfo_list(si, flags, socktype, proto, NULL, 259 + (struct in6_addr*) data, servPort, 0, NULL, 260 + (const char*) node); 261 + 262 + out = si_list_concat(out, list); 263 + si_list_release(list); 264 + } 265 + } 266 + } 267 + 268 + // If AI_V4MAPPED is used, return IPv4 mapped addresses only if there 269 + // are no IPv6 addresses or AI_ALL was also specified. 270 + if (resolveV4 && family == AF_INET6 && !(flags & AI_ALL)) 271 + { 272 + if (out != NULL) 273 + resolveV4 = false; 274 + } 275 + 276 + after_v6: 277 + if (resolveV4) 278 + { 279 + l = res_query((const char*) node, ns_c_any, ns_t_a, buf, sizeof(buf)); 280 + if (l < 0) 281 + goto after_v4; 282 + 283 + ns_initparse(buf, l, &msg); 284 + l = ns_msg_count(msg, ns_s_an); 285 + 286 + for (i = 0; i < l; i++) 287 + { 288 + const unsigned char* data; 289 + int type; 290 + 291 + ns_parserr(&msg, ns_s_an, i, &rr); 292 + data = ns_rr_rdata(rr); 293 + type = ns_rr_type(rr); 294 + 295 + if (type == ns_t_a) 296 + { 297 + if (family == AF_INET6) 298 + { 299 + // Convert to a mapped address 300 + struct in6_addr mapped; 301 + 302 + memcpy(&mapped.__u6_addr, "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12); 303 + mapped.__u6_addr.__u6_addr32[3] = *(uint32_t*) data; 304 + 305 + list = si_addrinfo_list(si, flags, socktype, proto, NULL, 306 + (struct in6_addr*) &mapped, servPort, 0, NULL, 307 + (const char*) node); 308 + 309 + out = si_list_concat(out, list); 310 + si_list_release(list); 311 + } 312 + else 313 + { 314 + list = si_addrinfo_list(si, flags, socktype, proto, 315 + (struct in_addr*) data, NULL, servPort, 0, 316 + (const char*) node, NULL); 317 + 318 + out = si_list_concat(out, list); 319 + si_list_release(list); 320 + } 321 + } 322 + } 323 + } 324 + 325 + after_v4: 326 + 327 + return out; 328 + } 175 329 } 176 330 177 331 static si_item_t *