diff --git a/CHANGES b/CHANGES index effcf1e8b1..7633bded32 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +4109. [port] linux: support reading the local port range from + net.ipv4.ip_local_port_range. [RT # 39379] + 4108. [func] An additional NXDOMAIN redirect method (option "nxdomain-redirect") has been added, allowing redirection to a specified DNS namespace instead diff --git a/doc/arm/notes.xml b/doc/arm/notes.xml index 012bcf6dd8..2dea1edc92 100644 --- a/doc/arm/notes.xml +++ b/doc/arm/notes.xml @@ -488,6 +488,12 @@ to be configured on the server is now available. + + + Retrieving the local port range from net.ipv4.ip_local_port_range + on Linux is now supported. + + diff --git a/lib/isc/unix/net.c b/lib/isc/unix/net.c index 0fa038885a..9bcd189225 100644 --- a/lib/isc/unix/net.c +++ b/lib/isc/unix/net.c @@ -778,12 +778,12 @@ getudpportrange_sysctl(int af, in_port_t *low, in_port_t *high) { sysctlname_lowport = SYSCTL_V6PORTRANGE_LOW; sysctlname_hiport = SYSCTL_V6PORTRANGE_HIGH; } - portlen = sizeof(portlen); + portlen = sizeof(port_low); if (sysctlbyname(sysctlname_lowport, &port_low, &portlen, NULL, 0) < 0) { return (ISC_R_FAILURE); } - portlen = sizeof(portlen); + portlen = sizeof(port_high); if (sysctlbyname(sysctlname_hiport, &port_high, &portlen, NULL, 0) < 0) { return (ISC_R_FAILURE); @@ -817,12 +817,12 @@ getudpportrange_sysctl(int af, in_port_t *low, in_port_t *high) { miblen = sizeof(mib_lo6) / sizeof(mib_lo6[0]); } - portlen = sizeof(portlen); + portlen = sizeof(port_low); if (sysctl(mib_lo, miblen, &port_low, &portlen, NULL, 0) < 0) { return (ISC_R_FAILURE); } - portlen = sizeof(portlen); + portlen = sizeof(port_high); if (sysctl(mib_hi, miblen, &port_high, &portlen, NULL, 0) < 0) { return (ISC_R_FAILURE); } @@ -841,11 +841,34 @@ getudpportrange_sysctl(int af, in_port_t *low, in_port_t *high) { isc_result_t isc_net_getudpportrange(int af, in_port_t *low, in_port_t *high) { int result = ISC_R_FAILURE; +#if !defined(USE_SYSCTL_PORTRANGE) && defined(__linux) + FILE *fp; +#endif REQUIRE(low != NULL && high != NULL); #if defined(USE_SYSCTL_PORTRANGE) result = getudpportrange_sysctl(af, low, high); +#elif defined(__linux) + + UNUSED(af); + + /* + * Linux local ports are address family agnostic. + */ + fp = fopen("/proc/sys/net/ipv4/ip_local_port_range", "r"); + if (fp != NULL) { + int n; + unsigned int l, h; + + n = fscanf(fp, "%u %u", &l, &h); + if (n == 2 && (l & ~0xffff) == 0 && (h & ~0xffff) == 0) { + *low = l; + *high = h; + result = ISC_R_SUCCESS; + } + fclose(fp); + } #else UNUSED(af); #endif