bind/feature-bind99-euler-range-port.patch
songnannan e152f570a8 init
2019-12-28 09:41:34 +08:00

283 lines
7.3 KiB
Diff

diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c
index c93651d..d03ef2d 100644
--- a/lib/dns/dispatch.c
+++ b/lib/dns/dispatch.c
@@ -49,6 +49,7 @@
#include <dns/tcpmsg.h>
#include <dns/types.h>
+const char *conffile = "/etc/dns_port.conf";
typedef ISC_LIST(dns_dispentry_t) dns_displist_t;
typedef struct dispsocket dispsocket_t;
@@ -1933,6 +1934,168 @@ open_socket(isc_socketmgr_t *mgr, isc_sockaddr_t *local,
return (ISC_R_SUCCESS);
}
+static int convert_num(char *str)
+{
+ int negative = 0;
+ int tval;
+ int val = 0;
+ int base = 10;
+ char *ptr = str;
+ if (str == NULL)
+ return -ISC_R_FAILURE;
+
+ if (*ptr == '-') {
+ negative = 1;
+ ++ptr;
+ }
+
+ do {
+ tval = *ptr++;
+ /* XXX assumes ASCII... */
+ if (tval >= '0')
+ tval -= '0';
+ else {
+ syslog (LOG_ERR, "Bogus number: %s.", str);
+ return -ISC_R_BADNUMBER;
+ }
+ if (tval >= base) {
+ syslog (LOG_ERR, "Bogus number: %s.", str);
+ return -ISC_R_BADNUMBER;
+ }
+ val = val * base + tval;
+ } while (*ptr);
+
+ if (negative)
+ val = -val;
+ return val;
+}
+
+static int str_token(char *str, int *digit, unsigned int len, const char *semi)
+{
+ int num = 0;
+ char *p;
+ p = strtok(str, semi);
+ while (p !=NULL) {
+ if (num >= len-1) {
+ digit[num] = '\0';
+ break;
+ }
+ /* convert string to integer */
+ digit[num] = convert_num(p);
+ if (digit[num] < 0)
+ return -ISC_R_BADNUMBER;
+
+ p = strtok(NULL, semi);
+ num++;
+ }
+
+ return num;
+}
+
+static int parse_port_config(const char *buffer, const char *sub_buf, int *ports, unsigned int len, const char *semi)
+{
+ char *str;
+ char string[256] = {0};
+ int start, end;
+ int ret = -ISC_R_DISABLED;
+
+ if (str = strstr(buffer, sub_buf)) {
+ start = strlen(sub_buf);
+ end = strlen(str);
+ strncpy(string, str + start, end - start -1);
+ /* string segmentation with semi character */
+ ret = str_token(string, ports, len, semi);
+ if (ret < 0)
+ return -ISC_R_BADNUMBER;
+ }
+
+ return ret;
+}
+
+static isc_result_t
+parse_config(const char *file, in_port_t *port_lo, in_port_t *port_hi, in_port_t *no_use_ports)
+{
+ FILE *fp;
+ char *str = NULL;
+ char buffer[256] = {0};
+ int ports[8] = {0};
+ int unports[17] = {0};
+ int i = 0;
+ int ret;
+
+ fp = fopen(file, "r");
+ if (fp) {
+ while (fgets(buffer, 256, fp)) {
+ const char *buffer_s = buffer;
+ str = buffer;
+ /* skip the comment line */
+ while (isspace(*str))
+ str++;
+ if (strncmp(str, "#", 1) == 0)
+ continue;
+ /* get default set of dispatch ports */
+ ret = parse_port_config(buffer_s, "dns-range-port", ports, 8, " ");
+ if (ret == 2) {
+ *port_lo = (in_port_t)ports[0];
+ *port_hi = (in_port_t)ports[1];
+ if (*port_lo < 1024 || *port_hi > 65535 || *port_lo > *port_hi) {
+ syslog(LOG_ERR,
+ "Unexpected ports contents in %s file.", file);
+ fclose(fp);
+ fp = NULL;
+ return ISC_R_INVALIDFILE;
+ }
+ } else if (ret != -ISC_R_DISABLED){
+ syslog(LOG_ERR,
+ "Unexpected ports contents in %s file.", file);
+ fclose(fp);
+ fp = NULL;
+ return ISC_R_INVALIDFILE;
+ }
+ /* get excluded ports */
+ ret = parse_port_config(buffer_s, "dns-excluded-ports", unports, 17, " ");
+ if (ret > 0) {
+ while (unports[i] != '\0') {
+ no_use_ports[i] = (in_port_t)unports[i];
+ i++;
+ }
+ } else if (ret != -ISC_R_DISABLED) {
+ syslog(LOG_ERR,
+ "Unexpected ports contents in %s file.", file);
+ fclose(fp);
+ fp = NULL;
+ return ISC_R_INVALIDFILE;
+ }
+ }
+
+ fclose(fp);
+ fp = NULL;
+ return ISC_R_SUCCESS;
+ }
+
+ syslog(LOG_ERR,
+ "Open %s fail, return.\n", file);
+ return ISC_R_FILENOTFOUND;
+}
+
+/*%
+ * Create a temporary port list to set the initial default set of dispatch
+ * ports and excluded ports. This is almost meaningless as the application will
+ * normally set the ports explicitly, but is provided to fill some minor corner
+ * cases.
+ */
+static isc_result_t
+create_portset_by_range(isc_mem_t *mctx, isc_portset_t **portsetp, in_port_t port_lo, in_port_t port_hi, in_port_t *no_use_ports) {
+ isc_result_t result;
+
+ result = isc_portset_create(mctx, portsetp);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ isc_portset_addrange_by_range(*portsetp, port_lo, port_hi, no_use_ports);
+
+ return (ISC_R_SUCCESS);
+}
+
/*%
* Create a temporary port list to set the initial default set of dispatch
* ports: [1024, 65535]. This is almost meaningless as the application will
@@ -1963,6 +2125,9 @@ dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy,
isc_result_t result;
isc_portset_t *v4portset = NULL;
isc_portset_t *v6portset = NULL;
+ in_port_t port_lo = 1024;
+ in_port_t port_hi = 65535;
+ in_port_t no_use_ports[17] = {0};
REQUIRE(mctx != NULL);
REQUIRE(mgrp != NULL && *mgrp == NULL);
@@ -2063,14 +2228,23 @@ dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy,
mgr->nv6ports = 0;
mgr->magic = DNS_DISPATCHMGR_MAGIC;
- result = create_default_portset(mctx, &v4portset);
+ /* parse port list file, get default set of dispatch ports and excluded ports */
+ result = parse_config(conffile, &port_lo, &port_hi, no_use_ports);
if (result == ISC_R_SUCCESS) {
- result = create_default_portset(mctx, &v6portset);
- if (result == ISC_R_SUCCESS) {
- result = dns_dispatchmgr_setavailports(mgr,
- v4portset,
- v6portset);
- }
+ create_portset_by_range(mctx, &v4portset, port_lo, port_hi, no_use_ports);
+ if (result == ISC_R_SUCCESS)
+ result = create_portset_by_range(mctx, &v6portset, port_lo, port_hi, no_use_ports);
+ }
+ else {
+ result = create_default_portset(mctx, &v4portset);
+ if (result == ISC_R_SUCCESS)
+ result = create_default_portset(mctx, &v6portset);
+ }
+
+ if (result == ISC_R_SUCCESS) {
+ result = dns_dispatchmgr_setavailports(mgr,
+ v4portset,
+ v6portset);
}
if (v4portset != NULL)
isc_portset_destroy(mctx, &v4portset);
diff --git a/lib/isc/include/isc/portset.h b/lib/isc/include/isc/portset.h
index 774d6bb..cfd0bcb 100644
--- a/lib/isc/include/isc/portset.h
+++ b/lib/isc/include/isc/portset.h
@@ -125,6 +125,19 @@ isc_portset_addrange(isc_portset_t *portset, in_port_t port_lo,
*/
void
+isc_portset_addrange_by_range(isc_portset_t *portset, in_port_t port_lo,
+ in_port_t port_hi, in_port_t *no_use_ports);
+/*%<
+ * Add a subset of [port_lo, port_hi] (inclusive) and no_use_ports(exclusive) to the portset. Ports in the
+ * subset may or may not be stored in portset.
+ *
+ * Requires:
+ *\li 'portlist' to be valid.
+ *\li port_lo <= port_hi
+ *\li no_use_ports > 0
+ */
+
+void
isc_portset_removerange(isc_portset_t *portset, in_port_t port_lo,
in_port_t port_hi);
/*%<
diff --git a/lib/isc/portset.c b/lib/isc/portset.c
index 471ca8e..0ebd79f 100644
--- a/lib/isc/portset.c
+++ b/lib/isc/portset.c
@@ -128,6 +128,31 @@ isc_portset_addrange(isc_portset_t *portset, in_port_t port_lo,
}
void
+isc_portset_addrange_by_range(isc_portset_t *portset, in_port_t port_lo,
+ in_port_t port_hi, in_port_t *no_use_ports)
+{
+ in_port_t p;
+ int i, flag;
+ REQUIRE(portset != NULL);
+ REQUIRE(port_lo <= port_hi);
+
+ p = port_lo;
+ do {
+ i = 0;
+ flag = 0;
+ while (no_use_ports[i] != '\0') {
+ if (no_use_ports[i] == p) {
+ flag = 1;
+ break;
+ }
+ i++;
+ }
+ if (flag == 0)
+ portset_add(portset, p);
+ } while (p++ < port_hi);
+}
+
+void
isc_portset_removerange(isc_portset_t *portset, in_port_t port_lo,
in_port_t port_hi)
{