static void init_gnba(ns_lwdclient_t *client) { int i; /* * Initialize the real name and alias arrays in the reply we're * going to build up. */ for (i = 0; i < LWRES_MAX_ALIASES; i++) { client->aliases[i] = NULL; client->aliaslen[i] = 0; } for (i = 0; i < LWRES_MAX_ADDRS; i++) { client->addrs[i].family = 0; client->addrs[i].length = 0; memset(client->addrs[i].address, 0, LWRES_ADDR_MAXLEN); LWRES_LINK_INIT(&client->addrs[i], link); } client->gnba.naliases = 0; client->gnba.realname = NULL; client->gnba.aliases = client->aliases; client->gnba.realnamelen = 0; client->gnba.aliaslen = client->aliaslen; client->gnba.base = NULL; client->gnba.baselen = 0; isc_buffer_init(&client->recv_buffer, client->buffer, LWRES_RECVLENGTH); }
static lwres_result_t context_connect(lwres_context_t *ctx) { #ifndef WIN32 int s; #else SOCKET s; #endif int ret; struct sockaddr_in sin; struct sockaddr_in6 sin6; struct sockaddr *sa; LWRES_SOCKADDR_LEN_T salen; int domain; if (ctx->confdata.lwnext != 0) { memmove(&ctx->address, &ctx->confdata.lwservers[0], sizeof(lwres_addr_t)); LWRES_LINK_INIT(&ctx->address, link); } else { /* The default is the IPv4 loopback address 127.0.0.1. */ memset(&ctx->address, 0, sizeof(ctx->address)); ctx->address.family = LWRES_ADDRTYPE_V4; ctx->address.length = 4; ctx->address.address[0] = 127; ctx->address.address[1] = 0; ctx->address.address[2] = 0; ctx->address.address[3] = 1; } if (ctx->address.family == LWRES_ADDRTYPE_V4) { memmove(&sin.sin_addr, ctx->address.address, sizeof(sin.sin_addr)); sin.sin_port = htons(lwres_udp_port); sin.sin_family = AF_INET; sa = (struct sockaddr *)&sin; salen = sizeof(sin); domain = PF_INET; } else if (ctx->address.family == LWRES_ADDRTYPE_V6) { memmove(&sin6.sin6_addr, ctx->address.address, sizeof(sin6.sin6_addr)); sin6.sin6_port = htons(lwres_udp_port); sin6.sin6_family = AF_INET6; sa = (struct sockaddr *)&sin6; salen = sizeof(sin6); domain = PF_INET6; } else return (LWRES_R_IOERROR); #ifdef WIN32 InitSockets(); #endif s = socket(domain, SOCK_DGRAM, IPPROTO_UDP); #ifndef WIN32 if (s < 0) { return (LWRES_R_IOERROR); } #else if (s == INVALID_SOCKET) { DestroySockets(); return (LWRES_R_IOERROR); } #endif ret = connect(s, sa, salen); if (ret != 0) { #ifdef WIN32 DestroySockets(); #endif (void)close(s); return (LWRES_R_IOERROR); } MAKE_NONBLOCKING(s, ret); if (ret < 0) { #ifdef WIN32 DestroySockets(); #endif (void)close(s); return (LWRES_R_IOERROR); } ctx->sock = (int)s; return (LWRES_R_SUCCESS); }
lwres_result_t lwres_gabnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_gabnresponse_t **structp) { lwres_result_t ret; unsigned int x; lwres_uint32_t flags; lwres_uint16_t naliases; lwres_uint16_t naddrs; lwres_gabnresponse_t *gabn; lwres_addrlist_t addrlist; lwres_addr_t *addr; REQUIRE(ctx != NULL); REQUIRE(pkt != NULL); REQUIRE(b != NULL); REQUIRE(structp != NULL && *structp == NULL); gabn = NULL; if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) == 0) return (LWRES_R_FAILURE); /* * Pull off the name itself */ if (!SPACE_REMAINING(b, 4 + 2 + 2)) return (LWRES_R_UNEXPECTEDEND); flags = lwres_buffer_getuint32(b); naliases = lwres_buffer_getuint16(b); naddrs = lwres_buffer_getuint16(b); gabn = CTXMALLOC(sizeof(lwres_gabnresponse_t)); if (gabn == NULL) return (LWRES_R_NOMEMORY); gabn->aliases = NULL; gabn->aliaslen = NULL; LWRES_LIST_INIT(gabn->addrs); gabn->base = NULL; gabn->flags = flags; gabn->naliases = naliases; gabn->naddrs = naddrs; LWRES_LIST_INIT(addrlist); if (naliases > 0) { gabn->aliases = CTXMALLOC(sizeof(char *) * naliases); if (gabn->aliases == NULL) { ret = LWRES_R_NOMEMORY; goto out; } gabn->aliaslen = CTXMALLOC(sizeof(lwres_uint16_t) * naliases); if (gabn->aliaslen == NULL) { ret = LWRES_R_NOMEMORY; goto out; } } for (x = 0; x < naddrs; x++) { addr = CTXMALLOC(sizeof(lwres_addr_t)); if (addr == NULL) { ret = LWRES_R_NOMEMORY; goto out; } LWRES_LINK_INIT(addr, link); LWRES_LIST_APPEND(addrlist, addr, link); } /* * Now, pull off the real name. */ ret = lwres_string_parse(b, &gabn->realname, &gabn->realnamelen); if (ret != LWRES_R_SUCCESS) goto out; /* * Parse off the aliases. */ for (x = 0; x < gabn->naliases; x++) { ret = lwres_string_parse(b, &gabn->aliases[x], &gabn->aliaslen[x]); if (ret != LWRES_R_SUCCESS) goto out; } /* * Pull off the addresses. We already strung the linked list * up above. */ addr = LWRES_LIST_HEAD(addrlist); for (x = 0; x < gabn->naddrs; x++) { INSIST(addr != NULL); ret = lwres_addr_parse(b, addr); if (ret != LWRES_R_SUCCESS) goto out; addr = LWRES_LIST_NEXT(addr, link); } if (LWRES_BUFFER_REMAINING(b) != 0) { ret = LWRES_R_TRAILINGDATA; goto out; } gabn->addrs = addrlist; *structp = gabn; return (LWRES_R_SUCCESS); out: if (gabn != NULL) { if (gabn->aliases != NULL) CTXFREE(gabn->aliases, sizeof(char *) * naliases); if (gabn->aliaslen != NULL) CTXFREE(gabn->aliaslen, sizeof(lwres_uint16_t) * naliases); addr = LWRES_LIST_HEAD(addrlist); while (addr != NULL) { LWRES_LIST_UNLINK(addrlist, addr, link); CTXFREE(addr, sizeof(lwres_addr_t)); addr = LWRES_LIST_HEAD(addrlist); } CTXFREE(gabn, sizeof(lwres_gabnresponse_t)); } return (ret); }