static void dyn_dir_init(VRT_CTX, struct xyzzy_debug_dyn *dyn, VCL_STRING addr, VCL_STRING port, VCL_PROBE probe) { struct addrinfo hints, *res = NULL; struct suckaddr *sa; VCL_BACKEND dir, dir2; struct vrt_backend vrt; CHECK_OBJ_NOTNULL(dyn, VMOD_DEBUG_DYN_MAGIC); XXXAN(addr); XXXAN(port); INIT_OBJ(&vrt, VRT_BACKEND_MAGIC); vrt.port = port; vrt.vcl_name = dyn->vcl_name; vrt.hosthdr = addr; vrt.probe = probe; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; AZ(getaddrinfo(addr, port, &hints, &res)); XXXAZ(res->ai_next); sa = VSA_Malloc(res->ai_addr, res->ai_addrlen); AN(sa); if (VSA_Get_Proto(sa) == AF_INET) { vrt.ipv4_addr = addr; vrt.ipv4_suckaddr = sa; } else if (VSA_Get_Proto(sa) == AF_INET6) { vrt.ipv6_addr = addr; vrt.ipv6_suckaddr = sa; } else WRONG("Wrong proto family"); freeaddrinfo(res); dir = VRT_new_backend(ctx, &vrt); AN(dir); /* * NB: A real dynamic backend should not replace the previous * instance if the new one is identical. We do it here because * the d* tests requires a replacement. */ AZ(pthread_mutex_lock(&dyn->mtx)); dir2 = dyn->dir; dyn->dir = dir; AZ(pthread_mutex_unlock(&dyn->mtx)); if (dir2 != NULL) VRT_delete_backend(ctx, &dir2); free(sa); }
struct suckaddr * VTCP_my_suckaddr(int sock) { struct sockaddr_storage addr_s; socklen_t l; l = sizeof addr_s; AZ(getsockname(sock, (void *)&addr_s, &l)); return (VSA_Malloc(&addr_s, l)); }
int VSS_resolver(const char *addr, const char *def_port, vss_resolved_f *func, void *priv, const char **err) { struct addrinfo hints, *res0, *res; struct suckaddr *vsa; char *h; char *adp, *hop; int ret; *err = NULL; h = strdup(addr); AN(h); *err = vss_parse(h, &hop, &adp); if (*err != NULL) { free(h); return (-1); } if (adp != NULL) def_port = adp; memset(&hints, 0, sizeof hints); hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; ret = getaddrinfo(hop, def_port, &hints, &res0); free(h); if (ret != 0) { *err = gai_strerror(ret); return (-1); } for (res = res0; res != NULL; res = res->ai_next) { vsa = VSA_Malloc(res->ai_addr, res->ai_addrlen); if (vsa != NULL) { ret = func(priv, vsa); free(vsa); if (ret) break; } } freeaddrinfo(res0); return (ret); }