mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-23 03:10:05 +00:00
* sysdeps/posix/getaddrinfo.c (defaults_scopes, scopes): New variables.
(get_scope): For IPv4 scope, use scopes table. (fini): Free scopes table if necessary. (free_scopelist): New function. (scopecmp): New function. (gaiconf_init): Also handle scopev4 entries. * posix/tst-rfc3484.c (do_test): Initialize scopes. * posix/tst-rfc3484-2.c (do_test): Likewise. * posix/gai.conf: Document scopev4 defaults. * posix/Makefile (tests): Add tst-rfc3484-3. * posix/tst-rfc3484-3.c: New file.
This commit is contained in:
parent
f4a7976578
commit
ee72b97189
12
ChangeLog
12
ChangeLog
@ -1,5 +1,17 @@
|
|||||||
2007-11-19 Ulrich Drepper <drepper@redhat.com>
|
2007-11-19 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
* sysdeps/posix/getaddrinfo.c (defaults_scopes, scopes): New variables.
|
||||||
|
(get_scope): For IPv4 scope, use scopes table.
|
||||||
|
(fini): Free scopes table if necessary.
|
||||||
|
(free_scopelist): New function.
|
||||||
|
(scopecmp): New function.
|
||||||
|
(gaiconf_init): Also handle scopev4 entries.
|
||||||
|
* posix/tst-rfc3484.c (do_test): Initialize scopes.
|
||||||
|
* posix/tst-rfc3484-2.c (do_test): Likewise.
|
||||||
|
* posix/gai.conf: Document scopev4 defaults.
|
||||||
|
* posix/Makefile (tests): Add tst-rfc3484-3.
|
||||||
|
* posix/tst-rfc3484-3.c: New file.
|
||||||
|
|
||||||
* sysdeps/posix/getaddrinfo.c (default_labels): Describe entry for
|
* sysdeps/posix/getaddrinfo.c (default_labels): Describe entry for
|
||||||
Teredo tunnels.
|
Teredo tunnels.
|
||||||
* posix/gai.conf: Update for current default tables.
|
* posix/gai.conf: Update for current default tables.
|
||||||
|
@ -90,6 +90,7 @@ tests := tstgetopt testfnm runtests runptests \
|
|||||||
tst-execv1 tst-execv2 tst-execl1 tst-execl2 \
|
tst-execv1 tst-execv2 tst-execl1 tst-execl2 \
|
||||||
tst-execve1 tst-execve2 tst-execle1 tst-execle2 \
|
tst-execve1 tst-execve2 tst-execle1 tst-execle2 \
|
||||||
tst-execvp3 tst-execvp4 tst-rfc3484 tst-rfc3484-2 \
|
tst-execvp3 tst-execvp4 tst-rfc3484 tst-rfc3484-2 \
|
||||||
|
tst-rfc3484-3 \
|
||||||
tst-getaddrinfo3 tst-fnmatch2 tst-cpucount tst-cpuset
|
tst-getaddrinfo3 tst-fnmatch2 tst-cpucount tst-cpuset
|
||||||
xtests := bug-ga2
|
xtests := bug-ga2
|
||||||
ifeq (yes,$(build-shared))
|
ifeq (yes,$(build-shared))
|
||||||
|
@ -52,3 +52,17 @@
|
|||||||
# For sites which prefer IPv4 connections change the last line to
|
# For sites which prefer IPv4 connections change the last line to
|
||||||
#
|
#
|
||||||
#precedence ::ffff:0:0/96 100
|
#precedence ::ffff:0:0/96 100
|
||||||
|
|
||||||
|
#
|
||||||
|
# scopev4 <mask> <value>
|
||||||
|
# Add another rule to the RFC 3484 scope table for IPv4 addresses.
|
||||||
|
# By default the scope IDs described in section 3.2 in RFC 3484 are
|
||||||
|
# used. Changing these defaults should hardly ever be necessary.
|
||||||
|
# The defaults are equivalent to:
|
||||||
|
#
|
||||||
|
#scopev4 ::ffff:169.254.0.0/112 2
|
||||||
|
#scopev4 ::ffff:127.0.0.0/104 2
|
||||||
|
#scopev4 ::ffff:10.0.0.0/104 5
|
||||||
|
#scopev4 ::ffff:172.16.0.0/108 5
|
||||||
|
#scopev4 ::ffff:192.168.0.0/112 5
|
||||||
|
#scopev4 ::ffff:0.0.0.0 14
|
||||||
|
@ -66,6 +66,7 @@ do_test (void)
|
|||||||
{
|
{
|
||||||
labels = default_labels;
|
labels = default_labels;
|
||||||
precedence = default_precedence;
|
precedence = default_precedence;
|
||||||
|
scopes = default_scopes;
|
||||||
|
|
||||||
struct sockaddr_in so1;
|
struct sockaddr_in so1;
|
||||||
so1.sin_family = AF_INET;
|
so1.sin_family = AF_INET;
|
||||||
|
137
posix/tst-rfc3484-3.c
Normal file
137
posix/tst-rfc3484-3.c
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ifaddrs.h>
|
||||||
|
|
||||||
|
/* Internal definitions used in the libc code. */
|
||||||
|
#define __getservbyname_r getservbyname_r
|
||||||
|
#define __socket socket
|
||||||
|
#define __getsockname getsockname
|
||||||
|
#define __inet_aton inet_aton
|
||||||
|
#define __gethostbyaddr_r gethostbyaddr_r
|
||||||
|
#define __gethostbyname2_r gethostbyname2_r
|
||||||
|
|
||||||
|
void
|
||||||
|
attribute_hidden
|
||||||
|
__check_pf (bool *p1, bool *p2, struct in6addrinfo **in6ai, size_t *in6ailen)
|
||||||
|
{
|
||||||
|
*p1 = *p2 = true;
|
||||||
|
*in6ai = NULL;
|
||||||
|
*in6ailen = 0;
|
||||||
|
}
|
||||||
|
void
|
||||||
|
attribute_hidden
|
||||||
|
__check_native (uint32_t a1_index, int *a1_native,
|
||||||
|
uint32_t a2_index, int *a2_native)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
int
|
||||||
|
__idna_to_ascii_lz (const char *input, char **output, int flags)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int
|
||||||
|
__idna_to_unicode_lzlz (const char *input, char **output, int flags)
|
||||||
|
{
|
||||||
|
*output = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "../sysdeps/posix/getaddrinfo.c"
|
||||||
|
|
||||||
|
service_user *__nss_hosts_database attribute_hidden;
|
||||||
|
|
||||||
|
|
||||||
|
/* This is the beginning of the real test code. The above defines
|
||||||
|
(among other things) the function rfc3484_sort. */
|
||||||
|
|
||||||
|
|
||||||
|
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||||
|
# define h(n) n
|
||||||
|
#else
|
||||||
|
# define h(n) __bswap_constant_32 (n)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct sockaddr_in addrs[] =
|
||||||
|
{
|
||||||
|
{ .sin_family = AF_INET, .sin_addr = { h (0xa0a86d1d) } },
|
||||||
|
{ .sin_family = AF_INET, .sin_addr = { h (0xa0a85d03) } },
|
||||||
|
{ .sin_family = AF_INET, .sin_addr = { h (0xa0a82c3d) } },
|
||||||
|
{ .sin_family = AF_INET, .sin_addr = { h (0xa0a86002) } },
|
||||||
|
{ .sin_family = AF_INET, .sin_addr = { h (0xa0a802f3) } },
|
||||||
|
{ .sin_family = AF_INET, .sin_addr = { h (0xa0a80810) } },
|
||||||
|
{ .sin_family = AF_INET, .sin_addr = { h (0xa0a85e02) } },
|
||||||
|
{ .sin_family = AF_INET, .sin_addr = { h (0xac162311) } },
|
||||||
|
{ .sin_family = AF_INET, .sin_addr = { h (0x0a324572) } }
|
||||||
|
};
|
||||||
|
#define naddrs (sizeof (addrs) / sizeof (addrs[0]))
|
||||||
|
static struct addrinfo ais[naddrs];
|
||||||
|
static struct sort_result results[naddrs];
|
||||||
|
|
||||||
|
static const int expected[naddrs] =
|
||||||
|
{
|
||||||
|
8, 0, 1, 2, 3, 4, 5, 6, 7
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct scopeentry new_scopes[] =
|
||||||
|
{
|
||||||
|
{ { { 169, 254, 0, 0 } }, h (0xffff0000), 2 },
|
||||||
|
{ { { 127, 0, 0, 0 } }, h (0xff000000), 2 },
|
||||||
|
{ { { 10, 0, 0, 0 } }, h (0xff000000), 5 },
|
||||||
|
{ { { 192, 168, 0, 0 } }, h(0xffff0000), 5 },
|
||||||
|
{ { { 0, 0, 0, 0 } }, h (0x00000000), 14 }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
__getline (char **lineptr, size_t *n, FILE *s)
|
||||||
|
{
|
||||||
|
*lineptr = NULL;
|
||||||
|
*n = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_test (void)
|
||||||
|
{
|
||||||
|
labels = default_labels;
|
||||||
|
precedence = default_precedence;
|
||||||
|
scopes= new_scopes;
|
||||||
|
|
||||||
|
struct sockaddr_in so;
|
||||||
|
so.sin_family = AF_INET;
|
||||||
|
so.sin_addr.s_addr = h (0x0aa85f19);
|
||||||
|
|
||||||
|
for (int i = 0; i < naddrs; ++i)
|
||||||
|
{
|
||||||
|
ais[i].ai_family = AF_INET;
|
||||||
|
ais[i].ai_addr = (struct sockaddr *) &addrs[i];
|
||||||
|
results[i].dest_addr = &ais[i];
|
||||||
|
results[i].got_source_addr = true;
|
||||||
|
memcpy(&results[i].source_addr, &so, sizeof (so));
|
||||||
|
results[i].source_addr_len = sizeof (so);
|
||||||
|
results[i].source_addr_flags = 0;
|
||||||
|
results[i].service_order = i;
|
||||||
|
results[i].prefixlen = 8;
|
||||||
|
results[i].index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sort_result_combo combo = { .results = results, .nresults = naddrs };
|
||||||
|
qsort_r (results, naddrs, sizeof (results[0]), rfc3484_sort, &combo);
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
|
for (int i = 0; i < naddrs; ++i)
|
||||||
|
{
|
||||||
|
struct in_addr addr = ((struct sockaddr_in *) (results[i].dest_addr->ai_addr))->sin_addr;
|
||||||
|
|
||||||
|
int here = memcmp (&addr, &addrs[expected[i]].sin_addr,
|
||||||
|
sizeof (struct in_addr));
|
||||||
|
printf ("[%d] = %s: %s\n", i, inet_ntoa (addr), here ? "FAIL" : "OK");
|
||||||
|
result |= here;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TEST_FUNCTION do_test ()
|
||||||
|
#include "../test-skeleton.c"
|
@ -85,6 +85,7 @@ do_test (void)
|
|||||||
{
|
{
|
||||||
labels = default_labels;
|
labels = default_labels;
|
||||||
precedence = default_precedence;
|
precedence = default_precedence;
|
||||||
|
scopes= default_scopes;
|
||||||
|
|
||||||
struct sockaddr_in so;
|
struct sockaddr_in so;
|
||||||
so.sin_family = AF_INET;
|
so.sin_family = AF_INET;
|
||||||
|
@ -1014,6 +1014,38 @@ struct sort_result_combo
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||||
|
# define htonl_c(n) n
|
||||||
|
#else
|
||||||
|
# define htonl_c(n) __bswap_constant_32 (n)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const struct scopeentry
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
char addr[4];
|
||||||
|
uint32_t addr32;
|
||||||
|
};
|
||||||
|
uint32_t netmask;
|
||||||
|
int32_t scope;
|
||||||
|
} default_scopes[] =
|
||||||
|
{
|
||||||
|
/* Link-local addresses: scope 2. */
|
||||||
|
{ { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
|
||||||
|
{ { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
|
||||||
|
/* Site-local addresses: scope 5. */
|
||||||
|
{ { { 10, 0, 0, 0 } }, htonl_c (0xff000000), 5 },
|
||||||
|
{ { { 172, 16, 0, 0 } }, htonl_c (0xfff00000), 5 },
|
||||||
|
{ { { 192, 168, 0, 0 } }, htonl_c (0xffff0000), 5 },
|
||||||
|
/* Default: scope 14. */
|
||||||
|
{ { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The label table. */
|
||||||
|
static const struct scopeentry *scopes;
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
get_scope (const struct sockaddr_storage *ss)
|
get_scope (const struct sockaddr_storage *ss)
|
||||||
{
|
{
|
||||||
@ -1038,17 +1070,17 @@ get_scope (const struct sockaddr_storage *ss)
|
|||||||
else if (ss->ss_family == PF_INET)
|
else if (ss->ss_family == PF_INET)
|
||||||
{
|
{
|
||||||
const struct sockaddr_in *in = (const struct sockaddr_in *) ss;
|
const struct sockaddr_in *in = (const struct sockaddr_in *) ss;
|
||||||
const uint8_t *addr = (const uint8_t *) &in->sin_addr;
|
|
||||||
|
|
||||||
/* RFC 3484 specifies how to map IPv6 addresses to scopes.
|
size_t cnt = 0;
|
||||||
169.254/16 and 127/8 are link-local. */
|
while (1)
|
||||||
if ((addr[0] == 169 && addr[1] == 254) || addr[0] == 127)
|
{
|
||||||
scope = 2;
|
if ((in->sin_addr.s_addr & scopes[cnt].netmask)
|
||||||
else if (addr[0] == 10 || (addr[0] == 172 && (addr[1] & 0xf0) == 16)
|
== scopes[cnt].addr32)
|
||||||
|| (addr[0] == 192 && addr[1] == 168))
|
return scopes[cnt].scope;
|
||||||
scope = 5;
|
|
||||||
else
|
++cnt;
|
||||||
scope = 14;
|
}
|
||||||
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* XXX What is a good default? */
|
/* XXX What is a good default? */
|
||||||
@ -1490,6 +1522,13 @@ libc_freeres_fn(fini)
|
|||||||
precedence = default_precedence;
|
precedence = default_precedence;
|
||||||
free ((void *) old);
|
free ((void *) old);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (scopes != default_scopes)
|
||||||
|
{
|
||||||
|
const struct scopeentry *old = scopes;
|
||||||
|
scopes = default_scopes;
|
||||||
|
free ((void *) old);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1500,6 +1539,13 @@ struct prefixlist
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct scopelist
|
||||||
|
{
|
||||||
|
struct scopeentry entry;
|
||||||
|
struct scopelist *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_prefixlist (struct prefixlist *list)
|
free_prefixlist (struct prefixlist *list)
|
||||||
{
|
{
|
||||||
@ -1512,6 +1558,18 @@ free_prefixlist (struct prefixlist *list)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_scopelist (struct scopelist *list)
|
||||||
|
{
|
||||||
|
while (list != NULL)
|
||||||
|
{
|
||||||
|
struct scopelist *oldp = list;
|
||||||
|
list = list->next;
|
||||||
|
free (oldp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
prefixcmp (const void *p1, const void *p2)
|
prefixcmp (const void *p1, const void *p2)
|
||||||
{
|
{
|
||||||
@ -1526,6 +1584,20 @@ prefixcmp (const void *p1, const void *p2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
scopecmp (const void *p1, const void *p2)
|
||||||
|
{
|
||||||
|
const struct scopeentry *e1 = (const struct scopeentry *) p1;
|
||||||
|
const struct scopeentry *e2 = (const struct scopeentry *) p2;
|
||||||
|
|
||||||
|
if (e1->netmask > e2->netmask)
|
||||||
|
return -1;
|
||||||
|
if (e1->netmask == e2->netmask)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gaiconf_init (void)
|
gaiconf_init (void)
|
||||||
{
|
{
|
||||||
@ -1535,6 +1607,9 @@ gaiconf_init (void)
|
|||||||
struct prefixlist *precedencelist = NULL;
|
struct prefixlist *precedencelist = NULL;
|
||||||
size_t nprecedencelist = 0;
|
size_t nprecedencelist = 0;
|
||||||
bool precedencelist_nullbits = false;
|
bool precedencelist_nullbits = false;
|
||||||
|
struct scopelist *scopelist = NULL;
|
||||||
|
size_t nscopelist = 0;
|
||||||
|
bool scopelist_nullbits = false;
|
||||||
|
|
||||||
FILE *fp = fopen (GAICONF_FNAME, "rc");
|
FILE *fp = fopen (GAICONF_FNAME, "rc");
|
||||||
if (fp != NULL)
|
if (fp != NULL)
|
||||||
@ -1625,7 +1700,7 @@ gaiconf_init (void)
|
|||||||
|| (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
|
|| (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
|
||||||
|| errno != ERANGE)
|
|| errno != ERANGE)
|
||||||
&& *endp == '\0'
|
&& *endp == '\0'
|
||||||
&& bits <= INT_MAX
|
&& bits <= 128
|
||||||
&& ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
|
&& ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
|
||||||
|| errno != ERANGE)
|
|| errno != ERANGE)
|
||||||
&& *endp == '\0'
|
&& *endp == '\0'
|
||||||
@ -1659,6 +1734,73 @@ gaiconf_init (void)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 7:
|
||||||
|
if (strcmp (cmd, "scopev4") == 0)
|
||||||
|
{
|
||||||
|
struct in6_addr prefix;
|
||||||
|
unsigned long int bits;
|
||||||
|
unsigned long int val;
|
||||||
|
char *endp;
|
||||||
|
|
||||||
|
bits = 32;
|
||||||
|
__set_errno (0);
|
||||||
|
cp = strchr (val1, '/');
|
||||||
|
if (cp != NULL)
|
||||||
|
*cp++ = '\0';
|
||||||
|
if (inet_pton (AF_INET6, val1, &prefix))
|
||||||
|
{
|
||||||
|
if (IN6_IS_ADDR_V4MAPPED (&prefix)
|
||||||
|
&& (cp == NULL
|
||||||
|
|| (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
|
||||||
|
|| errno != ERANGE)
|
||||||
|
&& *endp == '\0'
|
||||||
|
&& bits >= 96
|
||||||
|
&& bits <= 128
|
||||||
|
&& ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
|
||||||
|
|| errno != ERANGE)
|
||||||
|
&& *endp == '\0'
|
||||||
|
&& val <= INT_MAX)
|
||||||
|
{
|
||||||
|
struct scopelist *newp;
|
||||||
|
new_scope:
|
||||||
|
newp = malloc (sizeof (*newp));
|
||||||
|
if (newp == NULL)
|
||||||
|
{
|
||||||
|
free (line);
|
||||||
|
fclose (fp);
|
||||||
|
goto no_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
newp->entry.netmask = htonl (bits != 96
|
||||||
|
? (0xffffffff
|
||||||
|
<< (128 - bits))
|
||||||
|
: 0);
|
||||||
|
newp->entry.addr32 = (prefix.s6_addr32[3]
|
||||||
|
& newp->entry.netmask);
|
||||||
|
newp->entry.scope = val;
|
||||||
|
newp->next = scopelist;
|
||||||
|
scopelist = newp;
|
||||||
|
++nscopelist;
|
||||||
|
scopelist_nullbits |= bits == 96;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
|
||||||
|
&& (cp == NULL
|
||||||
|
|| (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
|
||||||
|
|| errno != ERANGE)
|
||||||
|
&& *endp == '\0'
|
||||||
|
&& bits <= 32
|
||||||
|
&& ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
|
||||||
|
|| errno != ERANGE)
|
||||||
|
&& *endp == '\0'
|
||||||
|
&& val <= INT_MAX)
|
||||||
|
{
|
||||||
|
bits += 96;
|
||||||
|
goto new_scope;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case 10:
|
case 10:
|
||||||
if (strcmp (cmd, "precedence") == 0)
|
if (strcmp (cmd, "precedence") == 0)
|
||||||
{
|
{
|
||||||
@ -1742,12 +1884,52 @@ gaiconf_init (void)
|
|||||||
|
|
||||||
/* Sort the entries so that the most specific ones are at
|
/* Sort the entries so that the most specific ones are at
|
||||||
the beginning. */
|
the beginning. */
|
||||||
qsort (new_precedence, nprecedencelist, sizeof (*new_labels),
|
qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
|
||||||
prefixcmp);
|
prefixcmp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
new_precedence = (struct prefixentry *) default_precedence;
|
new_precedence = (struct prefixentry *) default_precedence;
|
||||||
|
|
||||||
|
struct scopeentry *new_scopes;
|
||||||
|
if (nscopelist > 0)
|
||||||
|
{
|
||||||
|
if (!scopelist_nullbits)
|
||||||
|
++nscopelist;
|
||||||
|
new_scopes = malloc (nscopelist * sizeof (*new_scopes));
|
||||||
|
if (new_scopes == NULL)
|
||||||
|
{
|
||||||
|
if (new_labels != default_labels)
|
||||||
|
free (new_labels);
|
||||||
|
if (new_precedence != default_precedence)
|
||||||
|
free (new_precedence);
|
||||||
|
goto no_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = nscopelist;
|
||||||
|
if (!scopelist_nullbits)
|
||||||
|
{
|
||||||
|
--i;
|
||||||
|
new_scopes[i].addr32 = 0;
|
||||||
|
new_scopes[i].netmask = 0;
|
||||||
|
new_scopes[i].scope = 14;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct scopelist *l = scopelist;
|
||||||
|
while (i-- > 0)
|
||||||
|
{
|
||||||
|
new_scopes[i] = l->entry;
|
||||||
|
l = l->next;
|
||||||
|
}
|
||||||
|
free_scopelist (scopelist);
|
||||||
|
|
||||||
|
/* Sort the entries so that the most specific ones are at
|
||||||
|
the beginning. */
|
||||||
|
qsort (new_scopes, nscopelist, sizeof (*new_scopes),
|
||||||
|
scopecmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
new_scopes = (struct scopeentry *) default_scopes;
|
||||||
|
|
||||||
/* Now we are ready to replace the values. */
|
/* Now we are ready to replace the values. */
|
||||||
const struct prefixentry *old = labels;
|
const struct prefixentry *old = labels;
|
||||||
labels = new_labels;
|
labels = new_labels;
|
||||||
@ -1759,6 +1941,11 @@ gaiconf_init (void)
|
|||||||
if (old != default_precedence)
|
if (old != default_precedence)
|
||||||
free ((void *) old);
|
free ((void *) old);
|
||||||
|
|
||||||
|
const struct scopeentry *oldscope = scopes;
|
||||||
|
scopes = new_scopes;
|
||||||
|
if (oldscope != default_scopes)
|
||||||
|
free ((void *) oldscope);
|
||||||
|
|
||||||
gaiconf_mtime = st.st_mtim;
|
gaiconf_mtime = st.st_mtim;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1766,6 +1953,7 @@ gaiconf_init (void)
|
|||||||
no_file:
|
no_file:
|
||||||
free_prefixlist (labellist);
|
free_prefixlist (labellist);
|
||||||
free_prefixlist (precedencelist);
|
free_prefixlist (precedencelist);
|
||||||
|
free_scopelist (scopelist);
|
||||||
|
|
||||||
/* If we previously read the file but it is gone now, free the
|
/* If we previously read the file but it is gone now, free the
|
||||||
old data and use the builtin one. Leave the reload flag
|
old data and use the builtin one. Leave the reload flag
|
||||||
|
Loading…
Reference in New Issue
Block a user