File: use-system-rootserver-hints.patch

package info (click to toggle)
belle-sip 5.3.105%2Bdfsg-4.1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 12,480 kB
  • sloc: ansic: 276,717; cpp: 3,172; cs: 418; makefile: 185; python: 86; xml: 47; sh: 41; objc: 38; ruby: 8
file content (174 lines) | stat: -rw-r--r-- 5,249 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
Description: Use root.hints from dns-root-data
 This patch enables loading DNS root server hints as offered by
 package dns-root-data (or using equivalent paths under /usr/local) if
 they are available.  Otherwise the compiled-in defaults are used.
 .
 Setting BELLE_SIP_NO_SYS_ROOT_HINTS in the environment disables this
 feature.  Setting BELLE_SIP_LOG_ROOT_HINTS in the environment logs
 the loaded root server definitions to stderr which can be used to
 reveal discrepancies.
 .
 The code is short and easy to understand, though not very efficient,
 but since it runs only once at start-up that should not matter much.
Bug-Debian: https://bugs.debian.org/760467
Author: Dennis Filder <d.filder@web.de>
Last-Update: 2021-12-03
Forwarded: not-needed
--- a/src/dns/dns.c
+++ b/src/dns/dns.c
@@ -5856,11 +5856,120 @@
 	return 0;
 } /* dns_hints_local() */
 
+struct rootserver {
+	int af;
+	char addr[INET6_ADDRSTRLEN];
+};
+
+static int learn_system_root_servers(struct rootserver **servers_pp, size_t *nentries) {
+	static const char *Hint_paths[] = {
+		"/usr/local/share/dns/root.hints",
+		"/usr/share/dns/root.hints",
+		NULL
+	};
+
+	FILE *fp;
+	char *hintfile;
+	int addrfam = AF_INET, linecount=0, stillgood = 1;
+	struct rootserver *servers = NULL;
+	size_t nservers = 0;
+
+	for (hintfile = (char*) Hint_paths[0]; hintfile; hintfile++) {
+		if ((fp = fopen(hintfile, "r")) != NULL)
+			break;
+	}
+
+	if (fp == NULL) {
+		fprintf(stderr, "Error: parse-root-hints: could not open any root.hints file.  Aborting.\n");
+		return -1;
+	}
+
+	do {
+		size_t linelen=0;
+		char *line = NULL;
+		errno = 0;
+		ssize_t res = getline(&line, &linelen, fp);
+
+		if (res == -1) {
+			if (errno != 0) /* something irrecoverable happened */
+				stillgood = 0;
+			break;
+		}
+		linecount++;
+
+		if (line) {
+			if ( ( line[0] >= 'A' && line[0] <= 'Z' )
+			     && linelen >= strlen("*.ROOT-SERVERS.NET.")
+			     && memcmp(line+1, ".ROOT-SERVERS.NET.", strlen(".ROOT-SERVERS.NET.")) == 0) {
+				char *rr = NULL, *ipaddr = NULL;
+				int ret = sscanf(line, " %*s %*s %ms %ms ", &rr, &ipaddr);
+
+				if (ret == 2) {
+					if (rr && strlen(rr) == strlen("AAAA") && strcmp(rr, "AAAA") == 0) {
+						addrfam = AF_INET6;
+					} else if (rr && strlen(rr) == strlen("A") && strcmp(rr, "A") == 0) {
+						addrfam = AF_INET;
+					} else {
+						fprintf(stderr, "Warning: bogus resource record %s in %s, line %d.  Skipping.\n", rr, hintfile, linecount);
+						goto free_fields;
+					}
+
+					if (ipaddr && strlen(ipaddr) >= 1) {
+						/* we got a new server definition, add it! */
+						nservers++;
+
+						struct rootserver *p = realloc(servers, sizeof(struct rootserver) * nservers);
+						if (p == NULL) {
+							if (servers)
+								free(servers);
+							nservers = 0;
+							servers = NULL;
+							fprintf(stderr, "Error: out of memory.	Aborting.\n");
+							stillgood = 0;
+							goto free_fields;
+						}
+						servers = p;
+
+						memset(&servers[nservers-1], 0, sizeof(struct rootserver));
+						servers[nservers-1].af = addrfam;
+						strncpy(servers[nservers-1].addr, ipaddr, INET6_ADDRSTRLEN);
+						servers[nservers-1].addr[INET6_ADDRSTRLEN-1] = '\0';
+					}
+
+				}
+			free_fields:
+				if (rr)
+					free(rr);
+				if (ipaddr)
+					free(ipaddr);
+			}
+
+			free(line);
+			line = NULL;
+			linelen = 0;
+			res = 0;
+			if (stillgood)
+				continue;
+		} else {
+			break;
+		}
+
+	} while (1);
+
+	if (fp)
+		fclose(fp);
+
+	if (stillgood && nservers >= 1) {
+		*servers_pp = servers;
+		*nentries = nservers;
+		return 0;
+	}
+	return -1;
+} /* learn_system_root_servers() */
+
 struct dns_hints *dns_hints_root(struct dns_resolv_conf *resconf, int *error_) {
-	static const struct {
-		int af;
-		char addr[INET6_ADDRSTRLEN];
-	} root_hints[] = {
+	static const struct rootserver
+	fallback_root_hints[] = {
 	    {AF_INET, "198.41.0.4"},            /* A.ROOT-SERVERS.NET. */
 	    {AF_INET6, "2001:503:ba3e::2:30"},  /* A.ROOT-SERVERS.NET. */
 	    {AF_INET, "192.228.79.201"},        /* B.ROOT-SERVERS.NET. */
@@ -5887,6 +5996,16 @@
 	    {AF_INET, "202.12.27.33"},          /* M.ROOT-SERVERS.NET. */
 	    {AF_INET6, "2001:DC3::35"},         /* M.ROOT-SERVERS.NET. */
 	};
+	struct rootserver *sys_root_hints, *root_hints;
+	size_t nsys_root_hints, nroot_hints, nfallback_root_hints = lengthof(fallback_root_hints);
+	int ret = learn_system_root_servers(&sys_root_hints, &nsys_root_hints);
+	if (ret == -1 || getenv("BELLE_SIP_NO_SYS_ROOT_HINTS")) {
+		root_hints = (struct rootserver *)&fallback_root_hints[0];
+		nroot_hints = nfallback_root_hints;
+	} else {
+		root_hints = sys_root_hints;
+		nroot_hints = nsys_root_hints;
+	}
 	struct dns_hints *hints = 0;
 	struct sockaddr_storage ss;
 	unsigned i;
@@ -5895,9 +6014,12 @@
 	if (!(hints = dns_hints_open(resconf, &error))) goto error;
 
-	for (i = 0; i < lengthof(root_hints); i++) {
+	for (i = 0; i < nroot_hints; i++) {
 		af = root_hints[i].af;
 
 		if ((error = dns_pton(af, root_hints[i].addr, dns_sa_addr(af, &ss, NULL)))) goto error;
+		if (getenv("BELLE_SIP_LOG_ROOT_HINTS")) {
+			fprintf(stderr, "src/dns/dns.c:dns_hints_root():addr=%s, af=%d\n",root_hints[i].addr,af);
+		}
 
 		*dns_sa_port(af, &ss) = htons(53);
 		ss.ss_family = af;