Move bind9_getaddresses() to isc_sockaddr_fromtext()
More convivial surroundings for this function.
This commit is contained in:
+5
-7
@@ -81,8 +81,6 @@
|
||||
|
||||
#include <irs/resconf.h>
|
||||
|
||||
#include <bind9/getaddresses.h>
|
||||
|
||||
#include "dighost.h"
|
||||
|
||||
#define systemlocale(l) (void)setlocale(l, "")
|
||||
@@ -538,8 +536,8 @@ set_nameserver(char *opt) {
|
||||
}
|
||||
|
||||
isc_loopmgr_blocking(loopmgr);
|
||||
result = bind9_getaddresses(opt, 0, sockaddrs, DIG_MAX_ADDRESSES,
|
||||
&count);
|
||||
result = isc_sockaddr_fromtext(opt, 0, sockaddrs, DIG_MAX_ADDRESSES,
|
||||
&count);
|
||||
isc_loopmgr_nonblocking(loopmgr);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
fatal("couldn't get address for '%s': %s", opt,
|
||||
@@ -4533,7 +4531,7 @@ get_address(char *host, in_port_t myport, isc_sockaddr_t *sockaddr) {
|
||||
isc_result_t result;
|
||||
|
||||
isc_loopmgr_blocking(loopmgr);
|
||||
result = bind9_getaddresses(host, myport, sockaddr, 1, &count);
|
||||
result = isc_sockaddr_fromtext(host, myport, sockaddr, 1, &count);
|
||||
isc_loopmgr_nonblocking(loopmgr);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
@@ -4554,8 +4552,8 @@ getaddresses(dig_lookup_t *lookup, const char *host, isc_result_t *resultp) {
|
||||
char tmp[ISC_NETADDR_FORMATSIZE];
|
||||
|
||||
isc_loopmgr_blocking(loopmgr);
|
||||
result = bind9_getaddresses(host, 0, sockaddrs, DIG_MAX_ADDRESSES,
|
||||
&count);
|
||||
result = isc_sockaddr_fromtext(host, 0, sockaddrs, DIG_MAX_ADDRESSES,
|
||||
&count);
|
||||
isc_loopmgr_nonblocking(loopmgr);
|
||||
if (resultp != NULL) {
|
||||
*resultp = result;
|
||||
|
||||
@@ -95,8 +95,6 @@
|
||||
|
||||
#endif /* HAVE_GSSAPI */
|
||||
|
||||
#include <bind9/getaddresses.h>
|
||||
|
||||
#include "../dig/readline.h"
|
||||
|
||||
#define MAXCMD (128 * 1024)
|
||||
@@ -108,7 +106,7 @@
|
||||
|
||||
#define DNSDEFAULTPORT 53
|
||||
|
||||
/* Number of addresses to request from bind9_getaddresses() */
|
||||
/* Number of addresses to request from isc_sockaddr_fromtext() */
|
||||
#define MAX_SERVERADDRS 4
|
||||
|
||||
static uint16_t dnsport = DNSDEFAULTPORT;
|
||||
@@ -1017,7 +1015,7 @@ get_addresses(char *host, in_port_t port, isc_sockaddr_t *sockaddr,
|
||||
isc_result_t result;
|
||||
|
||||
isc_loopmgr_blocking(loopmgr);
|
||||
result = bind9_getaddresses(host, port, sockaddr, naddrs, &count);
|
||||
result = isc_sockaddr_fromtext(host, port, sockaddr, naddrs, &count);
|
||||
isc_loopmgr_nonblocking(loopmgr);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
error("couldn't get address for '%s': %s", host,
|
||||
|
||||
+1
-3
@@ -50,8 +50,6 @@
|
||||
|
||||
#include <isccfg/namedconf.h>
|
||||
|
||||
#include <bind9/getaddresses.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#define SERVERADDRS 10
|
||||
@@ -282,7 +280,7 @@ get_addresses(const char *host, in_port_t port) {
|
||||
}
|
||||
} else {
|
||||
count = SERVERADDRS - nserveraddrs;
|
||||
result = bind9_getaddresses(
|
||||
result = isc_sockaddr_fromtext(
|
||||
host, port, &serveraddrs[nserveraddrs], count, &found);
|
||||
nserveraddrs += found;
|
||||
}
|
||||
|
||||
+1
-3
@@ -54,8 +54,6 @@
|
||||
#include <dns/types.h>
|
||||
#include <dns/view.h>
|
||||
|
||||
#include <bind9/getaddresses.h>
|
||||
|
||||
#define CHECK(str, x) \
|
||||
{ \
|
||||
if ((x) != ISC_R_SUCCESS) { \
|
||||
@@ -2138,7 +2136,7 @@ main(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
ns = 0;
|
||||
result = bind9_getaddresses(server, port, &dstaddr, 1, &ns);
|
||||
result = isc_sockaddr_fromtext(server, port, &dstaddr, 1, &ns);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
fatal("couldn't get address for '%s': %s", server,
|
||||
isc_result_totext(result));
|
||||
|
||||
@@ -4,13 +4,11 @@ lib_LTLIBRARIES = libbind9.la
|
||||
|
||||
libbind9_ladir = $(includedir)/bind9
|
||||
libbind9_la_HEADERS = \
|
||||
include/bind9/check.h \
|
||||
include/bind9/getaddresses.h
|
||||
include/bind9/check.h
|
||||
|
||||
libbind9_la_SOURCES = \
|
||||
$(libbind9_la_HEADERS) \
|
||||
check.c \
|
||||
getaddresses.c
|
||||
check.c
|
||||
|
||||
libbind9_la_CPPFLAGS = \
|
||||
$(AM_CPPFLAGS) \
|
||||
|
||||
@@ -1,164 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <isc/net.h>
|
||||
#include <isc/netaddr.h>
|
||||
#include <isc/netdb.h>
|
||||
#include <isc/netscope.h>
|
||||
#include <isc/result.h>
|
||||
#include <isc/sockaddr.h>
|
||||
#include <isc/string.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <bind9/getaddresses.h>
|
||||
|
||||
isc_result_t
|
||||
bind9_getaddresses(const char *hostname, in_port_t port, isc_sockaddr_t *addrs,
|
||||
int addrsize, int *addrcount) {
|
||||
struct in_addr in4;
|
||||
struct in6_addr in6;
|
||||
bool have_ipv4, have_ipv6;
|
||||
int i;
|
||||
|
||||
struct addrinfo *ai = NULL, *tmpai, hints;
|
||||
int result;
|
||||
|
||||
REQUIRE(hostname != NULL);
|
||||
REQUIRE(addrs != NULL);
|
||||
REQUIRE(addrcount != NULL);
|
||||
REQUIRE(addrsize > 0);
|
||||
|
||||
have_ipv4 = (isc_net_probeipv4() == ISC_R_SUCCESS);
|
||||
have_ipv6 = (isc_net_probeipv6() == ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* Try IPv4, then IPv6. In order to handle the extended format
|
||||
* for IPv6 scoped addresses (address%scope_ID), we'll use a local
|
||||
* working buffer of 128 bytes. The length is an ad-hoc value, but
|
||||
* should be enough for this purpose; the buffer can contain a string
|
||||
* of at least 80 bytes for scope_ID in addition to any IPv6 numeric
|
||||
* addresses (up to 46 bytes), the delimiter character and the
|
||||
* terminating NULL character.
|
||||
*/
|
||||
if (inet_pton(AF_INET, hostname, &in4) == 1) {
|
||||
if (have_ipv4) {
|
||||
isc_sockaddr_fromin(&addrs[0], &in4, port);
|
||||
} else {
|
||||
isc_sockaddr_v6fromin(&addrs[0], &in4, port);
|
||||
}
|
||||
*addrcount = 1;
|
||||
return (ISC_R_SUCCESS);
|
||||
} else if (strlen(hostname) <= 127U) {
|
||||
char tmpbuf[128], *d;
|
||||
uint32_t zone = 0;
|
||||
|
||||
strlcpy(tmpbuf, hostname, sizeof(tmpbuf));
|
||||
d = strchr(tmpbuf, '%');
|
||||
if (d != NULL) {
|
||||
*d = '\0';
|
||||
}
|
||||
|
||||
if (inet_pton(AF_INET6, tmpbuf, &in6) == 1) {
|
||||
isc_netaddr_t na;
|
||||
|
||||
if (!have_ipv6) {
|
||||
return (ISC_R_FAMILYNOSUPPORT);
|
||||
}
|
||||
|
||||
if (d != NULL) {
|
||||
isc_result_t iresult;
|
||||
|
||||
iresult = isc_netscope_pton(AF_INET6, d + 1,
|
||||
&in6, &zone);
|
||||
|
||||
if (iresult != ISC_R_SUCCESS) {
|
||||
return (iresult);
|
||||
}
|
||||
}
|
||||
|
||||
isc_netaddr_fromin6(&na, &in6);
|
||||
isc_netaddr_setzone(&na, zone);
|
||||
isc_sockaddr_fromnetaddr(
|
||||
&addrs[0], (const isc_netaddr_t *)&na, port);
|
||||
|
||||
*addrcount = 1;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
}
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
if (!have_ipv6) {
|
||||
hints.ai_family = PF_INET;
|
||||
} else if (!have_ipv4) {
|
||||
hints.ai_family = PF_INET6;
|
||||
} else {
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
#ifdef AI_ADDRCONFIG
|
||||
hints.ai_flags = AI_ADDRCONFIG;
|
||||
#endif /* ifdef AI_ADDRCONFIG */
|
||||
}
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
#ifdef AI_ADDRCONFIG
|
||||
again:
|
||||
#endif /* ifdef AI_ADDRCONFIG */
|
||||
result = getaddrinfo(hostname, NULL, &hints, &ai);
|
||||
switch (result) {
|
||||
case 0:
|
||||
break;
|
||||
case EAI_NONAME:
|
||||
#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
|
||||
case EAI_NODATA:
|
||||
#endif /* if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) */
|
||||
return (ISC_R_NOTFOUND);
|
||||
#ifdef AI_ADDRCONFIG
|
||||
case EAI_BADFLAGS:
|
||||
if ((hints.ai_flags & AI_ADDRCONFIG) != 0) {
|
||||
hints.ai_flags &= ~AI_ADDRCONFIG;
|
||||
goto again;
|
||||
}
|
||||
#endif /* ifdef AI_ADDRCONFIG */
|
||||
FALLTHROUGH;
|
||||
default:
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
for (tmpai = ai, i = 0; tmpai != NULL && i < addrsize;
|
||||
tmpai = tmpai->ai_next)
|
||||
{
|
||||
if (tmpai->ai_family != AF_INET && tmpai->ai_family != AF_INET6)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (tmpai->ai_family == AF_INET) {
|
||||
struct sockaddr_in *sin;
|
||||
sin = (struct sockaddr_in *)tmpai->ai_addr;
|
||||
isc_sockaddr_fromin(&addrs[i], &sin->sin_addr, port);
|
||||
} else {
|
||||
struct sockaddr_in6 *sin6;
|
||||
sin6 = (struct sockaddr_in6 *)tmpai->ai_addr;
|
||||
isc_sockaddr_fromin6(&addrs[i], &sin6->sin6_addr, port);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
freeaddrinfo(ai);
|
||||
*addrcount = i;
|
||||
if (*addrcount == 0) {
|
||||
return (ISC_R_NOTFOUND);
|
||||
} else {
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/*! \file bind9/getaddresses.h */
|
||||
|
||||
#include <isc/lang.h>
|
||||
#include <isc/net.h>
|
||||
#include <isc/types.h>
|
||||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
isc_result_t
|
||||
bind9_getaddresses(const char *hostname, in_port_t port, isc_sockaddr_t *addrs,
|
||||
int addrsize, int *addrcount);
|
||||
/*%<
|
||||
* Use the system resolver to get the addresses associated with a hostname.
|
||||
* If successful, the number of addresses found is returned in 'addrcount'.
|
||||
* If a hostname lookup is performed and addresses of an unknown family is
|
||||
* seen, it is ignored. If more than 'addrsize' addresses are seen, the
|
||||
* first 'addrsize' are returned and the remainder silently truncated.
|
||||
*
|
||||
* This routine may block. If called by a program using the isc_loopmgr
|
||||
* framework, it should be surrounded by isc_loopmgr_blocking() and
|
||||
* isc_loopmgr_nonblocking().
|
||||
*
|
||||
* Requires:
|
||||
*\li 'hostname' is not NULL.
|
||||
*\li 'addrs' is not NULL.
|
||||
*\li 'addrsize' > 0
|
||||
*\li 'addrcount' is not NULL.
|
||||
*
|
||||
*
|
||||
* Returns:
|
||||
*\li #ISC_R_SUCCESS
|
||||
*\li #ISC_R_NOTFOUND
|
||||
*\li #ISC_R_FAMILYNOSUPPORT - 'hostname' is an IPv6 address, and IPv6 is
|
||||
* not supported.
|
||||
*/
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
@@ -245,4 +245,32 @@ isc_sockaddr_fromsockaddr(isc_sockaddr_t *isa, const struct sockaddr *sa);
|
||||
* Minimum size of array to pass to isc_sockaddr_format().
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
isc_sockaddr_fromtext(const char *hostname, in_port_t port,
|
||||
isc_sockaddr_t *addrs, int addrsize, int *addrcount);
|
||||
/*%<
|
||||
* Use the system resolver to get the addresses associated with a hostname.
|
||||
* If successful, the number of addresses found is returned in 'addrcount'.
|
||||
* If a hostname lookup is performed and addresses of an unknown family is
|
||||
* seen, it is ignored. If more than 'addrsize' addresses are seen, the
|
||||
* first 'addrsize' are returned and the remainder silently truncated.
|
||||
*
|
||||
* This routine may block. If called by a program using the isc_loopmgr
|
||||
* framework, it should be surrounded by isc_loopmgr_blocking() and
|
||||
* isc_loopmgr_nonblocking().
|
||||
*
|
||||
* Requires:
|
||||
*\li 'hostname' is not NULL.
|
||||
*\li 'addrs' is not NULL.
|
||||
*\li 'addrsize' > 0
|
||||
*\li 'addrcount' is not NULL.
|
||||
*
|
||||
*
|
||||
* Returns:
|
||||
*\li #ISC_R_SUCCESS
|
||||
*\li #ISC_R_NOTFOUND
|
||||
*\li #ISC_R_FAMILYNOSUPPORT - 'hostname' is an IPv6 address, and IPv6 is
|
||||
* not supported.
|
||||
*/
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
@@ -18,11 +18,15 @@
|
||||
|
||||
#include <isc/buffer.h>
|
||||
#include <isc/hash.h>
|
||||
#include <isc/net.h>
|
||||
#include <isc/netaddr.h>
|
||||
#include <isc/netdb.h>
|
||||
#include <isc/netscope.h>
|
||||
#include <isc/print.h>
|
||||
#include <isc/region.h>
|
||||
#include <isc/sockaddr.h>
|
||||
#include <isc/string.h>
|
||||
#include <isc/types.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
bool
|
||||
@@ -497,3 +501,138 @@ isc_sockaddr_fromsockaddr(isc_sockaddr_t *isa, const struct sockaddr *sa) {
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_sockaddr_fromtext(const char *hostname, in_port_t port,
|
||||
isc_sockaddr_t *addrs, int addrsize, int *addrcount) {
|
||||
struct in_addr in4;
|
||||
struct in6_addr in6;
|
||||
bool have_ipv4, have_ipv6;
|
||||
int i;
|
||||
|
||||
struct addrinfo *ai = NULL, *tmpai, hints;
|
||||
int result;
|
||||
|
||||
REQUIRE(hostname != NULL);
|
||||
REQUIRE(addrs != NULL);
|
||||
REQUIRE(addrcount != NULL);
|
||||
REQUIRE(addrsize > 0);
|
||||
|
||||
have_ipv4 = (isc_net_probeipv4() == ISC_R_SUCCESS);
|
||||
have_ipv6 = (isc_net_probeipv6() == ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* Try IPv4, then IPv6. In order to handle the extended format
|
||||
* for IPv6 scoped addresses (address%scope_ID), we'll use a local
|
||||
* working buffer of 128 bytes. The length is an ad-hoc value, but
|
||||
* should be enough for this purpose; the buffer can contain a string
|
||||
* of at least 80 bytes for scope_ID in addition to any IPv6 numeric
|
||||
* addresses (up to 46 bytes), the delimiter character and the
|
||||
* terminating NULL character.
|
||||
*/
|
||||
if (inet_pton(AF_INET, hostname, &in4) == 1) {
|
||||
if (have_ipv4) {
|
||||
isc_sockaddr_fromin(&addrs[0], &in4, port);
|
||||
} else {
|
||||
isc_sockaddr_v6fromin(&addrs[0], &in4, port);
|
||||
}
|
||||
*addrcount = 1;
|
||||
return (ISC_R_SUCCESS);
|
||||
} else if (strlen(hostname) <= 127U) {
|
||||
char tmpbuf[128], *d;
|
||||
uint32_t zone = 0;
|
||||
|
||||
strlcpy(tmpbuf, hostname, sizeof(tmpbuf));
|
||||
d = strchr(tmpbuf, '%');
|
||||
if (d != NULL) {
|
||||
*d = '\0';
|
||||
}
|
||||
|
||||
if (inet_pton(AF_INET6, tmpbuf, &in6) == 1) {
|
||||
isc_netaddr_t na;
|
||||
|
||||
if (!have_ipv6) {
|
||||
return (ISC_R_FAMILYNOSUPPORT);
|
||||
}
|
||||
|
||||
if (d != NULL) {
|
||||
isc_result_t iresult;
|
||||
|
||||
iresult = isc_netscope_pton(AF_INET6, d + 1,
|
||||
&in6, &zone);
|
||||
|
||||
if (iresult != ISC_R_SUCCESS) {
|
||||
return (iresult);
|
||||
}
|
||||
}
|
||||
|
||||
isc_netaddr_fromin6(&na, &in6);
|
||||
isc_netaddr_setzone(&na, zone);
|
||||
isc_sockaddr_fromnetaddr(
|
||||
&addrs[0], (const isc_netaddr_t *)&na, port);
|
||||
|
||||
*addrcount = 1;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
}
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
if (!have_ipv6) {
|
||||
hints.ai_family = PF_INET;
|
||||
} else if (!have_ipv4) {
|
||||
hints.ai_family = PF_INET6;
|
||||
} else {
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
#ifdef AI_ADDRCONFIG
|
||||
hints.ai_flags = AI_ADDRCONFIG;
|
||||
#endif /* ifdef AI_ADDRCONFIG */
|
||||
}
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
#ifdef AI_ADDRCONFIG
|
||||
again:
|
||||
#endif /* ifdef AI_ADDRCONFIG */
|
||||
result = getaddrinfo(hostname, NULL, &hints, &ai);
|
||||
switch (result) {
|
||||
case 0:
|
||||
break;
|
||||
case EAI_NONAME:
|
||||
#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
|
||||
case EAI_NODATA:
|
||||
#endif /* if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) */
|
||||
return (ISC_R_NOTFOUND);
|
||||
#ifdef AI_ADDRCONFIG
|
||||
case EAI_BADFLAGS:
|
||||
if ((hints.ai_flags & AI_ADDRCONFIG) != 0) {
|
||||
hints.ai_flags &= ~AI_ADDRCONFIG;
|
||||
goto again;
|
||||
}
|
||||
#endif /* ifdef AI_ADDRCONFIG */
|
||||
FALLTHROUGH;
|
||||
default:
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
for (tmpai = ai, i = 0; tmpai != NULL && i < addrsize;
|
||||
tmpai = tmpai->ai_next)
|
||||
{
|
||||
if (tmpai->ai_family != AF_INET && tmpai->ai_family != AF_INET6)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (tmpai->ai_family == AF_INET) {
|
||||
struct sockaddr_in *sin;
|
||||
sin = (struct sockaddr_in *)tmpai->ai_addr;
|
||||
isc_sockaddr_fromin(&addrs[i], &sin->sin_addr, port);
|
||||
} else {
|
||||
struct sockaddr_in6 *sin6;
|
||||
sin6 = (struct sockaddr_in6 *)tmpai->ai_addr;
|
||||
isc_sockaddr_fromin6(&addrs[i], &sin6->sin6_addr, port);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
freeaddrinfo(ai);
|
||||
*addrcount = i;
|
||||
if (*addrcount == 0) {
|
||||
return (ISC_R_NOTFOUND);
|
||||
} else {
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -2894,7 +2894,7 @@ token_addr(cfg_parser_t *pctx, unsigned int flags, isc_netaddr_t *na) {
|
||||
}
|
||||
}
|
||||
if ((flags & CFG_ADDR_V6OK) != 0 && strlen(s) <= 127U) {
|
||||
char buf[128]; /* see lib/bind9/getaddresses.c */
|
||||
char buf[128]; /* see isc_sockaddr_fromtext() */
|
||||
char *d; /* zone delimiter */
|
||||
uint32_t zone = 0; /* scope zone ID */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user