diff --git a/.gitignore b/.gitignore index 4fa6c09..5c781e9 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/unbound-1.7.3.tar.gz +SOURCES/unbound-1.16.2.tar.gz diff --git a/.unbound.metadata b/.unbound.metadata index 4552023..c8b7a90 100644 --- a/.unbound.metadata +++ b/.unbound.metadata @@ -1 +1 @@ -106789bdca173d033d769c67be3441b47611612a SOURCES/unbound-1.7.3.tar.gz +9aea0e923b9d6779b5bc360094e24a4017e2bb25 SOURCES/unbound-1.16.2.tar.gz diff --git a/SOURCES/icannbundle.pem b/SOURCES/icannbundle.pem index d76ce0b..ceeef5b 100644 --- a/SOURCES/icannbundle.pem +++ b/SOURCES/icannbundle.pem @@ -1,59 +1,3 @@ -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 1 (0x1) - Signature Algorithm: sha256WithRSAEncryption - Issuer: O=ICANN, OU=ICANN Certification Authority, CN=ICANN Root CA, C=US - Validity - Not Before: Dec 23 04:19:12 2009 GMT - Not After : Dec 18 04:19:12 2029 GMT - Subject: O=ICANN, OU=ICANN Certification Authority, CN=ICANN Root CA, C=US - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - RSA Public Key: (2048 bit) - Modulus (2048 bit): - 00:a0:db:70:b8:4f:34:da:9c:d4:d0:7e:bb:ea:15: - bc:e9:c9:11:2a:1f:61:2f:6a:b9:bd:3f:3d:76:a0: - 9a:0a:f7:ee:93:6e:6e:55:53:84:8c:f2:2c:f1:82: - 27:c8:0f:9a:cf:52:1b:54:da:28:d2:2c:30:8e:dd: - fb:92:20:33:2d:d6:c8:f1:0e:10:21:88:71:fa:84: - 22:4b:5d:47:56:16:7c:9b:9f:5d:c3:11:79:9c:14: - e2:ff:c0:74:ac:dd:39:d7:e0:38:d8:b0:73:aa:fb: - d1:db:84:af:52:22:a8:f6:d5:9b:94:f4:e6:5d:5e: - e8:3f:87:90:0b:c7:1a:77:f5:2e:d3:8f:1a:ce:02: - 1d:07:69:21:47:32:da:46:ae:00:4c:b6:a5:a2:9c: - 39:c1:c0:4a:f6:d3:1c:ae:d3:6d:bb:c7:18:f0:7e: - ed:f6:80:ce:d0:01:2e:89:de:12:ba:ee:11:cb:a6: - 7a:d7:0d:7c:f3:08:8d:72:9d:bf:55:75:13:70:bb: - 31:22:4a:cb:e8:c0:aa:a4:09:aa:36:68:40:60:74: - 9d:e7:19:81:43:22:52:fe:c9:2b:52:0f:41:13:36: - 09:72:65:95:cc:89:ae:6f:56:17:16:34:73:52:a3: - 04:ed:bd:88:82:8a:eb:d7:dc:82:52:9c:06:e1:52: - 85:41 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE - X509v3 Key Usage: critical - Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment, Key Agreement, Certificate Sign, CRL Sign - X509v3 Subject Key Identifier: - BA:52:E9:49:83:24:86:52:2F:C7:99:CD:FC:8D:6B:69:08:4D:C0:50 - Signature Algorithm: sha256WithRSAEncryption - 0f:f1:e9:82:a2:0a:87:9f:2d:94:60:5a:b2:c0:4b:a1:2f:2b: - 3b:47:d5:0a:99:86:38:b2:ec:c6:3b:89:e4:6e:07:cf:14:c7: - c7:e8:cf:99:8f:aa:30:c3:19:70:b9:e6:6d:d6:3f:c8:68:26: - b2:a0:a5:37:42:ca:d8:62:80:d1:a2:5a:48:2e:1f:85:3f:0c: - 7b:c2:c7:94:11:5f:19:2a:95:ac:a0:3a:03:d8:91:5b:2e:0d: - 9c:7c:1f:2e:fc:e9:44:e1:16:26:73:1c:45:4a:65:c1:83:4c: - 90:f3:f2:28:42:df:db:c4:e7:04:12:18:62:43:5e:bc:1f:6c: - 84:e6:bc:49:32:df:61:d7:99:ee:e4:90:52:7b:0a:c2:91:8a: - 98:62:66:b1:c8:e0:b7:5a:b5:46:7c:76:71:54:8e:cc:a4:81: - 5c:19:db:d2:6f:66:b5:bb:2b:ae:6b:c9:74:04:a8:24:de:e8: - c5:d3:fc:2c:1c:d7:8f:db:6a:8d:c9:53:be:5d:50:73:ac:cf: - 1f:93:c0:52:50:5b:a2:4f:fe:ad:65:36:17:46:d1:2d:e5:a2: - 90:66:05:db:29:4e:5d:50:5d:e3:4f:da:a0:8f:f0:6b:e4:16: - 70:dd:7f:f3:77:7d:b9:4e:f9:ec:c3:33:02:d7:e9:63:2f:31: - e7:40:61:a4 -----BEGIN CERTIFICATE----- MIIDdzCCAl+gAwIBAgIBATANBgkqhkiG9w0BAQsFADBdMQ4wDAYDVQQKEwVJQ0FO TjEmMCQGA1UECxMdSUNBTk4gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxFjAUBgNV @@ -75,163 +19,3 @@ DQEBCwUAA4IBAQAP8emCogqHny2UYFqywEuhLys7R9UKmYY4suzGO4nkbgfPFMfH 0/wsHNeP22qNyVO+XVBzrM8fk8BSUFuiT/6tZTYXRtEt5aKQZgXbKU5dUF3jT9qg j/Br5BZw3X/zd325TvnswzMC1+ljLzHnQGGk -----END CERTIFICATE----- -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 11 (0xb) - Signature Algorithm: sha256WithRSAEncryption - Issuer: O=ICANN, OU=ICANN Certification Authority, CN=ICANN Root CA, C=US - Validity - Not Before: Nov 8 23:39:47 2016 GMT - Not After : Nov 6 23:39:47 2026 GMT - Subject: O=ICANN, CN=ICANN EMAIL CA - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - RSA Public Key: (2048 bit) - Modulus (2048 bit): - 00:d2:19:1e:22:69:33:f6:a4:d2:76:c5:80:11:75: - 8e:d0:e8:6f:bf:89:f8:2a:6a:da:8a:85:28:40:ba: - c5:23:5f:47:ed:72:e2:8e:d3:5c:c8:8a:3a:99:a9: - 57:2c:0a:2b:22:f3:54:7b:8b:f7:8c:21:a2:50:01: - 4f:8b:af:34:df:72:fc:78:31:d0:1d:eb:bc:9b:e6: - fa:c1:84:d0:05:07:8a:74:53:a5:60:9e:eb:75:9e: - a8:5d:32:c8:02:32:e4:bf:cb:97:9b:7a:fa:2c:f6: - 6a:1d:b8:57:ad:e3:03:22:93:d0:f4:4f:a8:b8:01: - db:82:33:98:b6:87:ed:3d:67:40:00:27:2e:d5:95: - d2:ad:36:46:14:c6:17:79:65:7f:65:f3:88:80:65: - 7c:22:67:08:23:3c:cf:a5:10:38:72:30:97:92:6f: - 20:4a:ba:24:4c:4a:c8:4a:a5:dc:2a:44:a1:29:78: - b4:9f:fe:84:ff:27:5b:3a:72:ea:31:c1:ad:06:22: - d6:44:a0:4a:57:32:9c:f2:46:47:d0:89:6e:20:23: - 2c:ea:b0:83:7e:c1:f3:ea:da:dd:e3:63:59:97:21: - fa:1b:11:39:27:cf:82:8b:56:15:d4:36:92:0c:a5: - 7e:80:e0:18:c9:50:08:42:0a:df:97:3c:9c:b8:0a: - 4d:b1 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Authority Key Identifier: - keyid:BA:52:E9:49:83:24:86:52:2F:C7:99:CD:FC:8D:6B:69:08:4D:C0:50 - - X509v3 Subject Key Identifier: - 7B:3F:BA:CE:A1:B3:A6:13:2E:5A:82:84:D4:D2:EA:A5:24:F1:CD:B4 - Signature Algorithm: sha256WithRSAEncryption - 0e:8a:c9:ea:6f:9c:e9:23:b6:9c:a6:a4:c2:d1:b1:ee:25:18: - 24:2b:79:d4:a8:f2:99:b9:5c:91:4d:e6:2b:32:2e:01:f5:87: - 95:64:fc:6d:f1:87:fa:24:b4:43:4b:49:f3:84:54:44:eb:af: - 41:ab:49:ab:c8:b7:32:6c:14:83:5b:d7:2c:41:f9:89:d5:c4: - 2b:9a:55:c5:b6:ad:17:d5:4d:bc:41:58:56:72:0d:db:b7:7d: - 57:c6:a2:9c:7e:6b:67:ae:26:f8:26:45:bb:c4:95:2e:ea:71: - e3:b4:7a:69:95:a4:8a:80:f8:59:dc:88:6e:e1:a7:fc:bb:8e: - b2:aa:a8:b6:1b:2f:2c:97:a5:12:d5:82:ae:a0:e8:a6:15:fd: - d1:e0:5d:e4:84:b1:76:db:0a:e2:ca:58:2e:d3:df:48:4e:46: - ac:c6:35:79:17:99:ce:e9:be:2c:e4:c2:50:ff:5b:96:15:cd: - 64:ac:1b:db:fe:d2:ac:43:61:c8:5f:ee:24:b6:a4:3b:d2:ff: - 0a:f4:0c:88:58:a1:9d:a4:c1:1f:6a:6c:67:90:98:e8:1f:5e: - 2d:55:60:91:26:2a:b1:66:80:e4:e6:0e:05:2c:75:a9:ca:0b: - e4:a0:8f:e1:47:a8:8f:61:5d:7c:ce:09:60:88:48:c3:46:bf: - be:7e:36:be ------BEGIN CERTIFICATE----- -MIIDZDCCAkygAwIBAgIBCzANBgkqhkiG9w0BAQsFADBdMQ4wDAYDVQQKEwVJQ0FO -TjEmMCQGA1UECxMdSUNBTk4gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxFjAUBgNV -BAMTDUlDQU5OIFJvb3QgQ0ExCzAJBgNVBAYTAlVTMB4XDTE2MTEwODIzMzk0N1oX -DTI2MTEwNjIzMzk0N1owKTEOMAwGA1UEChMFSUNBTk4xFzAVBgNVBAMTDklDQU5O -IEVNQUlMIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0hkeImkz -9qTSdsWAEXWO0Ohvv4n4KmraioUoQLrFI19H7XLijtNcyIo6malXLAorIvNUe4v3 -jCGiUAFPi68033L8eDHQHeu8m+b6wYTQBQeKdFOlYJ7rdZ6oXTLIAjLkv8uXm3r6 -LPZqHbhXreMDIpPQ9E+ouAHbgjOYtoftPWdAACcu1ZXSrTZGFMYXeWV/ZfOIgGV8 -ImcIIzzPpRA4cjCXkm8gSrokTErISqXcKkShKXi0n/6E/ydbOnLqMcGtBiLWRKBK -VzKc8kZH0IluICMs6rCDfsHz6trd42NZlyH6GxE5J8+Ci1YV1DaSDKV+gOAYyVAI -QgrflzycuApNsQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE -AwIBBjAfBgNVHSMEGDAWgBS6UulJgySGUi/Hmc38jWtpCE3AUDAdBgNVHQ4EFgQU -ez+6zqGzphMuWoKE1NLqpSTxzbQwDQYJKoZIhvcNAQELBQADggEBAA6KyepvnOkj -tpympMLRse4lGCQredSo8pm5XJFN5isyLgH1h5Vk/G3xh/oktENLSfOEVETrr0Gr -SavItzJsFINb1yxB+YnVxCuaVcW2rRfVTbxBWFZyDdu3fVfGopx+a2euJvgmRbvE -lS7qceO0emmVpIqA+FnciG7hp/y7jrKqqLYbLyyXpRLVgq6g6KYV/dHgXeSEsXbb -CuLKWC7T30hORqzGNXkXmc7pvizkwlD/W5YVzWSsG9v+0qxDYchf7iS2pDvS/wr0 -DIhYoZ2kwR9qbGeQmOgfXi1VYJEmKrFmgOTmDgUsdanKC+Sgj+FHqI9hXXzOCWCI -SMNGv75+Nr4= ------END CERTIFICATE----- -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 10 (0xa) - Signature Algorithm: sha256WithRSAEncryption - Issuer: O=ICANN, OU=ICANN Certification Authority, CN=ICANN Root CA, C=US - Validity - Not Before: Nov 8 23:38:16 2016 GMT - Not After : Nov 6 23:38:16 2026 GMT - Subject: O=ICANN, CN=ICANN SSL CA - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - RSA Public Key: (2048 bit) - Modulus (2048 bit): - 00:dd:c6:ab:bf:7c:66:9d:b3:2b:96:00:14:c7:60: - 7a:8d:62:5b:26:4b:30:d7:b3:4c:82:69:c6:4d:4d: - 73:f3:d4:91:21:5d:ab:35:f0:c8:04:0e:f4:a3:35: - e2:e1:18:a9:98:12:03:58:f8:9f:eb:77:54:5b:89: - 81:26:c9:aa:c2:f4:c9:0c:82:57:2a:5e:05:e9:61: - 17:cc:19:18:71:eb:35:83:c1:86:9d:ec:f1:6b:ca: - dd:a1:96:0b:95:d4:e1:0f:9e:24:6f:dc:3c:d0:28: - 9e:f2:53:47:2b:a1:ad:32:03:c8:3f:0d:80:80:7d: - f0:02:d2:6e:5a:2c:44:21:9b:09:50:15:3f:a1:3d: - d3:c9:c8:24:e7:ea:4e:92:2f:94:90:2e:de:e7:68: - f6:c6:b3:90:1f:bc:c9:7b:a2:65:d7:11:e9:8b:f0: - 3a:5a:b7:17:07:df:69:e3:6e:b9:54:6a:8e:3a:aa: - 94:7f:2c:0a:a1:ad:ba:b7:d9:60:62:27:a7:71:40: - 3b:8e:b0:84:7b:b8:c8:67:ef:66:ba:3d:ac:c3:85: - e5:86:bb:a7:9c:fd:b6:e1:c0:10:53:3d:d4:7e:1b: - 09:e6:9f:22:5c:a7:27:09:7e:27:12:33:fa:df:9b: - 20:2f:14:f7:17:c0:e4:1e:07:91:1f:f9:9a:cd:a8: - e2:c5 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Authority Key Identifier: - keyid:BA:52:E9:49:83:24:86:52:2F:C7:99:CD:FC:8D:6B:69:08:4D:C0:50 - - X509v3 Subject Key Identifier: - 6E:77:A8:40:10:4A:D8:9C:0C:F2:B7:5A:3A:A5:2F:79:4A:61:14:D8 - Signature Algorithm: sha256WithRSAEncryption - 47:46:4f:c7:5f:46:e3:d1:dc:fc:2b:f8:fc:65:ce:36:b1:f4: - 5f:ee:14:75:a3:d9:5f:de:75:4b:fa:7b:88:9f:10:8c:2e:97: - cc:35:1b:ce:24:d3:36:60:95:d5:ae:11:b6:3f:8b:f4:12:69: - 85:b5:3b:2a:b6:ab:7a:81:85:c2:55:57:ed:d0:b5:e7:4f:54: - 37:51:24:c9:d5:07:3a:ef:b6:c5:1a:3e:14:29:a7:a6:f8:08: - 2a:0b:26:79:f9:62:85:4a:e5:ea:90:ca:71:38:16:91:4e:7e: - fd:e3:b3:f3:55:8f:5a:d0:86:cf:33:94:88:f1:90:99:cb:81: - e2:81:92:68:2f:c3:61:d5:52:8d:e6:9a:5b:00:83:42:27:88: - f6:d9:fa:d1:bc:bb:b0:bc:b5:14:0b:4e:1a:54:ef:fa:d6:9d: - c4:0c:fc:ed:15:ab:21:4b:45:b5:d9:3b:ed:3c:d5:1e:2e:7a: - 83:6f:24:45:d4:4c:b4:ef:60:43:18:d0:84:5d:16:7b:f5:50: - 80:b1:a9:c2:8f:3b:c8:90:08:fd:aa:17:13:19:38:19:d1:8e: - 85:7c:1e:57:16:8c:f9:8a:e8:29:25:38:cd:bb:55:8e:4a:6a: - 6f:e5:7d:fc:d7:55:d6:ae:38:07:96:c1:97:ff:e5:2b:4f:99: - 2d:70:f2:08 ------BEGIN CERTIFICATE----- -MIIDYjCCAkqgAwIBAgIBCjANBgkqhkiG9w0BAQsFADBdMQ4wDAYDVQQKEwVJQ0FO -TjEmMCQGA1UECxMdSUNBTk4gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxFjAUBgNV -BAMTDUlDQU5OIFJvb3QgQ0ExCzAJBgNVBAYTAlVTMB4XDTE2MTEwODIzMzgxNloX -DTI2MTEwNjIzMzgxNlowJzEOMAwGA1UEChMFSUNBTk4xFTATBgNVBAMTDElDQU5O -IFNTTCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN3Gq798Zp2z -K5YAFMdgeo1iWyZLMNezTIJpxk1Nc/PUkSFdqzXwyAQO9KM14uEYqZgSA1j4n+t3 -VFuJgSbJqsL0yQyCVypeBelhF8wZGHHrNYPBhp3s8WvK3aGWC5XU4Q+eJG/cPNAo -nvJTRyuhrTIDyD8NgIB98ALSblosRCGbCVAVP6E908nIJOfqTpIvlJAu3udo9saz -kB+8yXuiZdcR6YvwOlq3FwffaeNuuVRqjjqqlH8sCqGturfZYGInp3FAO46whHu4 -yGfvZro9rMOF5Ya7p5z9tuHAEFM91H4bCeafIlynJwl+JxIz+t+bIC8U9xfA5B4H -kR/5ms2o4sUCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AQYwHwYDVR0jBBgwFoAUulLpSYMkhlIvx5nN/I1raQhNwFAwHQYDVR0OBBYEFG53 -qEAQSticDPK3WjqlL3lKYRTYMA0GCSqGSIb3DQEBCwUAA4IBAQBHRk/HX0bj0dz8 -K/j8Zc42sfRf7hR1o9lf3nVL+nuInxCMLpfMNRvOJNM2YJXVrhG2P4v0EmmFtTsq -tqt6gYXCVVft0LXnT1Q3USTJ1Qc677bFGj4UKaem+AgqCyZ5+WKFSuXqkMpxOBaR -Tn7947PzVY9a0IbPM5SI8ZCZy4HigZJoL8Nh1VKN5ppbAINCJ4j22frRvLuwvLUU -C04aVO/61p3EDPztFashS0W12TvtPNUeLnqDbyRF1Ey072BDGNCEXRZ79VCAsanC -jzvIkAj9qhcTGTgZ0Y6FfB5XFoz5iugpJTjNu1WOSmpv5X3811XWrjgHlsGX/+Ur -T5ktcPII ------END CERTIFICATE----- diff --git a/SOURCES/unbound-1.15-source-compat.patch b/SOURCES/unbound-1.15-source-compat.patch new file mode 100644 index 0000000..bb0a1de --- /dev/null +++ b/SOURCES/unbound-1.15-source-compat.patch @@ -0,0 +1,85 @@ +From fbde301c2706a5d0c9c3942fe84693f2b7a6b16c Mon Sep 17 00:00:00 2001 +From: Petr Mensik +Date: Sat, 7 May 2022 10:05:33 +0200 +Subject: [PATCH] Use reserved RCODE, fake source version + +Use RCODE value assigned for a private use. Previous value were possible +returned value. + +Fake source version to be still 1.7.x. Hide real version into micro +version component and export it also in a proper way with _REAL +suffixes. Should workaround any source code detection to support correct +callback format. Fixes compilation error in libreswan. + +Use preprocessed unbound.h to prevent failures + +Swig complains about wrong @ variable formats. Make it use preprocessed +header instead of a template. +--- + libunbound/python/libunbound.i | 4 ++-- + libunbound/unbound.h | 13 ++++++++++--- + services/mesh.h | 2 +- + 3 files changed, 13 insertions(+), 6 deletions(-) + +diff --git a/libunbound/python/libunbound.i b/libunbound/python/libunbound.i +index c9549bf90..f01e9111e 100644 +--- a/libunbound/python/libunbound.i ++++ b/libunbound/python/libunbound.i +@@ -53,7 +53,7 @@ + #ifdef HAVE_ARPA_INET_H + #include + #endif +- #include "libunbound/unbound.h" ++ #include "unbound.h" + %} + + %pythoncode %{ +@@ -855,7 +855,7 @@ Result: ['74.125.43.147', '74.125.43.99', '74.125.43.103', '74.125.43.104'] + //printf("resolve_stop()\n"); + %} + +-%include "libunbound/unbound.h" ++%include "unbound.h" + + %inline %{ + //SWIG will see the ub_ctx as a class +diff --git a/libunbound/unbound.h b/libunbound/unbound.h +index c822d3f89..82660bd51 100644 +--- a/libunbound/unbound.h ++++ b/libunbound/unbound.h +@@ -102,9 +102,16 @@ extern "C" { + #endif + + /** the version of this header file */ +-#define UNBOUND_VERSION_MAJOR @UNBOUND_VERSION_MAJOR@ +-#define UNBOUND_VERSION_MINOR @UNBOUND_VERSION_MINOR@ +-#define UNBOUND_VERSION_MICRO @UNBOUND_VERSION_MICRO@ ++/* Because of RHEL compat change, callback type remains at ++ * 1.7.3 version. To prevent source-level incompatibility, ++ * fake still old version. Export real version in _REAL ++ * suffix definitions. */ ++#define UNBOUND_VERSION_MAJOR 1 ++#define UNBOUND_VERSION_MINOR 7 ++#define UNBOUND_VERSION_MICRO @UNBOUND_VERSION_MAJOR@@UNBOUND_VERSION_MINOR@@UNBOUND_VERSION_MICRO@ ++#define UNBOUND_VERSION_MAJOR_REAL @UNBOUND_VERSION_MAJOR@ ++#define UNBOUND_VERSION_MINOR_REAL @UNBOUND_VERSION_MINOR@ ++#define UNBOUND_VERSION_MICRO_REAL @UNBOUND_VERSION_MICRO@ + + /** + * The validation context is created to hold the resolver status, +diff --git a/services/mesh.h b/services/mesh.h +index 9c6f958ff..c0cbf355e 100644 +--- a/services/mesh.h ++++ b/services/mesh.h +@@ -237,7 +237,7 @@ struct mesh_reply { + /* RHEL 8 compatibility layer. + * Special rcode to send was_ratelimited to callback without adding + * extra parameter. It is ORed to the rcode parameter of the callback. */ +-#define LDNS_RCODE_RATELIMITED 0x100 ++#define LDNS_RCODE_RATELIMITED 0xf80 + #define RCODE_IS_RATELIMITED(rcode) ((rcode & LDNS_RCODE_RATELIMITED) != 0) + #define RCODE_NOT_RATELIMITED(rcode) (rcode & ~LDNS_RCODE_RATELIMITED) + +-- +2.34.1 + diff --git a/SOURCES/unbound-1.15-soversion2-compat.patch b/SOURCES/unbound-1.15-soversion2-compat.patch new file mode 100644 index 0000000..897e243 --- /dev/null +++ b/SOURCES/unbound-1.15-soversion2-compat.patch @@ -0,0 +1,471 @@ +From 605d66f0b6b8f7c308010f455058299d25c1d2ee Mon Sep 17 00:00:00 2001 +From: Petr Mensik +Date: Fri, 6 May 2022 16:36:39 +0200 +Subject: [PATCH] Rework ABI breaking change to compatible way + +Upstream commit 749d1b9ebc6fcb79824afd0471a1cfc12ca861b1 introduced +was_ratelimited variable to every async callback. Such change led to ABI +break and increase of soname of libunbound. + +Use rcode to pass that boolean inside rcode variable. Allows keeping +original callback prototype, but does not lose data. Extra integer bit +operations should be very small price. Much better than ABI break. + +Make current version compatible back to .2 version. +--- + unbound-1.16.2/configure.ac | 2 +- + unbound-1.16.2/daemon/worker.c | 6 ++-- + unbound-1.16.2/libunbound/libworker.c | 34 +++++++++++++++-------- + unbound-1.16.2/libunbound/unbound-event.h | 3 +- + unbound-1.16.2/libunbound/unbound.h | 13 +++++---- + unbound-1.16.2/libunbound/worker.h | 6 ++-- + unbound-1.16.2/services/authzone.c | 11 ++++---- + unbound-1.16.2/services/authzone.h | 9 ++---- + unbound-1.16.2/services/mesh.c | 17 ++++++++---- + unbound-1.16.2/services/mesh.h | 9 +++++- + unbound-1.16.2/smallapp/worker_cb.c | 6 ++-- + unbound-1.16.2/validator/autotrust.c | 2 +- + unbound-1.16.2/validator/autotrust.h | 2 +- + 13 files changed, 72 insertions(+), 48 deletions(-) + +diff --git a/unbound-1.16.2/configure.ac b/unbound-1.16.2/configure.ac +index 224501b..71f066c 100644 +--- a/unbound-1.16.2/configure.ac ++++ b/unbound-1.16.2/configure.ac +@@ -19,7 +19,7 @@ AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO]) + + LIBUNBOUND_CURRENT=9 + LIBUNBOUND_REVISION=18 +-LIBUNBOUND_AGE=1 ++LIBUNBOUND_AGE=7 + # 1.0.0 had 0:12:0 + # 1.0.1 had 0:13:0 + # 1.0.2 had 0:14:0 +diff --git a/unbound-1.16.2/daemon/worker.c b/unbound-1.16.2/daemon/worker.c +index 010c4dc..2b87a41 100644 +--- a/unbound-1.16.2/daemon/worker.c ++++ b/unbound-1.16.2/daemon/worker.c +@@ -2268,21 +2268,21 @@ void libworker_handle_control_cmd(struct tube* ATTR_UNUSED(tube), + + void libworker_fg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode), + sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s), +- char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited)) ++ char* ATTR_UNUSED(why_bogus)) + { + log_assert(0); + } + + void libworker_bg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode), + sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s), +- char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited)) ++ char* ATTR_UNUSED(why_bogus)) + { + log_assert(0); + } + + void libworker_event_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode), + sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s), +- char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited)) ++ char* ATTR_UNUSED(why_bogus)) + { + log_assert(0); + } +diff --git a/unbound-1.16.2/libunbound/libworker.c b/unbound-1.16.2/libunbound/libworker.c +index 11bf5f9..6895119 100644 +--- a/unbound-1.16.2/libunbound/libworker.c ++++ b/unbound-1.16.2/libunbound/libworker.c +@@ -549,9 +549,10 @@ libworker_enter_result(struct ub_result* res, sldns_buffer* buf, + /** fillup fg results */ + static void + libworker_fillup_fg(struct ctx_query* q, int rcode, sldns_buffer* buf, +- enum sec_status s, char* why_bogus, int was_ratelimited) ++ enum sec_status s, char* why_bogus) + { +- q->res->was_ratelimited = was_ratelimited; ++ q->res->was_ratelimited = RCODE_IS_RATELIMITED(rcode); ++ rcode = RCODE_NOT_RATELIMITED(rcode); + if(why_bogus) + q->res->why_bogus = strdup(why_bogus); + if(rcode != 0) { +@@ -575,13 +576,13 @@ libworker_fillup_fg(struct ctx_query* q, int rcode, sldns_buffer* buf, + + void + libworker_fg_done_cb(void* arg, int rcode, sldns_buffer* buf, enum sec_status s, +- char* why_bogus, int was_ratelimited) ++ char* why_bogus) + { + struct ctx_query* q = (struct ctx_query*)arg; + /* fg query is done; exit comm base */ + comm_base_exit(q->w->base); + +- libworker_fillup_fg(q, rcode, buf, s, why_bogus, was_ratelimited); ++ libworker_fillup_fg(q, rcode, buf, s, why_bogus); + } + + /** setup qinfo and edns */ +@@ -634,7 +635,7 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q) + NULL, 0, NULL, 0, NULL)) { + regional_free_all(w->env->scratch); + libworker_fillup_fg(q, LDNS_RCODE_NOERROR, +- w->back->udp_buff, sec_status_insecure, NULL, 0); ++ w->back->udp_buff, sec_status_insecure, NULL); + libworker_delete(w); + free(qinfo.qname); + return UB_NOERROR; +@@ -643,7 +644,7 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q) + w->env, &qinfo, &edns, NULL, w->back->udp_buff, w->env->scratch)) { + regional_free_all(w->env->scratch); + libworker_fillup_fg(q, LDNS_RCODE_NOERROR, +- w->back->udp_buff, sec_status_insecure, NULL, 0); ++ w->back->udp_buff, sec_status_insecure, NULL); + libworker_delete(w); + free(qinfo.qname); + return UB_NOERROR; +@@ -665,7 +666,7 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q) + + void + libworker_event_done_cb(void* arg, int rcode, sldns_buffer* buf, +- enum sec_status s, char* why_bogus, int was_ratelimited) ++ enum sec_status s, char* why_bogus) + { + struct ctx_query* q = (struct ctx_query*)arg; + ub_event_callback_type cb = q->cb_event; +@@ -688,7 +689,7 @@ libworker_event_done_cb(void* arg, int rcode, sldns_buffer* buf, + else if(s == sec_status_secure) + sec = 2; + (*cb)(cb_arg, rcode, (buf?(void*)sldns_buffer_begin(buf):NULL), +- (buf?(int)sldns_buffer_limit(buf):0), sec, why_bogus, was_ratelimited); ++ (buf?(int)sldns_buffer_limit(buf):0), sec, why_bogus); + } + } + +@@ -715,7 +716,7 @@ int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q, + regional_free_all(w->env->scratch); + free(qinfo.qname); + libworker_event_done_cb(q, LDNS_RCODE_NOERROR, +- w->back->udp_buff, sec_status_insecure, NULL, 0); ++ w->back->udp_buff, sec_status_insecure, NULL); + return UB_NOERROR; + } + if(ctx->env->auth_zones && auth_zones_answer(ctx->env->auth_zones, +@@ -723,7 +724,7 @@ int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q, + regional_free_all(w->env->scratch); + free(qinfo.qname); + libworker_event_done_cb(q, LDNS_RCODE_NOERROR, +- w->back->udp_buff, sec_status_insecure, NULL, 0); ++ w->back->udp_buff, sec_status_insecure, NULL); + return UB_NOERROR; + } + /* process new query */ +@@ -788,12 +789,23 @@ add_bg_result(struct libworker* w, struct ctx_query* q, sldns_buffer* pkt, + } + } + ++ ++void ++libworker_bg_done_cb_compat(void* arg, int rcode, sldns_buffer* buf, enum sec_status s, ++ char* why_bogus) ++{ ++ rcode = RCODE_NOT_RATELIMITED(rcode); ++ libworker_bg_done_cb(arg, rcode, buf, s, why_bogus); ++} ++ + void + libworker_bg_done_cb(void* arg, int rcode, sldns_buffer* buf, enum sec_status s, +- char* why_bogus, int was_ratelimited) ++ char* why_bogus) + { ++ int was_ratelimited = RCODE_IS_RATELIMITED(rcode); + struct ctx_query* q = (struct ctx_query*)arg; + ++ rcode = RCODE_NOT_RATELIMITED(rcode); + if(q->cancelled || q->w->back->want_to_quit) { + if(q->w->is_bg_thread) { + /* delete it now */ +diff --git a/unbound-1.16.2/libunbound/unbound-event.h b/unbound-1.16.2/libunbound/unbound-event.h +index a5d5c03..70aa4c8 100644 +--- a/unbound-1.16.2/libunbound/unbound-event.h ++++ b/unbound-1.16.2/libunbound/unbound-event.h +@@ -170,7 +170,8 @@ struct ub_event { + struct ub_event_vmt* vmt; + }; + +-typedef void (*ub_event_callback_type)(void*, int, void*, int, int, char*, int); ++/* Uses define LDNS_RCODE_RATELIMITED from services/mesh.h */ ++typedef void (*ub_event_callback_type)(void*, int, void*, int, int, char*); + + /** + * Create a resolving and validation context. +diff --git a/unbound-1.16.2/libunbound/unbound.h b/unbound-1.16.2/libunbound/unbound.h +index c779d18..f6d5c7c 100644 +--- a/unbound-1.16.2/libunbound/unbound.h ++++ b/unbound-1.16.2/libunbound/unbound.h +@@ -203,18 +203,19 @@ struct ub_result { + */ + char* why_bogus; + ++ /** ++ * TTL for the result, in seconds. If the security is bogus, then ++ * you also cannot trust this value. ++ */ ++ int ttl; ++ + /** + * If the query or one of its subqueries was ratelimited. Useful if + * ratelimiting is enabled and answer to the client is SERVFAIL as a + * result. ++ * RHEL8 Change, moved after ttl. + */ + int was_ratelimited; +- +- /** +- * TTL for the result, in seconds. If the security is bogus, then +- * you also cannot trust this value. +- */ +- int ttl; + }; + + /** +diff --git a/unbound-1.16.2/libunbound/worker.h b/unbound-1.16.2/libunbound/worker.h +index 0fa5bfa..8b64b4d 100644 +--- a/unbound-1.16.2/libunbound/worker.h ++++ b/unbound-1.16.2/libunbound/worker.h +@@ -90,15 +90,15 @@ void libworker_handle_control_cmd(struct tube* tube, uint8_t* msg, size_t len, + + /** mesh callback with fg results */ + void libworker_fg_done_cb(void* arg, int rcode, sldns_buffer* buf, +- enum sec_status s, char* why_bogus, int was_ratelimited); ++ enum sec_status s, char* why_bogus); + + /** mesh callback with bg results */ + void libworker_bg_done_cb(void* arg, int rcode, sldns_buffer* buf, +- enum sec_status s, char* why_bogus, int was_ratelimited); ++ enum sec_status s, char* why_bogus); + + /** mesh callback with event results */ + void libworker_event_done_cb(void* arg, int rcode, struct sldns_buffer* buf, +- enum sec_status s, char* why_bogus, int was_ratelimited); ++ enum sec_status s, char* why_bogus); + + /** + * Worker signal handler function. User argument is the worker itself. +diff --git a/unbound-1.16.2/services/authzone.c b/unbound-1.16.2/services/authzone.c +index b9e0b11..c72949f 100644 +--- a/unbound-1.16.2/services/authzone.c ++++ b/unbound-1.16.2/services/authzone.c +@@ -5656,8 +5656,7 @@ xfr_master_add_addrs(struct auth_master* m, struct ub_packed_rrset_key* rrset, + + /** callback for task_transfer lookup of host name, of A or AAAA */ + void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf, +- enum sec_status ATTR_UNUSED(sec), char* ATTR_UNUSED(why_bogus), +- int ATTR_UNUSED(was_ratelimited)) ++ enum sec_status ATTR_UNUSED(sec), char* ATTR_UNUSED(why_bogus)) + { + struct auth_xfer* xfr = (struct auth_xfer*)arg; + struct module_env* env; +@@ -5669,6 +5668,7 @@ void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf, + return; /* stop on quit */ + } + ++ rcode = RCODE_NOT_RATELIMITED(rcode); + /* process result */ + if(rcode == LDNS_RCODE_NOERROR) { + uint16_t wanted_qtype = LDNS_RR_TYPE_A; +@@ -6717,8 +6717,7 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env) + + /** callback for task_probe lookup of host name, of A or AAAA */ + void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf, +- enum sec_status ATTR_UNUSED(sec), char* ATTR_UNUSED(why_bogus), +- int ATTR_UNUSED(was_ratelimited)) ++ enum sec_status ATTR_UNUSED(sec), char* ATTR_UNUSED(why_bogus)) + { + struct auth_xfer* xfr = (struct auth_xfer*)arg; + struct module_env* env; +@@ -6730,6 +6729,7 @@ void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf, + return; /* stop on quit */ + } + ++ rcode = RCODE_NOT_RATELIMITED(rcode); + /* process result */ + if(rcode == LDNS_RCODE_NOERROR) { + uint16_t wanted_qtype = LDNS_RR_TYPE_A; +@@ -8212,7 +8212,7 @@ auth_zone_verify_zonemd_key_with_ds(struct auth_zone* z, + + /** callback for ZONEMD lookup of DNSKEY */ + void auth_zonemd_dnskey_lookup_callback(void* arg, int rcode, sldns_buffer* buf, +- enum sec_status sec, char* why_bogus, int ATTR_UNUSED(was_ratelimited)) ++ enum sec_status sec, char* why_bogus) + { + struct auth_zone* z = (struct auth_zone*)arg; + struct module_env* env; +@@ -8234,6 +8234,7 @@ void auth_zonemd_dnskey_lookup_callback(void* arg, int rcode, sldns_buffer* buf, + if(z->zonemd_callback_qtype == LDNS_RR_TYPE_DS) + typestr = "DS"; + downprot = env->cfg->harden_algo_downgrade; ++ rcode = RCODE_NOT_RATELIMITED(rcode); + + /* process result */ + if(sec == sec_status_bogus) { +diff --git a/unbound-1.16.2/services/authzone.h b/unbound-1.16.2/services/authzone.h +index 07614ed..b339fc1 100644 +--- a/unbound-1.16.2/services/authzone.h ++++ b/unbound-1.16.2/services/authzone.h +@@ -690,12 +690,10 @@ void auth_xfer_probe_timer_callback(void* arg); + void auth_xfer_transfer_timer_callback(void* arg); + /** mesh callback for task_probe on lookup of host names */ + void auth_xfer_probe_lookup_callback(void* arg, int rcode, +- struct sldns_buffer* buf, enum sec_status sec, char* why_bogus, +- int was_ratelimited); ++ struct sldns_buffer* buf, enum sec_status sec, char* why_bogus); + /** mesh callback for task_transfer on lookup of host names */ + void auth_xfer_transfer_lookup_callback(void* arg, int rcode, +- struct sldns_buffer* buf, enum sec_status sec, char* why_bogus, +- int was_ratelimited); ++ struct sldns_buffer* buf, enum sec_status sec, char* why_bogus); + + /* + * Compares two 32-bit serial numbers as defined in RFC1982. Returns +@@ -774,8 +772,7 @@ void auth_zone_verify_zonemd(struct auth_zone* z, struct module_env* env, + + /** mesh callback for zonemd on lookup of dnskey */ + void auth_zonemd_dnskey_lookup_callback(void* arg, int rcode, +- struct sldns_buffer* buf, enum sec_status sec, char* why_bogus, +- int was_ratelimited); ++ struct sldns_buffer* buf, enum sec_status sec, char* why_bogus); + + /** + * Check the ZONEMD records that need online DNSSEC chain lookups, +diff --git a/unbound-1.16.2/services/mesh.c b/unbound-1.16.2/services/mesh.c +index 30bcf7c..fc3c690 100644 +--- a/unbound-1.16.2/services/mesh.c ++++ b/unbound-1.16.2/services/mesh.c +@@ -63,6 +63,7 @@ + #include "util/data/dname.h" + #include "respip/respip.h" + #include "services/listen_dnsport.h" ++#include "libunbound/unbound-event.h" + + #ifdef CLIENT_SUBNET + #include "edns-subnet/subnetmod.h" +@@ -1012,7 +1013,7 @@ mesh_state_cleanup(struct mesh_state* mstate) + mstate->cb_list = cb->next; + fptr_ok(fptr_whitelist_mesh_cb(cb->cb)); + (*cb->cb)(cb->cb_arg, LDNS_RCODE_SERVFAIL, NULL, +- sec_status_unchecked, NULL, 0); ++ sec_status_unchecked, NULL); + log_assert(mesh->num_reply_addrs > 0); + mesh->num_reply_addrs--; + } +@@ -1268,8 +1269,9 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep, + r->edns.opt_list_inplace_cb_out = NULL; + } + fptr_ok(fptr_whitelist_mesh_cb(r->cb)); +- (*r->cb)(r->cb_arg, rcode, r->buf, sec_status_unchecked, NULL, +- was_ratelimited); ++ if (was_ratelimited) ++ rcode |= LDNS_RCODE_RATELIMITED; ++ (*r->cb)(r->cb_arg, rcode, r->buf, sec_status_unchecked, NULL); + } else { + size_t udp_size = r->edns.udp_size; + sldns_buffer_clear(r->buf); +@@ -1287,11 +1289,14 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep, + { + fptr_ok(fptr_whitelist_mesh_cb(r->cb)); + (*r->cb)(r->cb_arg, LDNS_RCODE_SERVFAIL, r->buf, +- sec_status_unchecked, NULL, 0); ++ sec_status_unchecked, NULL); + } else { + fptr_ok(fptr_whitelist_mesh_cb(r->cb)); +- (*r->cb)(r->cb_arg, LDNS_RCODE_NOERROR, r->buf, +- rep->security, reason, was_ratelimited); ++ rcode = LDNS_RCODE_NOERROR; ++ if (was_ratelimited) ++ rcode |= LDNS_RCODE_RATELIMITED; ++ (*r->cb)(r->cb_arg, rcode, r->buf, ++ rep->security, reason); + } + } + free(reason); +diff --git a/unbound-1.16.2/services/mesh.h b/unbound-1.16.2/services/mesh.h +index 3be9b63..5050d6c 100644 +--- a/unbound-1.16.2/services/mesh.h ++++ b/unbound-1.16.2/services/mesh.h +@@ -234,13 +234,20 @@ struct mesh_reply { + struct http2_stream* h2_stream; + }; + ++/* RHEL 8 compatibility layer. ++ * Special rcode to send was_ratelimited to callback without adding ++ * extra parameter. It is ORed to the rcode parameter of the callback. */ ++#define LDNS_RCODE_RATELIMITED 0x100 ++#define RCODE_IS_RATELIMITED(rcode) ((rcode & LDNS_RCODE_RATELIMITED) != 0) ++#define RCODE_NOT_RATELIMITED(rcode) (rcode & ~LDNS_RCODE_RATELIMITED) ++ + /** + * Mesh result callback func. + * called as func(cb_arg, rcode, buffer_with_reply, security, why_bogus, + * was_ratelimited); + */ + typedef void (*mesh_cb_func_type)(void* cb_arg, int rcode, struct sldns_buffer*, +- enum sec_status, char* why_bogus, int was_ratelimited); ++ enum sec_status, char* why_bogus); + + /** + * Callback to result routine +diff --git a/unbound-1.16.2/smallapp/worker_cb.c b/unbound-1.16.2/smallapp/worker_cb.c +index c689817..c7b1653 100644 +--- a/unbound-1.16.2/smallapp/worker_cb.c ++++ b/unbound-1.16.2/smallapp/worker_cb.c +@@ -159,21 +159,21 @@ void libworker_handle_control_cmd(struct tube* ATTR_UNUSED(tube), + + void libworker_fg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode), + struct sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s), +- char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited)) ++ char* ATTR_UNUSED(why_bogus)) + { + log_assert(0); + } + + void libworker_bg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode), + struct sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s), +- char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited)) ++ char* ATTR_UNUSED(why_bogus)) + { + log_assert(0); + } + + void libworker_event_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode), + struct sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s), +- char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited)) ++ char* ATTR_UNUSED(why_bogus)) + { + log_assert(0); + } +diff --git a/unbound-1.16.2/validator/autotrust.c b/unbound-1.16.2/validator/autotrust.c +index 3cdf9ce..40b3e35 100644 +--- a/unbound-1.16.2/validator/autotrust.c ++++ b/unbound-1.16.2/validator/autotrust.c +@@ -2331,7 +2331,7 @@ autr_debug_print(struct val_anchors* anchors) + + void probe_answer_cb(void* arg, int ATTR_UNUSED(rcode), + sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(sec), +- char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited)) ++ char* ATTR_UNUSED(why_bogus)) + { + /* retry was set before the query was done, + * re-querytime is set when query succeeded, but that may not +diff --git a/unbound-1.16.2/validator/autotrust.h b/unbound-1.16.2/validator/autotrust.h +index 057f2b6..c549798 100644 +--- a/unbound-1.16.2/validator/autotrust.h ++++ b/unbound-1.16.2/validator/autotrust.h +@@ -206,6 +206,6 @@ void autr_debug_print(struct val_anchors* anchors); + + /** callback for query answer to 5011 probe */ + void probe_answer_cb(void* arg, int rcode, struct sldns_buffer* buf, +- enum sec_status sec, char* errinf, int was_ratelimited); ++ enum sec_status sec, char* errinf); + + #endif /* VALIDATOR_AUTOTRUST_H */ +-- +2.37.1 + diff --git a/SOURCES/unbound-1.16.2.tar.gz.asc b/SOURCES/unbound-1.16.2.tar.gz.asc new file mode 100644 index 0000000..0f94fb9 --- /dev/null +++ b/SOURCES/unbound-1.16.2.tar.gz.asc @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCAAdFiEE7fqj8spObrBWga+On28cLX4EX40FAmLnudYACgkQn28cLX4E +X43GmRAAoROXbktLR2AXGEECgPCFlHag9oNZosa3J5yR2vaV4e8eA6AMzPyZbl7P +LnLon8PZZR+pTW+dDRqakvzJIwXkLeONFgEdvd0cAghWAtPrKCDZIkCyeQj0OOv3 +wt1pRRl2PXUKNZZf0bzpTUIhVsHF/w5f5T/mFAZm49rUDboj77xgokmaFK4kei0I +Gz4W8Vx3TIwwJc8nea8GtCYIg3UKmR/TMznMFExAoKdMllzKuJnGx5lR/eU0+NRc +uwWEQhNJrHXZyWethp9swLCrOmDHcgBJOd04TqcDwSIZrw9VuT3/Uza3Tw73N7kr +PZvF2xSOASL+i91QP6tnkmQD5pAORVpUFN3NePEWV5922iG/pVipaYBbEyV3dfph +Y4QGwj8G6ppcfjV7gmlxsAOM2gnhD3rDqFmkxau6zB1kktHnV2aqlzIQo396ZBJQ +hKyIAJlNvpTiFaACD7/cFkE80awJnCD/qvXATN//BWHKytgO8eYg7fZGrxjbpIQk +XV/vVlOJWRXPyPBnp8MQyCIDe2eq2ELlMfYw62/TNDuj2qKsM/W03cem3GlveOa6 +tw8RVfFFjwZlCLbXSbmsKo+mWJ3jCAvb3/gql52vJDE5FuRz7MvptIVU6DVE1O+J +mQ3AoQ2Mq9iHsZePfze4sq531DMlWTgBMwqfBTWqMaTC/8VH5rg= +=Ax9n +-----END PGP SIGNATURE----- diff --git a/SOURCES/unbound-1.7.2-python3-devel.patch b/SOURCES/unbound-1.7.2-python3-devel.patch deleted file mode 100644 index db6fce0..0000000 --- a/SOURCES/unbound-1.7.2-python3-devel.patch +++ /dev/null @@ -1,320 +0,0 @@ -From b5aab36d41f374eddb0f66f28f251588f53a1e1e Mon Sep 17 00:00:00 2001 -From: Wouter Wijngaards -Date: Wed, 27 Jun 2018 05:46:36 +0000 -Subject: [PATCH 1/2] - #4109: Fix that package config depends on python - unconditionally. - -git-svn-id: file:///svn/unbound/trunk@4757 be551aaa-1e26-0410-a405-d3ace91eadb9 ---- - configure | 257 +++++++++++++++++++++++++++++++---------------------------- - configure.ac | 5 +- - 2 files changed, 137 insertions(+), 125 deletions(-) - -diff --git a/configure b/configure -index 3f1c372a..2a1687ae 100755 ---- a/configure -+++ b/configure -@@ -670,9 +670,6 @@ SYSTEMD_DAEMON_LIBS - SYSTEMD_DAEMON_CFLAGS - SYSTEMD_LIBS - SYSTEMD_CFLAGS --PKG_CONFIG_LIBDIR --PKG_CONFIG_PATH --PKG_CONFIG - staticexe - PC_LIBEVENT_DEPENDENCY - UNBOUND_EVENT_UNINSTALL -@@ -697,6 +694,9 @@ swig - SWIG_LIB - SWIG - PC_PY_DEPENDENCY -+PKG_CONFIG_LIBDIR -+PKG_CONFIG_PATH -+PKG_CONFIG - PY_MAJOR_VERSION - PYTHON_SITE_PKG - PYTHON_LDFLAGS -@@ -16930,7 +16930,136 @@ $as_echo "#define HAVE_PYTHON 1" >>confdefs.h - CPPFLAGS="$PYTHON_CPPFLAGS" - fi - ub_have_python=yes -- PC_PY_DEPENDENCY="python" -+ -+ -+ -+ -+ -+ -+ -+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then -+ if test -n "$ac_tool_prefix"; then -+ # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. -+set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -+$as_echo_n "checking for $ac_word... " >&6; } -+if ${ac_cv_path_PKG_CONFIG+:} false; then : -+ $as_echo_n "(cached) " >&6 -+else -+ case $PKG_CONFIG in -+ [\\/]* | ?:[\\/]*) -+ ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. -+ ;; -+ *) -+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in $PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ for ac_exec_ext in '' $ac_executable_extensions; do -+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -+ ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" -+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 -+ break 2 -+ fi -+done -+ done -+IFS=$as_save_IFS -+ -+ ;; -+esac -+fi -+PKG_CONFIG=$ac_cv_path_PKG_CONFIG -+if test -n "$PKG_CONFIG"; then -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 -+$as_echo "$PKG_CONFIG" >&6; } -+else -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+$as_echo "no" >&6; } -+fi -+ -+ -+fi -+if test -z "$ac_cv_path_PKG_CONFIG"; then -+ ac_pt_PKG_CONFIG=$PKG_CONFIG -+ # Extract the first word of "pkg-config", so it can be a program name with args. -+set dummy pkg-config; ac_word=$2 -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -+$as_echo_n "checking for $ac_word... " >&6; } -+if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : -+ $as_echo_n "(cached) " >&6 -+else -+ case $ac_pt_PKG_CONFIG in -+ [\\/]* | ?:[\\/]*) -+ ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. -+ ;; -+ *) -+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in $PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ for ac_exec_ext in '' $ac_executable_extensions; do -+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -+ ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" -+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 -+ break 2 -+ fi -+done -+ done -+IFS=$as_save_IFS -+ -+ ;; -+esac -+fi -+ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG -+if test -n "$ac_pt_PKG_CONFIG"; then -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 -+$as_echo "$ac_pt_PKG_CONFIG" >&6; } -+else -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+$as_echo "no" >&6; } -+fi -+ -+ if test "x$ac_pt_PKG_CONFIG" = x; then -+ PKG_CONFIG="" -+ else -+ case $cross_compiling:$ac_tool_warned in -+yes:) -+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -+ac_tool_warned=yes ;; -+esac -+ PKG_CONFIG=$ac_pt_PKG_CONFIG -+ fi -+else -+ PKG_CONFIG="$ac_cv_path_PKG_CONFIG" -+fi -+ -+fi -+if test -n "$PKG_CONFIG"; then -+ _pkg_min_version=0.9.0 -+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 -+$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } -+ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -+$as_echo "yes" >&6; } -+ else -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+$as_echo "no" >&6; } -+ PKG_CONFIG="" -+ fi -+fi -+ if test -n "$PKG_CONFIG" && \ -+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\"python\${PY_MAJOR_VERSION}\"\""; } >&5 -+ ($PKG_CONFIG --exists --print-errors ""python${PY_MAJOR_VERSION}"") 2>&5 -+ ac_status=$? -+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -+ test $ac_status = 0; }; then -+ PC_PY_DEPENDENCY="python${PY_MAJOR_VERSION}" -+else -+ PC_PY_DEPENDENCY="python" -+fi - - - # Check for SWIG -@@ -18960,126 +19089,6 @@ else - fi - - have_systemd=no -- -- -- -- -- -- -- --if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then -- if test -n "$ac_tool_prefix"; then -- # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. --set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 --$as_echo_n "checking for $ac_word... " >&6; } --if ${ac_cv_path_PKG_CONFIG+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- case $PKG_CONFIG in -- [\\/]* | ?:[\\/]*) -- ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. -- ;; -- *) -- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR --for as_dir in $PATH --do -- IFS=$as_save_IFS -- test -z "$as_dir" && as_dir=. -- for ac_exec_ext in '' $ac_executable_extensions; do -- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -- ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" -- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 -- break 2 -- fi --done -- done --IFS=$as_save_IFS -- -- ;; --esac --fi --PKG_CONFIG=$ac_cv_path_PKG_CONFIG --if test -n "$PKG_CONFIG"; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 --$as_echo "$PKG_CONFIG" >&6; } --else -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 --$as_echo "no" >&6; } --fi -- -- --fi --if test -z "$ac_cv_path_PKG_CONFIG"; then -- ac_pt_PKG_CONFIG=$PKG_CONFIG -- # Extract the first word of "pkg-config", so it can be a program name with args. --set dummy pkg-config; ac_word=$2 --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 --$as_echo_n "checking for $ac_word... " >&6; } --if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- case $ac_pt_PKG_CONFIG in -- [\\/]* | ?:[\\/]*) -- ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. -- ;; -- *) -- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR --for as_dir in $PATH --do -- IFS=$as_save_IFS -- test -z "$as_dir" && as_dir=. -- for ac_exec_ext in '' $ac_executable_extensions; do -- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -- ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" -- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 -- break 2 -- fi --done -- done --IFS=$as_save_IFS -- -- ;; --esac --fi --ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG --if test -n "$ac_pt_PKG_CONFIG"; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 --$as_echo "$ac_pt_PKG_CONFIG" >&6; } --else -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 --$as_echo "no" >&6; } --fi -- -- if test "x$ac_pt_PKG_CONFIG" = x; then -- PKG_CONFIG="" -- else -- case $cross_compiling:$ac_tool_warned in --yes:) --{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 --$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} --ac_tool_warned=yes ;; --esac -- PKG_CONFIG=$ac_pt_PKG_CONFIG -- fi --else -- PKG_CONFIG="$ac_cv_path_PKG_CONFIG" --fi -- --fi --if test -n "$PKG_CONFIG"; then -- _pkg_min_version=0.9.0 -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 --$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } -- if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 --$as_echo "yes" >&6; } -- else -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 --$as_echo "no" >&6; } -- PKG_CONFIG="" -- fi --fi - if test "x$enable_systemd" != xno; then : - - -diff --git a/configure.ac b/configure.ac -index 1828253c..b2c95d1a 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -586,7 +586,10 @@ if test x_$ub_test_python != x_no; then - CPPFLAGS="$PYTHON_CPPFLAGS" - fi - ub_have_python=yes -- PC_PY_DEPENDENCY="python" -+ PKG_PROG_PKG_CONFIG -+ PKG_CHECK_EXISTS(["python${PY_MAJOR_VERSION}"], -+ [PC_PY_DEPENDENCY="python${PY_MAJOR_VERSION}"], -+ [PC_PY_DEPENDENCY="python"]) - AC_SUBST(PC_PY_DEPENDENCY) - - # Check for SWIG --- -2.14.4 - diff --git a/SOURCES/unbound-1.7.2-python3-pkgconfig.patch b/SOURCES/unbound-1.7.2-python3-pkgconfig.patch deleted file mode 100644 index 86ba0b8..0000000 --- a/SOURCES/unbound-1.7.2-python3-pkgconfig.patch +++ /dev/null @@ -1,31 +0,0 @@ -From bca54a8b252d4a75e940424dc761c6a4e487eb84 Mon Sep 17 00:00:00 2001 -From: Wouter Wijngaards -Date: Wed, 27 Jun 2018 06:07:31 +0000 -Subject: [PATCH 2/2] =?UTF-8?q?-=20Patch,=20do=20not=20export=20python=20f?= - =?UTF-8?q?rom=20pkg-config,=20from=20Petr=20Men=C5=A1=C3=ADk.?= -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -git-svn-id: file:///svn/unbound/trunk@4758 be551aaa-1e26-0410-a405-d3ace91eadb9 ---- - contrib/libunbound.pc.in | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/contrib/libunbound.pc.in b/contrib/libunbound.pc.in -index 0cb9f875..810c5713 100644 ---- a/contrib/libunbound.pc.in -+++ b/contrib/libunbound.pc.in -@@ -7,7 +7,8 @@ Name: unbound - Description: Library with validating, recursive, and caching DNS resolver - URL: http://www.unbound.net - Version: @PACKAGE_VERSION@ --Requires: @PC_LIBEVENT_DEPENDENCY@ @PC_PY_DEPENDENCY@ -+Requires: libcrypto libssl @PC_LIBEVENT_DEPENDENCY@ -+Requires.private: @PC_PY_DEPENDENCY@ - Libs: -L${libdir} -lunbound -lssl -lcrypto - Libs.private: @SSLLIB@ @LIBS@ - Cflags: -I${includedir} --- -2.14.4 - diff --git a/SOURCES/unbound-1.7.3-DNS-over-TLS-memory-leak.patch b/SOURCES/unbound-1.7.3-DNS-over-TLS-memory-leak.patch deleted file mode 100644 index 9823850..0000000 --- a/SOURCES/unbound-1.7.3-DNS-over-TLS-memory-leak.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 377d5b426a30fc915cf7905786f93c0ec89845b7 Mon Sep 17 00:00:00 2001 -From: Wouter Wijngaards -Date: Tue, 25 Sep 2018 09:01:13 +0000 -Subject: [PATCH] - Add SSL cleanup for tcp timeout. - -git-svn-id: file:///svn/unbound/trunk@4915 be551aaa-1e26-0410-a405-d3ace91eadb9 ---- - services/outside_network.c | 11 +++++++++++ - 1 files changed, 9 insertions(+) -diff --git a/services/outside_network.c b/services/outside_network.c -index 5700ef8..b52cdab 100644 ---- a/services/outside_network.c -+++ b/services/outside_network.c -@@ -373,6 +373,8 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len) - if(!SSL_set1_host(pend->c->ssl, w->tls_auth_name)) { - log_err("SSL_set1_host failed"); - pend->c->fd = s; -+ SSL_free(pend->c->ssl); -+ pend->c->ssl = NULL; - comm_point_close(pend->c); - return 0; - } -@@ -1258,6 +1260,13 @@ outnet_tcptimer(void* arg) - } else { - /* it was in use */ - struct pending_tcp* pend=(struct pending_tcp*)w->next_waiting; -+ if(pend->c->ssl) { -+#ifdef HAVE_SSL -+ SSL_shutdown(pend->c->ssl); -+ SSL_free(pend->c->ssl); -+ pend->c->ssl = NULL; -+#endif -+ } - comm_point_close(pend->c); - pend->query = NULL; - pend->next_free = outnet->tcp_free; diff --git a/SOURCES/unbound-1.7.3-additional-logging.patch b/SOURCES/unbound-1.7.3-additional-logging.patch deleted file mode 100644 index 7630422..0000000 --- a/SOURCES/unbound-1.7.3-additional-logging.patch +++ /dev/null @@ -1,553 +0,0 @@ -diff --git a/daemon/worker.c b/daemon/worker.c -index 44a989a..3acecc1 100644 ---- a/daemon/worker.c -+++ b/daemon/worker.c -@@ -1193,7 +1193,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error, - if(worker->env.cfg->log_queries) { - char ip[128]; - addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip)); -- log_nametypeclass(0, ip, qinfo.qname, qinfo.qtype, qinfo.qclass); -+ log_query_in(ip, qinfo.qname, qinfo.qtype, qinfo.qclass); - } - if(qinfo.qtype == LDNS_RR_TYPE_AXFR || - qinfo.qtype == LDNS_RR_TYPE_IXFR) { -diff --git a/doc/Changelog b/doc/Changelog -index 3d05ae5..bb74461 100644 ---- a/doc/Changelog -+++ b/doc/Changelog -@@ -1,3 +1,15 @@ -+30 November 2018: Wouter -+ - log-tag-queryreply: yes in unbound.conf tags the log-queries and -+ log-replies in the log file for easier log filter maintenance. -+ -+21 August 2018: Wouter -+ - log-local-actions: yes option for unbound.conf that logs all the -+ local zone actions, a patch from Saksham Manchanda (Secure64). -+ -+17 August 2018: Wouter -+ - log-servfail: yes prints log lines that say why queries are -+ returning SERVFAIL to clients. -+ - 19 June 2018: Wouter - - Fix for unbound-control on Windows and set TCP socket parameters - more closely. -diff --git a/doc/example.conf.in b/doc/example.conf.in -index be83bda..aa06cee 100644 ---- a/doc/example.conf.in -+++ b/doc/example.conf.in -@@ -309,6 +309,17 @@ server: - # timetoresolve, fromcache and responsesize. - # log-replies: no - -+ # log with tag 'query' and 'reply' instead of 'info' for -+ # filtering log-queries and log-replies from the log. -+ # log-tag-queryreply: no -+ -+ # log the local-zone actions, like local-zone type inform is enabled -+ # also for the other local zone types. -+ # log-local-actions: no -+ -+ # print log lines that say why queries return SERVFAIL to clients. -+ # log-servfail: no -+ - # the pid file. Can be an absolute path outside of chroot/work dir. - # pidfile: "@UNBOUND_PIDFILE@" - -diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in -index 9167a5a..b73bc70 100644 ---- a/doc/unbound.conf.5.in -+++ b/doc/unbound.conf.5.in -@@ -618,6 +618,21 @@ Default is no. Note that it takes time to print these - lines which makes the server (significantly) slower. Odd (nonprintable) - characters in names are printed as '?'. - .TP -+.B log\-tag\-queryreply: \fI -+Prints the word 'query' and 'reply' with log\-queries and log\-replies. -+This makes filtering logs easier. The default is off (for backwards -+compatibility). -+.TP -+.B log\-local\-actions: \fI -+Print log lines to inform about local zone actions. These lines are like the -+local\-zone type inform prints out, but they are also printed for the other -+types of local zones. -+.TP -+.B log\-servfail: \fI -+Print log lines that say why queries return SERVFAIL to clients. -+This is separate from the verbosity debug logs, much smaller, and printed -+at the error level, not the info level of debug info from verbosity. -+.TP - .B pidfile: \fI - The process id is written to the file. Default is "@UNBOUND_PIDFILE@". - So, -diff --git a/services/localzone.c b/services/localzone.c -index 0f60817..a85619b 100644 ---- a/services/localzone.c -+++ b/services/localzone.c -@@ -1459,7 +1459,7 @@ lz_inform_print(struct local_zone* z, struct query_info* qinfo, - uint16_t port = ntohs(((struct sockaddr_in*)&repinfo->addr)->sin_port); - dname_str(z->name, zname); - addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip)); -- snprintf(txt, sizeof(txt), "%s inform %s@%u", zname, ip, -+ snprintf(txt, sizeof(txt), "%s %s %s@%u", zname, local_zone_type2str(z->type), ip, - (unsigned)port); - log_nametypeclass(0, txt, qinfo->qname, qinfo->qtype, qinfo->qclass); - } -@@ -1576,7 +1576,8 @@ local_zones_answer(struct local_zones* zones, struct module_env* env, - z->override_tree, &tag, tagname, num_tags); - lock_rw_unlock(&zones->lock); - } -- if((lzt == local_zone_inform || lzt == local_zone_inform_deny) -+ if((env->cfg->log_local_actions || -+ lzt == local_zone_inform || lzt == local_zone_inform_deny) - && repinfo) - lz_inform_print(z, qinfo, repinfo); - -diff --git a/services/mesh.c b/services/mesh.c -index 41aba74..55c1947 100644 ---- a/services/mesh.c -+++ b/services/mesh.c -@@ -977,7 +977,7 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep, - rcode = LDNS_RCODE_SERVFAIL; - if(!rcode && (rep->security == sec_status_bogus || - rep->security == sec_status_secure_sentinel_fail)) { -- if(!(reason = errinf_to_str(&m->s))) -+ if(!(reason = errinf_to_str_bogus(&m->s))) - rcode = LDNS_RCODE_SERVFAIL; - } - /* send the reply */ -@@ -1148,6 +1148,15 @@ void mesh_query_done(struct mesh_state* mstate) - struct mesh_cb* c; - struct reply_info* rep = (mstate->s.return_msg? - mstate->s.return_msg->rep:NULL); -+ if((mstate->s.return_rcode == LDNS_RCODE_SERVFAIL || -+ (rep && FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_SERVFAIL)) -+ && mstate->s.env->cfg->log_servfail -+ && !mstate->s.env->cfg->val_log_squelch) { -+ char* err = errinf_to_str_servfail(&mstate->s); -+ if(err) -+ log_err("%s", err); -+ free(err); -+ } - for(r = mstate->reply_list; r; r = r->next) { - /* if a response-ip address block has been stored the - * information should be logged for each client. */ -diff --git a/util/config_file.c b/util/config_file.c -index b061760..68a0a15 100644 ---- a/util/config_file.c -+++ b/util/config_file.c -@@ -115,6 +115,9 @@ config_create(void) - cfg->log_time_ascii = 0; - cfg->log_queries = 0; - cfg->log_replies = 0; -+ cfg->log_tag_queryreply = 0; -+ cfg->log_local_actions = 0; -+ cfg->log_servfail = 0; - #ifndef USE_WINSOCK - # ifdef USE_MINI_EVENT - /* select max 1024 sockets */ -@@ -540,6 +543,9 @@ int config_set_option(struct config_file* cfg, const char* opt, - else S_YNO("val-log-squelch:", val_log_squelch) - else S_YNO("log-queries:", log_queries) - else S_YNO("log-replies:", log_replies) -+ else S_YNO("log-tag-queryreply:", log_tag_queryreply) -+ else S_YNO("log-local-actions:", log_local_actions) -+ else S_YNO("log-servfail:", log_servfail) - else S_YNO("val-permissive-mode:", val_permissive_mode) - else S_YNO("aggressive-nsec:", aggressive_nsec) - else S_YNO("ignore-cd-flag:", ignore_cd) -@@ -893,6 +899,9 @@ config_get_option(struct config_file* cfg, const char* opt, - else O_STR(opt, "logfile", logfile) - else O_YNO(opt, "log-queries", log_queries) - else O_YNO(opt, "log-replies", log_replies) -+ else O_YNO(opt, "log-tag-queryreply", log_tag_queryreply) -+ else O_YNO(opt, "log-local-actions", log_local_actions) -+ else O_YNO(opt, "log-servfail", log_servfail) - else O_STR(opt, "pidfile", pidfile) - else O_YNO(opt, "hide-identity", hide_identity) - else O_YNO(opt, "hide-version", hide_version) -@@ -1845,6 +1854,7 @@ config_apply(struct config_file* config) - EDNS_ADVERTISED_SIZE = (uint16_t)config->edns_buffer_size; - MINIMAL_RESPONSES = config->minimal_responses; - RRSET_ROUNDROBIN = config->rrset_roundrobin; -+ LOG_TAG_QUERYREPLY = config->log_tag_queryreply; - log_set_time_asc(config->log_time_ascii); - autr_permit_small_holddown = config->permit_small_holddown; - } -@@ -2220,7 +2230,7 @@ void errinf_origin(struct module_qstate* qstate, struct sock_list *origin) - } - } - --char* errinf_to_str(struct module_qstate* qstate) -+char* errinf_to_str_bogus(struct module_qstate* qstate) - { - char buf[20480]; - char* p = buf; -@@ -2245,6 +2255,31 @@ char* errinf_to_str(struct module_qstate* qstate) - return p; - } - -+char* errinf_to_str_servfail(struct module_qstate* qstate) -+{ -+ char buf[20480]; -+ char* p = buf; -+ size_t left = sizeof(buf); -+ struct config_strlist* s; -+ char dname[LDNS_MAX_DOMAINLEN+1]; -+ char t[16], c[16]; -+ sldns_wire2str_type_buf(qstate->qinfo.qtype, t, sizeof(t)); -+ sldns_wire2str_class_buf(qstate->qinfo.qclass, c, sizeof(c)); -+ dname_str(qstate->qinfo.qname, dname); -+ snprintf(p, left, "SERVFAIL <%s %s %s>:", dname, t, c); -+ left -= strlen(p); p += strlen(p); -+ if(!qstate->errinf) -+ snprintf(p, left, " misc failure"); -+ else for(s=qstate->errinf; s; s=s->next) { -+ snprintf(p, left, " %s", s->str); -+ left -= strlen(p); p += strlen(p); -+ } -+ p = strdup(buf); -+ if(!p) -+ log_err("malloc failure in errinf_to_str"); -+ return p; -+} -+ - void errinf_rrset(struct module_qstate* qstate, struct ub_packed_rrset_key *rr) - { - char buf[1024]; -diff --git a/util/config_file.h b/util/config_file.h -index 4206eb9..1e7f402 100644 ---- a/util/config_file.h -+++ b/util/config_file.h -@@ -268,6 +268,12 @@ struct config_file { - int log_queries; - /** log replies with one line per reply */ - int log_replies; -+ /** tag log_queries and log_replies for filtering */ -+ int log_tag_queryreply; -+ /** log every local-zone hit **/ -+ int log_local_actions; -+ /** log servfails with a reason */ -+ int log_servfail; - /** log identity to report */ - char* log_identity; - -@@ -1070,7 +1076,15 @@ void errinf_dname(struct module_qstate* qstate, const char* str, - * @return string or NULL on malloc failure (already logged). - * This string is malloced and has to be freed by caller. - */ --char* errinf_to_str(struct module_qstate* qstate); -+char* errinf_to_str_bogus(struct module_qstate* qstate); -+ -+/** -+ * Create error info in string. For other servfails. -+ * @param qstate: query state. -+ * @return string or NULL on malloc failure (already logged). -+ * This string is malloced and has to be freed by caller. -+ */ -+char* errinf_to_str_servfail(struct module_qstate* qstate); - - /** - * Used during options parsing -diff --git a/util/configlexer.lex b/util/configlexer.lex -index 6124e32..9b22db1 100644 ---- a/util/configlexer.lex -+++ b/util/configlexer.lex -@@ -366,6 +366,9 @@ log-identity{COLON} { YDVAR(1, VAR_LOG_IDENTITY) } - log-time-ascii{COLON} { YDVAR(1, VAR_LOG_TIME_ASCII) } - log-queries{COLON} { YDVAR(1, VAR_LOG_QUERIES) } - log-replies{COLON} { YDVAR(1, VAR_LOG_REPLIES) } -+log-tag-queryreply{COLON} { YDVAR(1, VAR_LOG_TAG_QUERYREPLY) } -+log-local-actions{COLON} { YDVAR(1, VAR_LOG_LOCAL_ACTIONS) } -+log-servfail{COLON} { YDVAR(1, VAR_LOG_SERVFAIL) } - local-zone{COLON} { YDVAR(2, VAR_LOCAL_ZONE) } - local-data{COLON} { YDVAR(1, VAR_LOCAL_DATA) } - local-data-ptr{COLON} { YDVAR(1, VAR_LOCAL_DATA_PTR) } -diff --git a/util/configparser.y b/util/configparser.y -index e34665a..4b23a71 100644 ---- a/util/configparser.y -+++ b/util/configparser.y -@@ -106,7 +106,7 @@ extern struct config_parser_state* cfg_parser; - %token VAR_AUTO_TRUST_ANCHOR_FILE VAR_KEEP_MISSING VAR_ADD_HOLDDOWN - %token VAR_DEL_HOLDDOWN VAR_SO_RCVBUF VAR_EDNS_BUFFER_SIZE VAR_PREFETCH - %token VAR_PREFETCH_KEY VAR_SO_SNDBUF VAR_SO_REUSEPORT VAR_HARDEN_BELOW_NXDOMAIN --%token VAR_IGNORE_CD_FLAG VAR_LOG_QUERIES VAR_LOG_REPLIES -+%token VAR_IGNORE_CD_FLAG VAR_LOG_QUERIES VAR_LOG_REPLIES VAR_LOG_LOCAL_ACTIONS - %token VAR_TCP_UPSTREAM VAR_SSL_UPSTREAM - %token VAR_SSL_SERVICE_KEY VAR_SSL_SERVICE_PEM VAR_SSL_PORT VAR_FORWARD_FIRST - %token VAR_STUB_SSL_UPSTREAM VAR_FORWARD_SSL_UPSTREAM VAR_TLS_CERT_BUNDLE -@@ -158,6 +158,8 @@ extern struct config_parser_state* cfg_parser; - %token VAR_AUTH_ZONE VAR_ZONEFILE VAR_MASTER VAR_URL VAR_FOR_DOWNSTREAM - %token VAR_FALLBACK_ENABLED VAR_TLS_ADDITIONAL_PORT VAR_LOW_RTT VAR_LOW_RTT_PERMIL - %token VAR_ALLOW_NOTIFY VAR_TLS_WIN_CERT -+%token VAR_FORWARD_NO_CACHE VAR_STUB_NO_CACHE VAR_LOG_SERVFAIL -+%token VAR_UNKNOWN_SERVER_TIME_LIMIT VAR_LOG_TAG_QUERYREPLY - - %% - toplevelvars: /* empty */ | toplevelvars toplevelvar ; -@@ -217,6 +219,7 @@ content_server: server_num_threads | server_verbosity | server_port | - server_edns_buffer_size | server_prefetch | server_prefetch_key | - server_so_sndbuf | server_harden_below_nxdomain | server_ignore_cd_flag | - server_log_queries | server_log_replies | server_tcp_upstream | server_ssl_upstream | -+ server_log_local_actions | - server_ssl_service_key | server_ssl_service_pem | server_ssl_port | - server_minimal_responses | server_rrset_roundrobin | server_max_udp_size | - server_so_reuseport | server_delay_close | -@@ -249,7 +252,9 @@ content_server: server_num_threads | server_verbosity | server_port | - server_ipsecmod_whitelist | server_ipsecmod_strict | - server_udp_upstream_without_downstream | server_aggressive_nsec | - server_tls_cert_bundle | server_tls_additional_port | server_low_rtt | -- server_low_rtt_permil | server_tls_win_cert -+ server_low_rtt_permil | server_tls_win_cert | -+ server_tcp_connection_limit | server_log_servfail | -+ server_unknown_server_time_limit | server_log_tag_queryreply - ; - stubstart: VAR_STUB_ZONE - { -@@ -764,6 +769,33 @@ server_log_replies: VAR_LOG_REPLIES STRING_ARG - free($2); - } - ; -+server_log_tag_queryreply: VAR_LOG_TAG_QUERYREPLY STRING_ARG -+ { -+ OUTYY(("P(server_log_tag_queryreply:%s)\n", $2)); -+ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) -+ yyerror("expected yes or no."); -+ else cfg_parser->cfg->log_tag_queryreply = (strcmp($2, "yes")==0); -+ free($2); -+ } -+ ; -+server_log_servfail: VAR_LOG_SERVFAIL STRING_ARG -+ { -+ OUTYY(("P(server_log_servfail:%s)\n", $2)); -+ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) -+ yyerror("expected yes or no."); -+ else cfg_parser->cfg->log_servfail = (strcmp($2, "yes")==0); -+ free($2); -+ } -+ ; -+server_log_local_actions: VAR_LOG_LOCAL_ACTIONS STRING_ARG -+ { -+ OUTYY(("P(server_log_local_actions:%s)\n", $2)); -+ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) -+ yyerror("expected yes or no."); -+ else cfg_parser->cfg->log_local_actions = (strcmp($2, "yes")==0); -+ free($2); -+ } -+ ; - server_chroot: VAR_CHROOT STRING_ARG - { - OUTYY(("P(server_chroot:%s)\n", $2)); -diff --git a/util/data/msgreply.c b/util/data/msgreply.c -index 772f5d1..df2131c 100644 ---- a/util/data/msgreply.c -+++ b/util/data/msgreply.c -@@ -844,7 +844,9 @@ log_reply_info(enum verbosity_value v, struct query_info *qinf, - addr_to_str(addr, addrlen, clientip_buf, sizeof(clientip_buf)); - if(rcode == LDNS_RCODE_FORMERR) - { -- log_info("%s - - - %s - - - ", clientip_buf, rcode_buf); -+ if(LOG_TAG_QUERYREPLY) -+ log_reply("%s - - - %s - - - ", clientip_buf, rcode_buf); -+ else log_info("%s - - - %s - - - ", clientip_buf, rcode_buf); - } else { - if(qinf->qname) - dname_str(qinf->qname, qname_buf); -@@ -852,7 +854,11 @@ log_reply_info(enum verbosity_value v, struct query_info *qinf, - pktlen = sldns_buffer_limit(rmsg); - sldns_wire2str_type_buf(qinf->qtype, type_buf, sizeof(type_buf)); - sldns_wire2str_class_buf(qinf->qclass, class_buf, sizeof(class_buf)); -- log_info("%s %s %s %s %s " ARG_LL "d.%6.6d %d %d", -+ if(LOG_TAG_QUERYREPLY) -+ log_reply("%s %s %s %s %s " ARG_LL "d.%6.6d %d %d", -+ clientip_buf, qname_buf, type_buf, class_buf, -+ rcode_buf, (long long)dur.tv_sec, (int)dur.tv_usec, cached, (int)pktlen); -+ else log_info("%s %s %s %s %s " ARG_LL "d.%6.6d %d %d", - clientip_buf, qname_buf, type_buf, class_buf, - rcode_buf, (long long)dur.tv_sec, (int)dur.tv_usec, cached, (int)pktlen); - } -diff --git a/util/log.c b/util/log.c -index 43dd572..fff4319 100644 ---- a/util/log.c -+++ b/util/log.c -@@ -391,6 +391,24 @@ log_hex(const char* msg, void* data, size_t length) - log_hex_f(verbosity, msg, data, length); - } - -+void -+log_query(const char *format, ...) -+{ -+ va_list args; -+ va_start(args, format); -+ log_vmsg(LOG_INFO, "query", format, args); -+ va_end(args); -+} -+ -+void -+log_reply(const char *format, ...) -+{ -+ va_list args; -+ va_start(args, format); -+ log_vmsg(LOG_INFO, "reply", format, args); -+ va_end(args); -+} -+ - void log_buf(enum verbosity_value level, const char* msg, sldns_buffer* buf) - { - if(verbosity < level) -diff --git a/util/log.h b/util/log.h -index 7bc3d9e..172cd01 100644 ---- a/util/log.h -+++ b/util/log.h -@@ -160,6 +160,20 @@ void log_warn(const char* format, ...) ATTR_FORMAT(printf, 1, 2); - */ - void log_hex(const char* msg, void* data, size_t length); - -+/** -+ * Log query. -+ * Pass printf formatted arguments. No trailing newline is needed. -+ * @param format: printf-style format string. Arguments follow. -+ */ -+void log_query(const char* format, ...) ATTR_FORMAT(printf, 1, 2); -+ -+/** -+ * Log reply. -+ * Pass printf formatted arguments. No trailing newline is needed. -+ * @param format: printf-style format string. Arguments follow. -+ */ -+void log_reply(const char* format, ...) ATTR_FORMAT(printf, 1, 2); -+ - /** - * Easy alternative for log_hex, takes a sldns_buffer. - * @param level: verbosity level for this message, compared to global -diff --git a/util/net_help.c b/util/net_help.c -index a193c36..617a896 100644 ---- a/util/net_help.c -+++ b/util/net_help.c -@@ -67,6 +67,9 @@ int MINIMAL_RESPONSES = 0; - /** rrset order roundrobin: default is no */ - int RRSET_ROUNDROBIN = 0; - -+/** log tag queries with name instead of 'info' for filtering */ -+int LOG_TAG_QUERYREPLY = 0; -+ - /* returns true is string addr is an ip6 specced address */ - int - str_is_ip6(const char* str) -@@ -335,7 +338,7 @@ log_nametypeclass(enum verbosity_value v, const char* str, uint8_t* name, - { - char buf[LDNS_MAX_DOMAINLEN+1]; - char t[12], c[12]; -- const char *ts, *cs; -+ const char *ts, *cs; - if(verbosity < v) - return; - dname_str(name, buf); -@@ -361,6 +364,37 @@ log_nametypeclass(enum verbosity_value v, const char* str, uint8_t* name, - log_info("%s %s %s %s", str, buf, ts, cs); - } - -+void -+log_query_in(const char* str, uint8_t* name, uint16_t type, uint16_t dclass) -+{ -+ char buf[LDNS_MAX_DOMAINLEN+1]; -+ char t[12], c[12]; -+ const char *ts, *cs; -+ dname_str(name, buf); -+ if(type == LDNS_RR_TYPE_TSIG) ts = "TSIG"; -+ else if(type == LDNS_RR_TYPE_IXFR) ts = "IXFR"; -+ else if(type == LDNS_RR_TYPE_AXFR) ts = "AXFR"; -+ else if(type == LDNS_RR_TYPE_MAILB) ts = "MAILB"; -+ else if(type == LDNS_RR_TYPE_MAILA) ts = "MAILA"; -+ else if(type == LDNS_RR_TYPE_ANY) ts = "ANY"; -+ else if(sldns_rr_descript(type) && sldns_rr_descript(type)->_name) -+ ts = sldns_rr_descript(type)->_name; -+ else { -+ snprintf(t, sizeof(t), "TYPE%d", (int)type); -+ ts = t; -+ } -+ if(sldns_lookup_by_id(sldns_rr_classes, (int)dclass) && -+ sldns_lookup_by_id(sldns_rr_classes, (int)dclass)->name) -+ cs = sldns_lookup_by_id(sldns_rr_classes, (int)dclass)->name; -+ else { -+ snprintf(c, sizeof(c), "CLASS%d", (int)dclass); -+ cs = c; -+ } -+ if(LOG_TAG_QUERYREPLY) -+ log_query("%s %s %s %s", str, buf, ts, cs); -+ else log_info("%s %s %s %s", str, buf, ts, cs); -+} -+ - void log_name_addr(enum verbosity_value v, const char* str, uint8_t* zone, - struct sockaddr_storage* addr, socklen_t addrlen) - { -diff --git a/util/net_help.h b/util/net_help.h -index de2e1ac..f2e0e43 100644 ---- a/util/net_help.h -+++ b/util/net_help.h -@@ -99,6 +99,9 @@ extern int MINIMAL_RESPONSES; - /** rrset order roundrobin */ - extern int RRSET_ROUNDROBIN; - -+/** log tag queries with name instead of 'info' for filtering */ -+extern int LOG_TAG_QUERYREPLY; -+ - /** - * See if string is ip4 or ip6. - * @param str: IP specification. -@@ -235,6 +238,12 @@ void sockaddr_store_port(struct sockaddr_storage* addr, socklen_t addrlen, - void log_nametypeclass(enum verbosity_value v, const char* str, - uint8_t* name, uint16_t type, uint16_t dclass); - -+/** -+ * Like log_nametypeclass, but logs with log_query for query logging -+ */ -+void log_query_in(const char* str, uint8_t* name, uint16_t type, -+ uint16_t dclass); -+ - /** - * Compare two sockaddrs. Imposes an ordering on the addresses. - * Compares address and port. -diff --git a/validator/val_kcache.c b/validator/val_kcache.c -index 22070cc..e0b88b6 100644 ---- a/validator/val_kcache.c -+++ b/validator/val_kcache.c -@@ -89,7 +89,7 @@ key_cache_insert(struct key_cache* kcache, struct key_entry_key* kkey, - if(key_entry_isbad(k) && qstate->errinf && - qstate->env->cfg->val_log_level >= 2) { - /* on malloc failure there is simply no reason string */ -- key_entry_set_reason(k, errinf_to_str(qstate)); -+ key_entry_set_reason(k, errinf_to_str_bogus(qstate)); - } - key_entry_hash(k); - slabhash_insert(kcache->slab, k->entry.hash, &k->entry, -diff --git a/validator/validator.c b/validator/validator.c -index 5777b29..2d9cc17 100644 ---- a/validator/validator.c -+++ b/validator/validator.c -@@ -2227,13 +2227,15 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq, - vq->orig_msg->rep->ttl = ve->bogus_ttl; - vq->orig_msg->rep->prefetch_ttl = - PREFETCH_TTL_CALC(vq->orig_msg->rep->ttl); -- if(qstate->env->cfg->val_log_level >= 1 && -+ if((qstate->env->cfg->val_log_level >= 1 || -+ qstate->env->cfg->log_servfail) && - !qstate->env->cfg->val_log_squelch) { -- if(qstate->env->cfg->val_log_level < 2) -+ if(qstate->env->cfg->val_log_level < 2 && -+ !qstate->env->cfg->log_servfail) - log_query_info(0, "validation failure", - &qstate->qinfo); - else { -- char* err = errinf_to_str(qstate); -+ char* err = errinf_to_str_bogus(qstate); - if(err) log_info("%s", err); - free(err); - } -@@ -2332,6 +2334,7 @@ processDLVLookup(struct module_qstate* qstate, struct val_qstate* vq, - - if(vq->dlv_status == dlv_error) { - verbose(VERB_QUERY, "failed DLV lookup"); -+ errinf(qstate, "failed DLV lookup"); - return val_error(qstate, id); - } else if(vq->dlv_status == dlv_success) { - uint8_t* nm; diff --git a/SOURCES/unbound-1.7.3-amplifying-an-incoming-query.patch b/SOURCES/unbound-1.7.3-amplifying-an-incoming-query.patch deleted file mode 100644 index a3f9aef..0000000 --- a/SOURCES/unbound-1.7.3-amplifying-an-incoming-query.patch +++ /dev/null @@ -1,944 +0,0 @@ -diff --git a/iterator/iter_delegpt.c b/iterator/iter_delegpt.c -index f88b3e1..522e0e9 100644 ---- a/iterator/iter_delegpt.c -+++ b/iterator/iter_delegpt.c -@@ -84,7 +84,7 @@ struct delegpt* delegpt_copy(struct delegpt* dp, struct regional* region) - } - for(a = dp->target_list; a; a = a->next_target) { - if(!delegpt_add_addr(copy, region, &a->addr, a->addrlen, -- a->bogus, a->lame, a->tls_auth_name)) -+ a->bogus, a->lame, a->tls_auth_name, NULL)) - return NULL; - } - return copy; -@@ -161,7 +161,7 @@ delegpt_find_addr(struct delegpt* dp, struct sockaddr_storage* addr, - int - delegpt_add_target(struct delegpt* dp, struct regional* region, - uint8_t* name, size_t namelen, struct sockaddr_storage* addr, -- socklen_t addrlen, uint8_t bogus, uint8_t lame) -+ socklen_t addrlen, uint8_t bogus, uint8_t lame, int* additions) - { - struct delegpt_ns* ns = delegpt_find_ns(dp, name, namelen); - log_assert(!dp->dp_type_mlc); -@@ -176,13 +176,14 @@ delegpt_add_target(struct delegpt* dp, struct regional* region, - if(ns->got4 && ns->got6) - ns->resolved = 1; - } -- return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame, NULL); -+ return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame, NULL, -+ additions); - } - - int - delegpt_add_addr(struct delegpt* dp, struct regional* region, - struct sockaddr_storage* addr, socklen_t addrlen, uint8_t bogus, -- uint8_t lame, char* tls_auth_name) -+ uint8_t lame, char* tls_auth_name, int* additions) - { - struct delegpt_addr* a; - log_assert(!dp->dp_type_mlc); -@@ -195,6 +196,9 @@ delegpt_add_addr(struct delegpt* dp, struct regional* region, - return 1; - } - -+ if(additions) -+ *additions = 1; -+ - a = (struct delegpt_addr*)regional_alloc(region, - sizeof(struct delegpt_addr)); - if(!a) -@@ -382,10 +386,10 @@ delegpt_from_message(struct dns_msg* msg, struct regional* region) - continue; - - if(ntohs(s->rk.type) == LDNS_RR_TYPE_A) { -- if(!delegpt_add_rrset_A(dp, region, s, 0)) -+ if(!delegpt_add_rrset_A(dp, region, s, 0, NULL)) - return NULL; - } else if(ntohs(s->rk.type) == LDNS_RR_TYPE_AAAA) { -- if(!delegpt_add_rrset_AAAA(dp, region, s, 0)) -+ if(!delegpt_add_rrset_AAAA(dp, region, s, 0, NULL)) - return NULL; - } - } -@@ -416,7 +420,7 @@ delegpt_rrset_add_ns(struct delegpt* dp, struct regional* region, - - int - delegpt_add_rrset_A(struct delegpt* dp, struct regional* region, -- struct ub_packed_rrset_key* ak, uint8_t lame) -+ struct ub_packed_rrset_key* ak, uint8_t lame, int* additions) - { - struct packed_rrset_data* d=(struct packed_rrset_data*)ak->entry.data; - size_t i; -@@ -432,7 +436,7 @@ delegpt_add_rrset_A(struct delegpt* dp, struct regional* region, - memmove(&sa.sin_addr, d->rr_data[i]+2, INET_SIZE); - if(!delegpt_add_target(dp, region, ak->rk.dname, - ak->rk.dname_len, (struct sockaddr_storage*)&sa, -- len, (d->security==sec_status_bogus), lame)) -+ len, (d->security==sec_status_bogus), lame, additions)) - return 0; - } - return 1; -@@ -440,7 +444,7 @@ delegpt_add_rrset_A(struct delegpt* dp, struct regional* region, - - int - delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* region, -- struct ub_packed_rrset_key* ak, uint8_t lame) -+ struct ub_packed_rrset_key* ak, uint8_t lame, int* additions) - { - struct packed_rrset_data* d=(struct packed_rrset_data*)ak->entry.data; - size_t i; -@@ -456,7 +460,7 @@ delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* region, - memmove(&sa.sin6_addr, d->rr_data[i]+2, INET6_SIZE); - if(!delegpt_add_target(dp, region, ak->rk.dname, - ak->rk.dname_len, (struct sockaddr_storage*)&sa, -- len, (d->security==sec_status_bogus), lame)) -+ len, (d->security==sec_status_bogus), lame, additions)) - return 0; - } - return 1; -@@ -464,20 +468,32 @@ delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* region, - - int - delegpt_add_rrset(struct delegpt* dp, struct regional* region, -- struct ub_packed_rrset_key* rrset, uint8_t lame) -+ struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions) - { - if(!rrset) - return 1; - if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_NS) - return delegpt_rrset_add_ns(dp, region, rrset, lame); - else if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_A) -- return delegpt_add_rrset_A(dp, region, rrset, lame); -+ return delegpt_add_rrset_A(dp, region, rrset, lame, additions); - else if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_AAAA) -- return delegpt_add_rrset_AAAA(dp, region, rrset, lame); -+ return delegpt_add_rrset_AAAA(dp, region, rrset, lame, additions); - log_warn("Unknown rrset type added to delegpt"); - return 1; - } - -+void delegpt_mark_neg(struct delegpt_ns* ns, uint16_t qtype) -+{ -+ if(ns) { -+ if(qtype == LDNS_RR_TYPE_A) -+ ns->got4 = 2; -+ else if(qtype == LDNS_RR_TYPE_AAAA) -+ ns->got6 = 2; -+ if(ns->got4 && ns->got6) -+ ns->resolved = 1; -+ } -+} -+ - void delegpt_add_neg_msg(struct delegpt* dp, struct msgreply_entry* msg) - { - struct reply_info* rep = (struct reply_info*)msg->entry.data; -@@ -487,14 +503,7 @@ void delegpt_add_neg_msg(struct delegpt* dp, struct msgreply_entry* msg) - if(FLAGS_GET_RCODE(rep->flags) != 0 || rep->an_numrrsets == 0) { - struct delegpt_ns* ns = delegpt_find_ns(dp, msg->key.qname, - msg->key.qname_len); -- if(ns) { -- if(msg->key.qtype == LDNS_RR_TYPE_A) -- ns->got4 = 1; -- else if(msg->key.qtype == LDNS_RR_TYPE_AAAA) -- ns->got6 = 1; -- if(ns->got4 && ns->got6) -- ns->resolved = 1; -- } -+ delegpt_mark_neg(ns, msg->key.qtype); - } - } - -diff --git a/iterator/iter_delegpt.h b/iterator/iter_delegpt.h -index 354bd61..3aded22 100644 ---- a/iterator/iter_delegpt.h -+++ b/iterator/iter_delegpt.h -@@ -104,9 +104,10 @@ struct delegpt_ns { - * and marked true if got4 and got6 are both true. - */ - int resolved; -- /** if the ipv4 address is in the delegpt */ -+ /** if the ipv4 address is in the delegpt, 0=not, 1=yes 2=negative, -+ * negative means it was done, but no content. */ - uint8_t got4; -- /** if the ipv6 address is in the delegpt */ -+ /** if the ipv6 address is in the delegpt, 0=not, 1=yes 2=negative */ - uint8_t got6; - /** - * If the name is parent-side only and thus dispreferred. -@@ -213,11 +214,12 @@ int delegpt_rrset_add_ns(struct delegpt* dp, struct regional* regional, - * @param addrlen: the length of addr. - * @param bogus: security status for the address, pass true if bogus. - * @param lame: address is lame. -+ * @param additions: will be set to 1 if a new address is added - * @return false on error. - */ - int delegpt_add_target(struct delegpt* dp, struct regional* regional, - uint8_t* name, size_t namelen, struct sockaddr_storage* addr, -- socklen_t addrlen, uint8_t bogus, uint8_t lame); -+ socklen_t addrlen, uint8_t bogus, uint8_t lame, int* additions); - - /** - * Add A RRset to delegpt. -@@ -225,10 +227,11 @@ int delegpt_add_target(struct delegpt* dp, struct regional* regional, - * @param regional: where to allocate the info. - * @param rrset: RRset A to add. - * @param lame: rrset is lame, disprefer it. -+ * @param additions: will be set to 1 if a new address is added - * @return 0 on alloc error. - */ - int delegpt_add_rrset_A(struct delegpt* dp, struct regional* regional, -- struct ub_packed_rrset_key* rrset, uint8_t lame); -+ struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions); - - /** - * Add AAAA RRset to delegpt. -@@ -236,10 +239,11 @@ int delegpt_add_rrset_A(struct delegpt* dp, struct regional* regional, - * @param regional: where to allocate the info. - * @param rrset: RRset AAAA to add. - * @param lame: rrset is lame, disprefer it. -+ * @param additions: will be set to 1 if a new address is added - * @return 0 on alloc error. - */ - int delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* regional, -- struct ub_packed_rrset_key* rrset, uint8_t lame); -+ struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions); - - /** - * Add any RRset to delegpt. -@@ -248,10 +252,11 @@ int delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* regional, - * @param regional: where to allocate the info. - * @param rrset: RRset to add, NS, A, AAAA. - * @param lame: rrset is lame, disprefer it. -+ * @param additions: will be set to 1 if a new address is added - * @return 0 on alloc error. - */ - int delegpt_add_rrset(struct delegpt* dp, struct regional* regional, -- struct ub_packed_rrset_key* rrset, uint8_t lame); -+ struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions); - - /** - * Add address to the delegation point. No servername is associated or checked. -@@ -262,11 +267,13 @@ int delegpt_add_rrset(struct delegpt* dp, struct regional* regional, - * @param bogus: if address is bogus. - * @param lame: if address is lame. - * @param tls_auth_name: TLS authentication name (or NULL). -+ * @param additions: will be set to 1 if a new address is added -+ * @return 0 on alloc error. - * @return false on error. - */ - int delegpt_add_addr(struct delegpt* dp, struct regional* regional, - struct sockaddr_storage* addr, socklen_t addrlen, -- uint8_t bogus, uint8_t lame, char* tls_auth_name); -+ uint8_t bogus, uint8_t lame, char* tls_auth_name, int* additions); - - /** - * Find NS record in name list of delegation point. -@@ -339,6 +346,14 @@ size_t delegpt_count_targets(struct delegpt* dp); - struct delegpt* delegpt_from_message(struct dns_msg* msg, - struct regional* regional); - -+/** -+* Mark negative return in delegation point for specific nameserver. -+* sets the got4 or got6 to negative, updates the ns->resolved. -+* @param ns: the nameserver in the delegpt. -+* @param qtype: A or AAAA (host order). -+*/ -+void delegpt_mark_neg(struct delegpt_ns* ns, uint16_t qtype); -+ - /** - * Add negative message to delegation point. - * @param dp: delegation point. -diff --git a/iterator/iter_scrub.c b/iterator/iter_scrub.c -index 12580dc..8230d17 100644 ---- a/iterator/iter_scrub.c -+++ b/iterator/iter_scrub.c -@@ -185,8 +185,9 @@ mark_additional_rrset(sldns_buffer* pkt, struct msg_parse* msg, - /** Get target name of a CNAME */ - static int - parse_get_cname_target(struct rrset_parse* rrset, uint8_t** sname, -- size_t* snamelen) -+ size_t* snamelen, sldns_buffer* pkt) - { -+ size_t oldpos, dlen; - if(rrset->rr_count != 1) { - struct rr_parse* sig; - verbose(VERB_ALGO, "Found CNAME rrset with " -@@ -204,6 +205,19 @@ parse_get_cname_target(struct rrset_parse* rrset, uint8_t** sname, - *sname = rrset->rr_first->ttl_data + sizeof(uint32_t) - + sizeof(uint16_t); /* skip ttl, rdatalen */ - *snamelen = rrset->rr_first->size - sizeof(uint16_t); -+ -+ if(rrset->rr_first->outside_packet) { -+ if(!dname_valid(*sname, *snamelen)) -+ return 0; -+ return 1; -+ } -+ oldpos = sldns_buffer_position(pkt); -+ sldns_buffer_set_position(pkt, (size_t)(*sname - sldns_buffer_begin(pkt))); -+ dlen = pkt_dname_len(pkt); -+ sldns_buffer_set_position(pkt, oldpos); -+ if(dlen == 0) -+ return 0; /* parse fail on the rdata name */ -+ *snamelen = dlen; - return 1; - } - -@@ -215,7 +229,7 @@ synth_cname(uint8_t* qname, size_t qnamelen, struct rrset_parse* dname_rrset, - /* we already know that sname is a strict subdomain of DNAME owner */ - uint8_t* dtarg = NULL; - size_t dtarglen; -- if(!parse_get_cname_target(dname_rrset, &dtarg, &dtarglen)) -+ if(!parse_get_cname_target(dname_rrset, &dtarg, &dtarglen, pkt)) - return 0; - log_assert(qnamelen > dname_rrset->dname_len); - /* DNAME from com. to net. with qname example.com. -> example.net. */ -@@ -372,7 +386,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg, - /* check next cname */ - uint8_t* t = NULL; - size_t tlen = 0; -- if(!parse_get_cname_target(nx, &t, &tlen)) -+ if(!parse_get_cname_target(nx, &t, &tlen, pkt)) - return 0; - if(dname_pkt_compare(pkt, alias, t) == 0) { - /* it's OK and better capitalized */ -@@ -423,7 +437,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg, - size_t tlen = 0; - if(synth_cname(sname, snamelen, nx, alias, - &aliaslen, pkt) && -- parse_get_cname_target(rrset, &t, &tlen) && -+ parse_get_cname_target(rrset, &t, &tlen, pkt) && - dname_pkt_compare(pkt, alias, t) == 0) { - /* the synthesized CNAME equals the - * current CNAME. This CNAME is the -@@ -442,7 +456,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg, - } - - /* move to next name in CNAME chain */ -- if(!parse_get_cname_target(rrset, &sname, &snamelen)) -+ if(!parse_get_cname_target(rrset, &sname, &snamelen, pkt)) - return 0; - prev = rrset; - rrset = rrset->rrset_all_next; -diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c -index 0a8f770..a107bee 100644 ---- a/iterator/iter_utils.c -+++ b/iterator/iter_utils.c -@@ -1008,7 +1008,7 @@ int iter_lookup_parent_glue_from_cache(struct module_env* env, - log_rrset_key(VERB_ALGO, "found parent-side", akey); - ns->done_pside4 = 1; - /* a negative-cache-element has no addresses it adds */ -- if(!delegpt_add_rrset_A(dp, region, akey, 1)) -+ if(!delegpt_add_rrset_A(dp, region, akey, 1, NULL)) - log_err("malloc failure in lookup_parent_glue"); - lock_rw_unlock(&akey->entry.lock); - } -@@ -1020,7 +1020,7 @@ int iter_lookup_parent_glue_from_cache(struct module_env* env, - log_rrset_key(VERB_ALGO, "found parent-side", akey); - ns->done_pside6 = 1; - /* a negative-cache-element has no addresses it adds */ -- if(!delegpt_add_rrset_AAAA(dp, region, akey, 1)) -+ if(!delegpt_add_rrset_AAAA(dp, region, akey, 1, NULL)) - log_err("malloc failure in lookup_parent_glue"); - lock_rw_unlock(&akey->entry.lock); - } -diff --git a/iterator/iterator.c b/iterator/iterator.c -index 58a9bff..a4ad319 100644 ---- a/iterator/iterator.c -+++ b/iterator/iterator.c -@@ -69,6 +69,8 @@ - #include "sldns/parseutil.h" - #include "sldns/sbuffer.h" - -+static void target_count_increase_nx(struct iter_qstate* iq, int num); -+ - int - iter_init(struct module_env* env, int id) - { -@@ -147,6 +149,7 @@ iter_new(struct module_qstate* qstate, int id) - iq->sent_count = 0; - iq->ratelimit_ok = 0; - iq->target_count = NULL; -+ iq->dp_target_count = 0; - iq->wait_priming_stub = 0; - iq->refetch_glue = 0; - iq->dnssec_expected = 0; -@@ -218,6 +221,7 @@ final_state(struct iter_qstate* iq) - static void - error_supers(struct module_qstate* qstate, int id, struct module_qstate* super) - { -+ struct iter_env* ie = (struct iter_env*)qstate->env->modinfo[id]; - struct iter_qstate* super_iq = (struct iter_qstate*)super->minfo[id]; - - if(qstate->qinfo.qtype == LDNS_RR_TYPE_A || -@@ -242,7 +246,11 @@ error_supers(struct module_qstate* qstate, int id, struct module_qstate* super) - super->region, super_iq->dp)) - log_err("out of memory adding missing"); - } -+ delegpt_mark_neg(dpns, qstate->qinfo.qtype); - dpns->resolved = 1; /* mark as failed */ -+ if((dpns->got4 == 2 || !ie->supports_ipv4) && -+ (dpns->got6 == 2 || !ie->supports_ipv6)) -+ target_count_increase_nx(super_iq, 1); - } - if(qstate->qinfo.qtype == LDNS_RR_TYPE_NS) { - /* prime failed to get delegation */ -@@ -577,7 +585,7 @@ static void - target_count_create(struct iter_qstate* iq) - { - if(!iq->target_count) { -- iq->target_count = (int*)calloc(2, sizeof(int)); -+ iq->target_count = (int*)calloc(3, sizeof(int)); - /* if calloc fails we simply do not track this number */ - if(iq->target_count) - iq->target_count[0] = 1; -@@ -590,6 +598,15 @@ target_count_increase(struct iter_qstate* iq, int num) - target_count_create(iq); - if(iq->target_count) - iq->target_count[1] += num; -+ iq->dp_target_count++; -+} -+ -+static void -+target_count_increase_nx(struct iter_qstate* iq, int num) -+{ -+ target_count_create(iq); -+ if(iq->target_count) -+ iq->target_count[2] += num; - } - - /** -@@ -612,13 +629,15 @@ target_count_increase(struct iter_qstate* iq, int num) - * @param subq_ret: if newly allocated, the subquerystate, or NULL if it does - * not need initialisation. - * @param v: if true, validation is done on the subquery. -+ * @param detached: true if this qstate should not attach to the subquery - * @return false on error (malloc). - */ - static int - generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype, - uint16_t qclass, struct module_qstate* qstate, int id, - struct iter_qstate* iq, enum iter_state initial_state, -- enum iter_state finalstate, struct module_qstate** subq_ret, int v) -+ enum iter_state finalstate, struct module_qstate** subq_ret, int v, -+ int detached) - { - struct module_qstate* subq = NULL; - struct iter_qstate* subiq = NULL; -@@ -645,12 +664,24 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype, - valrec = 1; - } - -- /* attach subquery, lookup existing or make a new one */ -- fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub)); -- if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, valrec, -- &subq)) { -- return 0; -- } -+ if(detached) { -+ struct mesh_state* sub = NULL; -+ fptr_ok(fptr_whitelist_modenv_add_sub( -+ qstate->env->add_sub)); -+ if(!(*qstate->env->add_sub)(qstate, &qinf, -+ qflags, prime, valrec, &subq, &sub)){ -+ return 0; -+ } -+ } -+ else { -+ /* attach subquery, lookup existing or make a new one */ -+ fptr_ok(fptr_whitelist_modenv_attach_sub( -+ qstate->env->attach_sub)); -+ if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, -+ valrec, &subq)) { -+ return 0; -+ } -+ } - *subq_ret = subq; - if(subq) { - /* initialise the new subquery */ -@@ -672,6 +703,7 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype, - subiq->target_count = iq->target_count; - if(iq->target_count) - iq->target_count[0] ++; /* extra reference */ -+ subiq->dp_target_count = 0; - subiq->num_current_queries = 0; - subiq->depth = iq->depth+1; - outbound_list_init(&subiq->outlist); -@@ -715,7 +747,7 @@ prime_root(struct module_qstate* qstate, struct iter_qstate* iq, int id, - * the normal INIT state logic (which would cause an infloop). */ - if(!generate_sub_request((uint8_t*)"\000", 1, LDNS_RR_TYPE_NS, - qclass, qstate, id, iq, QUERYTARGETS_STATE, PRIME_RESP_STATE, -- &subq, 0)) { -+ &subq, 0, 0)) { - verbose(VERB_ALGO, "could not prime root"); - return 0; - } -@@ -805,7 +837,7 @@ prime_stub(struct module_qstate* qstate, struct iter_qstate* iq, int id, - * redundant INIT state processing. */ - if(!generate_sub_request(stub_dp->name, stub_dp->namelen, - LDNS_RR_TYPE_NS, qclass, qstate, id, iq, -- QUERYTARGETS_STATE, PRIME_RESP_STATE, &subq, 0)) { -+ QUERYTARGETS_STATE, PRIME_RESP_STATE, &subq, 0, 0)) { - verbose(VERB_ALGO, "could not prime stub"); - (void)error_response(qstate, id, LDNS_RCODE_SERVFAIL); - return 1; /* return 1 to make module stop, with error */ -@@ -976,7 +1008,7 @@ generate_a_aaaa_check(struct module_qstate* qstate, struct iter_qstate* iq, - if(!generate_sub_request(s->rk.dname, s->rk.dname_len, - ntohs(s->rk.type), ntohs(s->rk.rrset_class), - qstate, id, iq, -- INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) { -+ INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1, 0)) { - verbose(VERB_ALGO, "could not generate addr check"); - return; - } -@@ -1020,7 +1052,7 @@ generate_ns_check(struct module_qstate* qstate, struct iter_qstate* iq, int id) - iq->dp->name, LDNS_RR_TYPE_NS, iq->qchase.qclass); - if(!generate_sub_request(iq->dp->name, iq->dp->namelen, - LDNS_RR_TYPE_NS, iq->qchase.qclass, qstate, id, iq, -- INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) { -+ INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1, 0)) { - verbose(VERB_ALGO, "could not generate ns check"); - return; - } -@@ -1077,7 +1109,7 @@ generate_dnskey_prefetch(struct module_qstate* qstate, - iq->dp->name, LDNS_RR_TYPE_DNSKEY, iq->qchase.qclass); - if(!generate_sub_request(iq->dp->name, iq->dp->namelen, - LDNS_RR_TYPE_DNSKEY, iq->qchase.qclass, qstate, id, iq, -- INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0)) { -+ INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0, 0)) { - /* we'll be slower, but it'll work */ - verbose(VERB_ALGO, "could not generate dnskey prefetch"); - return; -@@ -1251,6 +1283,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq, - iq->refetch_glue = 0; - iq->query_restart_count++; - iq->sent_count = 0; -+ iq->dp_target_count = 0; - sock_list_insert(&qstate->reply_origin, NULL, 0, qstate->region); - if(qstate->env->cfg->qname_minimisation) - iq->minimisation_state = INIT_MINIMISE_STATE; -@@ -1613,7 +1646,7 @@ generate_parentside_target_query(struct module_qstate* qstate, - { - struct module_qstate* subq; - if(!generate_sub_request(name, namelen, qtype, qclass, qstate, -- id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0)) -+ id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0, 0)) - return 0; - if(subq) { - struct iter_qstate* subiq = -@@ -1664,7 +1697,7 @@ generate_target_query(struct module_qstate* qstate, struct iter_qstate* iq, - { - struct module_qstate* subq; - if(!generate_sub_request(name, namelen, qtype, qclass, qstate, -- id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0)) -+ id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0, 0)) - return 0; - log_nametypeclass(VERB_QUERY, "new target", name, qtype, qclass); - return 1; -@@ -1703,6 +1736,14 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq, - "number of glue fetches %d", s, iq->target_count[1]); - return 0; - } -+ if(iq->dp_target_count > MAX_DP_TARGET_COUNT) { -+ char s[LDNS_MAX_DOMAINLEN+1]; -+ dname_str(qstate->qinfo.qname, s); -+ verbose(VERB_QUERY, "request %s has exceeded the maximum " -+ "number of glue fetches %d to a single delegation point", -+ s, iq->dp_target_count); -+ return 0; -+ } - - iter_mark_cycle_targets(qstate, iq->dp); - missing = (int)delegpt_count_missing_targets(iq->dp); -@@ -1815,7 +1856,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq, - for(a = p->target_list; a; a=a->next_target) { - (void)delegpt_add_addr(iq->dp, qstate->region, - &a->addr, a->addrlen, a->bogus, -- a->lame, a->tls_auth_name); -+ a->lame, a->tls_auth_name, NULL); - } - } - iq->dp->has_parent_side_NS = 1; -@@ -1832,6 +1873,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq, - iq->refetch_glue = 1; - iq->query_restart_count++; - iq->sent_count = 0; -+ iq->dp_target_count = 0; - if(qstate->env->cfg->qname_minimisation) - iq->minimisation_state = INIT_MINIMISE_STATE; - return next_state(iq, INIT_REQUEST_STATE); -@@ -1986,7 +2028,7 @@ processDSNSFind(struct module_qstate* qstate, struct iter_qstate* iq, int id) - iq->dsns_point, LDNS_RR_TYPE_NS, iq->qchase.qclass); - if(!generate_sub_request(iq->dsns_point, iq->dsns_point_len, - LDNS_RR_TYPE_NS, iq->qchase.qclass, qstate, id, iq, -- INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0)) { -+ INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0, 0)) { - return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL); - } - -@@ -2039,7 +2081,14 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, - "number of sends with %d", iq->sent_count); - return error_response(qstate, id, LDNS_RCODE_SERVFAIL); - } -- -+ if(iq->target_count && iq->target_count[2] > MAX_TARGET_NX) { -+ verbose(VERB_QUERY, "request has exceeded the maximum " -+ " number of nxdomain nameserver lookups with %d", -+ iq->target_count[2]); -+ errinf(qstate, "exceeded the maximum nameserver nxdomains"); -+ return error_response(qstate, id, LDNS_RCODE_SERVFAIL); -+ } -+ - /* Make sure we have a delegation point, otherwise priming failed - * or another failure occurred */ - if(!iq->dp) { -@@ -2139,12 +2188,41 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, - iq->qinfo_out.qtype, iq->qinfo_out.qclass, - qstate->query_flags, qstate->region, - qstate->env->scratch, 0); -- if(msg && msg->rep->an_numrrsets == 0 -- && FLAGS_GET_RCODE(msg->rep->flags) == -+ if(msg && FLAGS_GET_RCODE(msg->rep->flags) == - LDNS_RCODE_NOERROR) - /* no need to send query if it is already -- * cached as NOERROR/NODATA */ -+ * cached as NOERROR */ - return 1; -+ if(msg && FLAGS_GET_RCODE(msg->rep->flags) == -+ LDNS_RCODE_NXDOMAIN && -+ qstate->env->need_to_validate && -+ qstate->env->cfg->harden_below_nxdomain) { -+ if(msg->rep->security == sec_status_secure) { -+ iq->response = msg; -+ return final_state(iq); -+ } -+ if(msg->rep->security == sec_status_unchecked) { -+ struct module_qstate* subq = NULL; -+ if(!generate_sub_request( -+ iq->qinfo_out.qname, -+ iq->qinfo_out.qname_len, -+ iq->qinfo_out.qtype, -+ iq->qinfo_out.qclass, -+ qstate, id, iq, -+ INIT_REQUEST_STATE, -+ FINISHED_STATE, &subq, 1, 1)) -+ verbose(VERB_ALGO, -+ "could not validate NXDOMAIN " -+ "response"); -+ } -+ } -+ if(msg && FLAGS_GET_RCODE(msg->rep->flags) == -+ LDNS_RCODE_NXDOMAIN) { -+ /* return and add a label in the next -+ * minimisation iteration. -+ */ -+ return 1; -+ } - } - } - if(iq->minimisation_state == SKIP_MINIMISE_STATE) { -@@ -2219,6 +2297,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, - * generated query will immediately be discarded due to depth and - * that servfail is cached, which is not good as opportunism goes. */ - if(iq->depth < ie->max_dependency_depth -+ && iq->num_target_queries == 0 -+ && (!iq->target_count || iq->target_count[2]==0) - && iq->sent_count < TARGET_FETCH_STOP) { - tf_policy = ie->target_fetch_policy[iq->depth]; - } -@@ -2256,6 +2336,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, - iq->num_current_queries++; /* RespState decrements it*/ - iq->referral_count++; /* make sure we don't loop */ - iq->sent_count = 0; -+ iq->dp_target_count = 0; - iq->state = QUERY_RESP_STATE; - return 1; - } -@@ -2341,6 +2422,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, - iq->num_current_queries++; /* RespState decrements it*/ - iq->referral_count++; /* make sure we don't loop */ - iq->sent_count = 0; -+ iq->dp_target_count = 0; - iq->state = QUERY_RESP_STATE; - return 1; - } -@@ -2607,7 +2689,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, - /* Make subrequest to validate intermediate - * NXDOMAIN if harden-below-nxdomain is - * enabled. */ -- if(qstate->env->cfg->harden_below_nxdomain) { -+ if(qstate->env->cfg->harden_below_nxdomain && -+ qstate->env->need_to_validate) { - struct module_qstate* subq = NULL; - log_query_info(VERB_QUERY, - "schedule NXDOMAIN validation:", -@@ -2619,7 +2702,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, - iq->response->qinfo.qclass, - qstate, id, iq, - INIT_REQUEST_STATE, -- FINISHED_STATE, &subq, 1)) -+ FINISHED_STATE, &subq, 1, 1)) - verbose(VERB_ALGO, - "could not validate NXDOMAIN " - "response"); -@@ -2702,6 +2785,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, - /* Count this as a referral. */ - iq->referral_count++; - iq->sent_count = 0; -+ iq->dp_target_count = 0; - /* see if the next dp is a trust anchor, or a DS was sent - * along, indicating dnssec is expected for next zone */ - iq->dnssec_expected = iter_indicates_dnssec(qstate->env, -@@ -2776,6 +2860,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, - iq->dsns_point = NULL; - iq->auth_zone_response = 0; - iq->sent_count = 0; -+ iq->dp_target_count = 0; - if(iq->minimisation_state != MINIMISE_STATE) - /* Only count as query restart when it is not an extra - * query as result of qname minimisation. */ -@@ -2964,7 +3049,7 @@ processPrimeResponse(struct module_qstate* qstate, int id) - if(!generate_sub_request(qstate->qinfo.qname, - qstate->qinfo.qname_len, qstate->qinfo.qtype, - qstate->qinfo.qclass, qstate, id, iq, -- INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) { -+ INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1, 0)) { - verbose(VERB_ALGO, "could not generate prime check"); - } - generate_a_aaaa_check(qstate, iq, id); -@@ -2992,6 +3077,7 @@ static void - processTargetResponse(struct module_qstate* qstate, int id, - struct module_qstate* forq) - { -+ struct iter_env* ie = (struct iter_env*)qstate->env->modinfo[id]; - struct iter_qstate* iq = (struct iter_qstate*)qstate->minfo[id]; - struct iter_qstate* foriq = (struct iter_qstate*)forq->minfo[id]; - struct ub_packed_rrset_key* rrset; -@@ -3029,7 +3115,7 @@ processTargetResponse(struct module_qstate* qstate, int id, - log_rrset_key(VERB_ALGO, "add parentside glue to dp", - iq->pside_glue); - if(!delegpt_add_rrset(foriq->dp, forq->region, -- iq->pside_glue, 1)) -+ iq->pside_glue, 1, NULL)) - log_err("out of memory adding pside glue"); - } - -@@ -3040,6 +3126,7 @@ processTargetResponse(struct module_qstate* qstate, int id, - * response type was ANSWER. */ - rrset = reply_find_answer_rrset(&iq->qchase, qstate->return_msg->rep); - if(rrset) { -+ int additions = 0; - /* if CNAMEs have been followed - add new NS to delegpt. */ - /* BTW. RFC 1918 says NS should not have got CNAMEs. Robust. */ - if(!delegpt_find_ns(foriq->dp, rrset->rk.dname, -@@ -3051,13 +3138,23 @@ processTargetResponse(struct module_qstate* qstate, int id, - } - /* if dpns->lame then set the address(es) lame too */ - if(!delegpt_add_rrset(foriq->dp, forq->region, rrset, -- dpns->lame)) -+ dpns->lame, &additions)) - log_err("out of memory adding targets"); -+ if(!additions) { -+ /* no new addresses, increase the nxns counter, like -+ * this could be a list of wildcards with no new -+ * addresses */ -+ target_count_increase_nx(foriq, 1); -+ } - verbose(VERB_ALGO, "added target response"); - delegpt_log(VERB_ALGO, foriq->dp); - } else { - verbose(VERB_ALGO, "iterator TargetResponse failed"); -+ delegpt_mark_neg(dpns, qstate->qinfo.qtype); - dpns->resolved = 1; /* fail the target */ -+ if((dpns->got4 == 2 || !ie->supports_ipv4) && -+ (dpns->got6 == 2 || !ie->supports_ipv6)) -+ target_count_increase_nx(foriq, 1); - } - } - -@@ -3228,7 +3325,7 @@ processCollectClass(struct module_qstate* qstate, int id) - qstate->qinfo.qname_len, qstate->qinfo.qtype, - c, qstate, id, iq, INIT_REQUEST_STATE, - FINISHED_STATE, &subq, -- (int)!(qstate->query_flags&BIT_CD))) { -+ (int)!(qstate->query_flags&BIT_CD), 0)) { - return error_response(qstate, id, - LDNS_RCODE_SERVFAIL); - } -diff --git a/iterator/iterator.h b/iterator/iterator.h -index 67ffeb1..4b325b5 100644 ---- a/iterator/iterator.h -+++ b/iterator/iterator.h -@@ -55,6 +55,11 @@ struct rbtree_type; - - /** max number of targets spawned for a query and its subqueries */ - #define MAX_TARGET_COUNT 64 -+/** max number of target lookups per qstate, per delegation point */ -+#define MAX_DP_TARGET_COUNT 16 -+/** max number of nxdomains allowed for target lookups for a query and -+ * its subqueries */ -+#define MAX_TARGET_NX 5 - /** max number of query restarts. Determines max number of CNAME chain. */ - #define MAX_RESTART_COUNT 8 - /** max number of referrals. Makes sure resolver does not run away */ -@@ -305,9 +310,14 @@ struct iter_qstate { - int sent_count; - - /** number of target queries spawned in [1], for this query and its -- * subqueries, the malloced-array is shared, [0] refcount. */ -+ * subqueries, the malloced-array is shared, [0] refcount. -+ * in [2] the number of nxdomains is counted. */ - int* target_count; - -+ /** number of target lookups per delegation point. Reset to 0 after -+ * receiving referral answer. Not shared with subqueries. */ -+ int dp_target_count; -+ - /** if true, already tested for ratelimiting and passed the test */ - int ratelimit_ok; - -diff --git a/services/cache/dns.c b/services/cache/dns.c -index 35adc35..23ec68e 100644 ---- a/services/cache/dns.c -+++ b/services/cache/dns.c -@@ -271,7 +271,7 @@ find_add_addrs(struct module_env* env, uint16_t qclass, - akey = rrset_cache_lookup(env->rrset_cache, ns->name, - ns->namelen, LDNS_RR_TYPE_A, qclass, 0, now, 0); - if(akey) { -- if(!delegpt_add_rrset_A(dp, region, akey, 0)) { -+ if(!delegpt_add_rrset_A(dp, region, akey, 0, NULL)) { - lock_rw_unlock(&akey->entry.lock); - return 0; - } -@@ -291,7 +291,7 @@ find_add_addrs(struct module_env* env, uint16_t qclass, - akey = rrset_cache_lookup(env->rrset_cache, ns->name, - ns->namelen, LDNS_RR_TYPE_AAAA, qclass, 0, now, 0); - if(akey) { -- if(!delegpt_add_rrset_AAAA(dp, region, akey, 0)) { -+ if(!delegpt_add_rrset_AAAA(dp, region, akey, 0, NULL)) { - lock_rw_unlock(&akey->entry.lock); - return 0; - } -@@ -325,7 +325,8 @@ cache_fill_missing(struct module_env* env, uint16_t qclass, - akey = rrset_cache_lookup(env->rrset_cache, ns->name, - ns->namelen, LDNS_RR_TYPE_A, qclass, 0, now, 0); - if(akey) { -- if(!delegpt_add_rrset_A(dp, region, akey, ns->lame)) { -+ if(!delegpt_add_rrset_A(dp, region, akey, ns->lame, -+ NULL)) { - lock_rw_unlock(&akey->entry.lock); - return 0; - } -@@ -345,7 +346,8 @@ cache_fill_missing(struct module_env* env, uint16_t qclass, - akey = rrset_cache_lookup(env->rrset_cache, ns->name, - ns->namelen, LDNS_RR_TYPE_AAAA, qclass, 0, now, 0); - if(akey) { -- if(!delegpt_add_rrset_AAAA(dp, region, akey, ns->lame)) { -+ if(!delegpt_add_rrset_AAAA(dp, region, akey, ns->lame, -+ NULL)) { - lock_rw_unlock(&akey->entry.lock); - return 0; - } -diff --git a/util/data/dname.c b/util/data/dname.c -index c7360f7..b744f06 100644 ---- a/util/data/dname.c -+++ b/util/data/dname.c -@@ -231,17 +231,28 @@ int - dname_pkt_compare(sldns_buffer* pkt, uint8_t* d1, uint8_t* d2) - { - uint8_t len1, len2; -+ int count1 = 0, count2 = 0; - log_assert(pkt && d1 && d2); - len1 = *d1++; - len2 = *d2++; - while( len1 != 0 || len2 != 0 ) { - /* resolve ptrs */ - if(LABEL_IS_PTR(len1)) { -+ if((size_t)PTR_OFFSET(len1, *d1) -+ >= sldns_buffer_limit(pkt)) -+ return -1; -+ if(count1++ > MAX_COMPRESS_PTRS) -+ return -1; - d1 = sldns_buffer_at(pkt, PTR_OFFSET(len1, *d1)); - len1 = *d1++; - continue; - } - if(LABEL_IS_PTR(len2)) { -+ if((size_t)PTR_OFFSET(len2, *d2) -+ >= sldns_buffer_limit(pkt)) -+ return 1; -+ if(count2++ > MAX_COMPRESS_PTRS) -+ return 1; - d2 = sldns_buffer_at(pkt, PTR_OFFSET(len2, *d2)); - len2 = *d2++; - continue; -@@ -300,12 +311,19 @@ dname_pkt_hash(sldns_buffer* pkt, uint8_t* dname, hashvalue_type h) - uint8_t labuf[LDNS_MAX_LABELLEN+1]; - uint8_t lablen; - int i; -+ int count = 0; - - /* preserve case of query, make hash label by label */ - lablen = *dname++; - while(lablen) { - if(LABEL_IS_PTR(lablen)) { - /* follow pointer */ -+ if((size_t)PTR_OFFSET(lablen, *dname) -+ >= sldns_buffer_limit(pkt)) -+ return h; -+ if(count++ > MAX_COMPRESS_PTRS) -+ return h; -+ - dname = sldns_buffer_at(pkt, PTR_OFFSET(lablen, *dname)); - lablen = *dname++; - continue; -@@ -333,6 +351,9 @@ void dname_pkt_copy(sldns_buffer* pkt, uint8_t* to, uint8_t* dname) - while(lablen) { - if(LABEL_IS_PTR(lablen)) { - /* follow pointer */ -+ if((size_t)PTR_OFFSET(lablen, *dname) -+ >= sldns_buffer_limit(pkt)) -+ return; - dname = sldns_buffer_at(pkt, PTR_OFFSET(lablen, *dname)); - lablen = *dname++; - continue; -@@ -357,6 +378,7 @@ void dname_pkt_copy(sldns_buffer* pkt, uint8_t* to, uint8_t* dname) - void dname_print(FILE* out, struct sldns_buffer* pkt, uint8_t* dname) - { - uint8_t lablen; -+ int count = 0; - if(!out) out = stdout; - if(!dname) return; - -@@ -370,6 +392,15 @@ void dname_print(FILE* out, struct sldns_buffer* pkt, uint8_t* dname) - fputs("??compressionptr??", out); - return; - } -+ if((size_t)PTR_OFFSET(lablen, *dname) -+ >= sldns_buffer_limit(pkt)) { -+ fputs("??compressionptr??", out); -+ return; -+ } -+ if(count++ > MAX_COMPRESS_PTRS) { -+ fputs("??compressionptr??", out); -+ return; -+ } - dname = sldns_buffer_at(pkt, PTR_OFFSET(lablen, *dname)); - lablen = *dname++; - continue; -diff --git a/util/data/msgparse.c b/util/data/msgparse.c -index 13cad8a..c8a5384 100644 ---- a/util/data/msgparse.c -+++ b/util/data/msgparse.c -@@ -55,7 +55,11 @@ smart_compare(sldns_buffer* pkt, uint8_t* dnow, - { - if(LABEL_IS_PTR(*dnow)) { - /* ptr points to a previous dname */ -- uint8_t* p = sldns_buffer_at(pkt, PTR_OFFSET(dnow[0], dnow[1])); -+ uint8_t* p; -+ if((size_t)PTR_OFFSET(dnow[0], dnow[1]) -+ >= sldns_buffer_limit(pkt)) -+ return -1; -+ p = sldns_buffer_at(pkt, PTR_OFFSET(dnow[0], dnow[1])); - if( p == dprfirst || p == dprlast ) - return 0; - /* prev dname is also a ptr, both ptrs are the same. */ diff --git a/SOURCES/unbound-1.7.3-anchor-fallback.patch b/SOURCES/unbound-1.7.3-anchor-fallback.patch deleted file mode 100644 index 2470ce1..0000000 --- a/SOURCES/unbound-1.7.3-anchor-fallback.patch +++ /dev/null @@ -1,182 +0,0 @@ -From 81e9f82a8ddd811d7ebafe2fd0ee5af836d0b405 Mon Sep 17 00:00:00 2001 -From: Wouter Wijngaards -Date: Wed, 4 Jul 2018 10:02:16 +0000 -Subject: [PATCH] - Fix #4112: Fix that unbound-anchor -f /etc/resolv.conf will - not pass if DNSSEC is not enabled. New option -R allows fallback from - resolv.conf to direct queries. - -git-svn-id: file:///svn/unbound/trunk@4770 be551aaa-1e26-0410-a405-d3ace91eadb9 ---- - doc/unbound-anchor.8.in | 5 ++++ - smallapp/unbound-anchor.c | 66 ++++++++++++++++++++++++++++++++++------------- - 2 files changed, 53 insertions(+), 18 deletions(-) - -diff --git a/doc/unbound-anchor.8.in b/doc/unbound-anchor.8.in -index 02a3e781..e114eb25 100644 ---- a/doc/unbound-anchor.8.in -+++ b/doc/unbound-anchor.8.in -@@ -109,6 +109,11 @@ It does so, because the tool when used for bootstrapping the recursive - resolver, cannot use that recursive resolver itself because it is bootstrapping - that server. - .TP -+.B \-R -+Allow fallback from \-f resolv.conf file to direct root servers query. -+It allows you to prefer local resolvers, but fallback automatically -+to direct root query if they do not respond or do not support DNSSEC. -+.TP - .B \-v - More verbose. Once prints informational messages, multiple times may enable - large debug amounts (such as full certificates or byte\-dumps of downloaded -diff --git a/smallapp/unbound-anchor.c b/smallapp/unbound-anchor.c -index b3009108..f3985090 100644 ---- a/smallapp/unbound-anchor.c -+++ b/smallapp/unbound-anchor.c -@@ -192,9 +192,10 @@ usage(void) - printf("-n name signer's subject emailAddress, default %s\n", P7SIGNER); - printf("-4 work using IPv4 only\n"); - printf("-6 work using IPv6 only\n"); -- printf("-f resolv.conf use given resolv.conf to resolve -u name\n"); -- printf("-r root.hints use given root.hints to resolve -u name\n" -+ printf("-f resolv.conf use given resolv.conf\n"); -+ printf("-r root.hints use given root.hints\n" - " builtin root hints are used by default\n"); -+ printf("-R fallback from -f to root query on error\n"); - printf("-v more verbose\n"); - printf("-C conf debug, read config\n"); - printf("-P port use port for https connect, default 443\n"); -@@ -1920,8 +1921,7 @@ static int - do_certupdate(const char* root_anchor_file, const char* root_cert_file, - const char* urlname, const char* xmlname, const char* p7sname, - const char* p7signer, const char* res_conf, const char* root_hints, -- const char* debugconf, int ip4only, int ip6only, int port, -- struct ub_result* dnskey) -+ const char* debugconf, int ip4only, int ip6only, int port) - { - STACK_OF(X509)* cert; - BIO *xml, *p7s; -@@ -1961,7 +1961,6 @@ do_certupdate(const char* root_anchor_file, const char* root_cert_file, - #ifndef S_SPLINT_S - sk_X509_pop_free(cert, X509_free); - #endif -- ub_resolve_free(dnskey); - ip_list_free(ip_list); - return 1; - } -@@ -2199,16 +2198,33 @@ probe_date_allows_certupdate(const char* root_anchor_file) - return 0; - } - -+static struct ub_result * -+fetch_root_key(const char* root_anchor_file, const char* res_conf, -+ const char* root_hints, const char* debugconf, -+ int ip4only, int ip6only) -+{ -+ struct ub_ctx* ctx; -+ struct ub_result* dnskey; -+ -+ ctx = create_unbound_context(res_conf, root_hints, debugconf, -+ ip4only, ip6only); -+ add_5011_probe_root(ctx, root_anchor_file); -+ dnskey = prime_root_key(ctx); -+ ub_ctx_delete(ctx); -+ return dnskey; -+} -+ - /** perform the unbound-anchor work */ - static int - do_root_update_work(const char* root_anchor_file, const char* root_cert_file, - const char* urlname, const char* xmlname, const char* p7sname, - const char* p7signer, const char* res_conf, const char* root_hints, -- const char* debugconf, int ip4only, int ip6only, int force, int port) -+ const char* debugconf, int ip4only, int ip6only, int force, -+ int res_conf_fallback, int port) - { -- struct ub_ctx* ctx; - struct ub_result* dnskey; - int used_builtin = 0; -+ int rcode; - - /* see if builtin rootanchor needs to be provided, or if - * rootanchor is 'revoked-trust-point' */ -@@ -2217,12 +2233,22 @@ do_root_update_work(const char* root_anchor_file, const char* root_cert_file, - - /* make unbound context with 5011-probe for root anchor, - * and probe . DNSKEY */ -- ctx = create_unbound_context(res_conf, root_hints, debugconf, -- ip4only, ip6only); -- add_5011_probe_root(ctx, root_anchor_file); -- dnskey = prime_root_key(ctx); -- ub_ctx_delete(ctx); -- -+ dnskey = fetch_root_key(root_anchor_file, res_conf, -+ root_hints, debugconf, ip4only, ip6only); -+ rcode = dnskey->rcode; -+ -+ if (res_conf_fallback && res_conf && !dnskey->secure) { -+ if (verb) printf("%s failed, retrying direct\n", res_conf); -+ ub_resolve_free(dnskey); -+ /* try direct query without res_conf */ -+ dnskey = fetch_root_key(root_anchor_file, NULL, -+ root_hints, debugconf, ip4only, ip6only); -+ if (rcode != 0 && dnskey->rcode == 0) { -+ res_conf = NULL; -+ rcode = 0; -+ } -+ } -+ - /* if secure: exit */ - if(dnskey->secure && !force) { - if(verb) printf("success: the anchor is ok\n"); -@@ -2230,18 +2256,18 @@ do_root_update_work(const char* root_anchor_file, const char* root_cert_file, - return used_builtin; - } - if(force && verb) printf("debug cert update forced\n"); -+ ub_resolve_free(dnskey); - - /* if not (and NOERROR): check date and do certupdate */ -- if((dnskey->rcode == 0 && -+ if((rcode == 0 && - probe_date_allows_certupdate(root_anchor_file)) || force) { - if(do_certupdate(root_anchor_file, root_cert_file, urlname, - xmlname, p7sname, p7signer, res_conf, root_hints, -- debugconf, ip4only, ip6only, port, dnskey)) -+ debugconf, ip4only, ip6only, port)) - return 1; - return used_builtin; - } - if(verb) printf("fail: the anchor is NOT ok and could not be fixed\n"); -- ub_resolve_free(dnskey); - return used_builtin; - } - -@@ -2264,8 +2290,9 @@ int main(int argc, char* argv[]) - const char* root_hints = NULL; - const char* debugconf = NULL; - int dolist=0, ip4only=0, ip6only=0, force=0, port = HTTPS_PORT; -+ int res_conf_fallback = 0; - /* parse the options */ -- while( (c=getopt(argc, argv, "46C:FP:a:c:f:hln:r:s:u:vx:")) != -1) { -+ while( (c=getopt(argc, argv, "46C:FRP:a:c:f:hln:r:s:u:vx:")) != -1) { - switch(c) { - case 'l': - dolist = 1; -@@ -2300,6 +2327,9 @@ int main(int argc, char* argv[]) - case 'r': - root_hints = optarg; - break; -+ case 'R': -+ res_conf_fallback = 1; -+ break; - case 'C': - debugconf = optarg; - break; -@@ -2346,5 +2376,5 @@ int main(int argc, char* argv[]) - - return do_root_update_work(root_anchor_file, root_cert_file, urlname, - xmlname, p7sname, p7signer, res_conf, root_hints, debugconf, -- ip4only, ip6only, force, port); -+ ip4only, ip6only, force, res_conf_fallback, port); - } --- -2.14.4 - diff --git a/SOURCES/unbound-1.7.3-auth-callback.patch b/SOURCES/unbound-1.7.3-auth-callback.patch deleted file mode 100644 index 57a8922..0000000 --- a/SOURCES/unbound-1.7.3-auth-callback.patch +++ /dev/null @@ -1,65 +0,0 @@ ---- a/services/authzone.c 2018-06-14 09:09:01.000000000 +0200 -+++ b/services/authzone.c 2020-04-16 18:55:50.806693241 +0200 -@@ -5139,7 +5139,7 @@ - log_assert(xfr->task_transfer); - lock_basic_lock(&xfr->lock); - env = xfr->task_transfer->env; -- if(env->outnet->want_to_quit) { -+ if(!env || env->outnet->want_to_quit) { - lock_basic_unlock(&xfr->lock); - return; /* stop on quit */ - } -@@ -5558,7 +5558,7 @@ - log_assert(xfr->task_transfer); - lock_basic_lock(&xfr->lock); - env = xfr->task_transfer->env; -- if(env->outnet->want_to_quit) { -+ if(!env || env->outnet->want_to_quit) { - lock_basic_unlock(&xfr->lock); - return 0; /* stop on quit */ - } -@@ -5619,7 +5619,7 @@ - log_assert(xfr->task_transfer); - lock_basic_lock(&xfr->lock); - env = xfr->task_transfer->env; -- if(env->outnet->want_to_quit) { -+ if(!env || env->outnet->want_to_quit) { - lock_basic_unlock(&xfr->lock); - return 0; /* stop on quit */ - } -@@ -5798,7 +5798,7 @@ - log_assert(xfr->task_probe); - lock_basic_lock(&xfr->lock); - env = xfr->task_probe->env; -- if(env->outnet->want_to_quit) { -+ if(!env || env->outnet->want_to_quit) { - lock_basic_unlock(&xfr->lock); - return; /* stop on quit */ - } -@@ -5829,7 +5829,7 @@ - log_assert(xfr->task_probe); - lock_basic_lock(&xfr->lock); - env = xfr->task_probe->env; -- if(env->outnet->want_to_quit) { -+ if(!env || env->outnet->want_to_quit) { - lock_basic_unlock(&xfr->lock); - return 0; /* stop on quit */ - } -@@ -6030,7 +6030,7 @@ - log_assert(xfr->task_probe); - lock_basic_lock(&xfr->lock); - env = xfr->task_probe->env; -- if(env->outnet->want_to_quit) { -+ if(!env || env->outnet->want_to_quit) { - lock_basic_unlock(&xfr->lock); - return; /* stop on quit */ - } -@@ -6089,7 +6089,7 @@ - log_assert(xfr->task_nextprobe); - lock_basic_lock(&xfr->lock); - env = xfr->task_nextprobe->env; -- if(env->outnet->want_to_quit) { -+ if(!env || env->outnet->want_to_quit) { - lock_basic_unlock(&xfr->lock); - return; /* stop on quit */ - } diff --git a/SOURCES/unbound-1.7.3-crypto-policy-non-compliance-openssl.patch b/SOURCES/unbound-1.7.3-crypto-policy-non-compliance-openssl.patch deleted file mode 100644 index 6d4b906..0000000 --- a/SOURCES/unbound-1.7.3-crypto-policy-non-compliance-openssl.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/util/net_help.c b/util/net_help.c -index a5059b0..a193c36 100644 ---- a/util/net_help.c -+++ b/util/net_help.c -@@ -703,7 +703,7 @@ listen_sslctx_setup(void* ctxt) - #endif - #if defined(SHA256_DIGEST_LENGTH) && defined(USE_ECDSA) - /* if we have sha256, set the cipher list to have no known vulns */ -- if(!SSL_CTX_set_cipher_list(ctx, "TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256")) -+ if(!SSL_CTX_set_cipher_list(ctx, "PROFILE=SYSTEM")) - log_crypto_err("could not set cipher list with SSL_CTX_set_cipher_list"); - #endif - diff --git a/SOURCES/unbound-1.7.3-host-any.patch b/SOURCES/unbound-1.7.3-host-any.patch deleted file mode 100644 index 9db4b94..0000000 --- a/SOURCES/unbound-1.7.3-host-any.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/smallapp/unbound-host.c b/smallapp/unbound-host.c -index 53bf3277..f02511fe 100644 ---- a/smallapp/unbound-host.c -+++ b/smallapp/unbound-host.c -@@ -340,6 +340,7 @@ pretty_output(char* q, int t, int c, struct ub_result* result, int docname) - exit(1); - } - printf("%s\n", s); -+ free(s); - } else printf(" has no %s record", tstr); - printf(" %s\n", secstatus); - } diff --git a/SOURCES/unbound-1.7.3-ipsec-hook.patch b/SOURCES/unbound-1.7.3-ipsec-hook.patch deleted file mode 100644 index 30fea5d..0000000 --- a/SOURCES/unbound-1.7.3-ipsec-hook.patch +++ /dev/null @@ -1,218 +0,0 @@ -diff --git a/ipsecmod/ipsecmod.c b/ipsecmod/ipsecmod.c -index c8400c6..9e916d6 100644 ---- a/ipsecmod/ipsecmod.c -+++ b/ipsecmod/ipsecmod.c -@@ -162,6 +162,71 @@ generate_request(struct module_qstate* qstate, int id, uint8_t* name, - } - - /** -+ * Check if the string passed is a valid domain name with safe characters to -+ * pass to a shell. -+ * This will only allow: -+ * - digits -+ * - alphas -+ * - hyphen (not at the start) -+ * - dot (not at the start, or the only character) -+ * - underscore -+ * @param s: pointer to the string. -+ * @param slen: string's length. -+ * @return true if s only contains safe characters; false otherwise. -+ */ -+static int -+domainname_has_safe_characters(char* s, size_t slen) { -+ size_t i; -+ for(i = 0; i < slen; i++) { -+ if(s[i] == '\0') return 1; -+ if((s[i] == '-' && i != 0) -+ || (s[i] == '.' && (i != 0 || s[1] == '\0')) -+ || (s[i] == '_') || (s[i] >= '0' && s[i] <= '9') -+ || (s[i] >= 'A' && s[i] <= 'Z') -+ || (s[i] >= 'a' && s[i] <= 'z')) { -+ continue; -+ } -+ return 0; -+ } -+ return 1; -+} -+ -+/** -+ * Check if the stringified IPSECKEY RDATA contains safe characters to pass to -+ * a shell. -+ * This is only relevant for checking the gateway when the gateway type is 3 -+ * (domainname). -+ * @param s: pointer to the string. -+ * @param slen: string's length. -+ * @return true if s contains only safe characters; false otherwise. -+ */ -+static int -+ipseckey_has_safe_characters(char* s, size_t slen) { -+ int precedence, gateway_type, algorithm; -+ char* gateway; -+ gateway = (char*)calloc(slen, sizeof(char)); -+ if(!gateway) { -+ log_err("ipsecmod: out of memory when calling the hook"); -+ return 0; -+ } -+ if(sscanf(s, "%d %d %d %s ", -+ &precedence, &gateway_type, &algorithm, gateway) != 4) { -+ free(gateway); -+ return 0; -+ } -+ if(gateway_type != 3) { -+ free(gateway); -+ return 1; -+ } -+ if(domainname_has_safe_characters(gateway, slen)) { -+ free(gateway); -+ return 1; -+ } -+ free(gateway); -+ return 0; -+} -+ -+/** - * Prepare the data and call the hook. - * - * @param qstate: query state. -@@ -175,7 +240,7 @@ call_hook(struct module_qstate* qstate, struct ipsecmod_qstate* iq, - { - size_t slen, tempdata_len, tempstring_len, i; - char str[65535], *s, *tempstring; -- int w; -+ int w = 0, w_temp, qtype; - struct ub_packed_rrset_key* rrset_key; - struct packed_rrset_data* rrset_data; - uint8_t *tempdata; -@@ -192,9 +257,9 @@ call_hook(struct module_qstate* qstate, struct ipsecmod_qstate* iq, - memset(s, 0, slen); - - /* Copy the hook into the buffer. */ -- sldns_str_print(&s, &slen, "%s", qstate->env->cfg->ipsecmod_hook); -+ w += sldns_str_print(&s, &slen, "%s", qstate->env->cfg->ipsecmod_hook); - /* Put space into the buffer. */ -- sldns_str_print(&s, &slen, " "); -+ w += sldns_str_print(&s, &slen, " "); - /* Copy the qname into the buffer. */ - tempstring = sldns_wire2str_dname(qstate->qinfo.qname, - qstate->qinfo.qname_len); -@@ -202,68 +267,96 @@ call_hook(struct module_qstate* qstate, struct ipsecmod_qstate* iq, - log_err("ipsecmod: out of memory when calling the hook"); - return 0; - } -- sldns_str_print(&s, &slen, "\"%s\"", tempstring); -+ if(!domainname_has_safe_characters(tempstring, strlen(tempstring))) { -+ log_err("ipsecmod: qname has unsafe characters"); -+ free(tempstring); -+ return 0; -+ } -+ w += sldns_str_print(&s, &slen, "\"%s\"", tempstring); - free(tempstring); - /* Put space into the buffer. */ -- sldns_str_print(&s, &slen, " "); -+ w += sldns_str_print(&s, &slen, " "); - /* Copy the IPSECKEY TTL into the buffer. */ - rrset_data = (struct packed_rrset_data*)iq->ipseckey_rrset->entry.data; -- sldns_str_print(&s, &slen, "\"%ld\"", (long)rrset_data->ttl); -+ w += sldns_str_print(&s, &slen, "\"%ld\"", (long)rrset_data->ttl); - /* Put space into the buffer. */ -- sldns_str_print(&s, &slen, " "); -- /* Copy the A/AAAA record(s) into the buffer. Start and end this section -- * with a double quote. */ -+ w += sldns_str_print(&s, &slen, " "); - rrset_key = reply_find_answer_rrset(&qstate->return_msg->qinfo, - qstate->return_msg->rep); -+ /* Double check that the records are indeed A/AAAA. -+ * This should never happen as this function is only executed for A/AAAA -+ * queries but make sure we don't pass anything other than A/AAAA to the -+ * shell. */ -+ qtype = ntohs(rrset_key->rk.type); -+ if(qtype != LDNS_RR_TYPE_AAAA && qtype != LDNS_RR_TYPE_A) { -+ log_err("ipsecmod: Answer is not of A or AAAA type"); -+ return 0; -+ } - rrset_data = (struct packed_rrset_data*)rrset_key->entry.data; -- sldns_str_print(&s, &slen, "\""); -+ /* Copy the A/AAAA record(s) into the buffer. Start and end this section -+ * with a double quote. */ -+ w += sldns_str_print(&s, &slen, "\""); - for(i=0; icount; i++) { - if(i > 0) { - /* Put space into the buffer. */ -- sldns_str_print(&s, &slen, " "); -+ w += sldns_str_print(&s, &slen, " "); - } - /* Ignore the first two bytes, they are the rr_data len. */ -- w = sldns_wire2str_rdata_buf(rrset_data->rr_data[i] + 2, -+ w_temp = sldns_wire2str_rdata_buf(rrset_data->rr_data[i] + 2, - rrset_data->rr_len[i] - 2, s, slen, qstate->qinfo.qtype); -- if(w < 0) { -+ if(w_temp < 0) { - /* Error in printout. */ -- return -1; -- } else if((size_t)w >= slen) { -+ log_err("ipsecmod: Error in printing IP address"); -+ return 0; -+ } else if((size_t)w_temp >= slen) { - s = NULL; /* We do not want str to point outside of buffer. */ - slen = 0; -- return -1; -+ log_err("ipsecmod: shell command too long"); -+ return 0; - } else { -- s += w; -- slen -= w; -+ s += w_temp; -+ slen -= w_temp; -+ w += w_temp; - } - } -- sldns_str_print(&s, &slen, "\""); -+ w += sldns_str_print(&s, &slen, "\""); - /* Put space into the buffer. */ -- sldns_str_print(&s, &slen, " "); -+ w += sldns_str_print(&s, &slen, " "); - /* Copy the IPSECKEY record(s) into the buffer. Start and end this section - * with a double quote. */ -- sldns_str_print(&s, &slen, "\""); -+ w += sldns_str_print(&s, &slen, "\""); - rrset_data = (struct packed_rrset_data*)iq->ipseckey_rrset->entry.data; - for(i=0; icount; i++) { - if(i > 0) { - /* Put space into the buffer. */ -- sldns_str_print(&s, &slen, " "); -+ w += sldns_str_print(&s, &slen, " "); - } - /* Ignore the first two bytes, they are the rr_data len. */ - tempdata = rrset_data->rr_data[i] + 2; - tempdata_len = rrset_data->rr_len[i] - 2; - /* Save the buffer pointers. */ - tempstring = s; tempstring_len = slen; -- w = sldns_wire2str_ipseckey_scan(&tempdata, &tempdata_len, &s, &slen, -- NULL, 0); -+ w_temp = sldns_wire2str_ipseckey_scan(&tempdata, &tempdata_len, &s, -+ &slen, NULL, 0); - /* There was an error when parsing the IPSECKEY; reset the buffer - * pointers to their previous values. */ -- if(w == -1){ -+ if(w_temp == -1) { - s = tempstring; slen = tempstring_len; -+ } else if(w_temp > 0) { -+ if(!ipseckey_has_safe_characters( -+ tempstring, tempstring_len - slen)) { -+ log_err("ipsecmod: ipseckey has unsafe characters"); -+ return 0; -+ } -+ w += w_temp; - } - } -- sldns_str_print(&s, &slen, "\""); -- verbose(VERB_ALGO, "ipsecmod: hook command: '%s'", str); -+ w += sldns_str_print(&s, &slen, "\""); -+ if(w >= (int)sizeof(str)) { -+ log_err("ipsecmod: shell command too long"); -+ return 0; -+ } -+ verbose(VERB_ALGO, "ipsecmod: shell command: '%s'", str); - /* ipsecmod-hook should return 0 on success. */ - if(system(str) != 0) - return 0; diff --git a/SOURCES/unbound-1.7.3-ksk-2010-revoked.patch b/SOURCES/unbound-1.7.3-ksk-2010-revoked.patch deleted file mode 100644 index a01109c..0000000 --- a/SOURCES/unbound-1.7.3-ksk-2010-revoked.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff --git a/smallapp/unbound-anchor.c b/smallapp/unbound-anchor.c -index 2bf5b3ab..a30523c7 100644 ---- a/smallapp/unbound-anchor.c -+++ b/smallapp/unbound-anchor.c -@@ -246,9 +246,7 @@ get_builtin_ds(void) - return - /* The anchors must start on a new line with ". IN DS and end with \n"[;] - * because the makedist script greps on the source here */ --/* anchor 19036 is from 2010 */ - /* anchor 20326 is from 2017 */ --". IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5\n" - ". IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D\n"; - } - diff --git a/SOURCES/unbound-1.7.3-rh1830625.patch b/SOURCES/unbound-1.7.3-rh1830625.patch deleted file mode 100644 index dd36c7e..0000000 --- a/SOURCES/unbound-1.7.3-rh1830625.patch +++ /dev/null @@ -1,203 +0,0 @@ -diff --git a/config.h.in b/config.h.in -index 3b06bfa..2beb538 100644 ---- a/config.h.in -+++ b/config.h.in -@@ -735,6 +735,14 @@ - /* Define to 1 to use ipsecmod support. */ - #undef USE_IPSECMOD - -+/* WARNING! This is only for the libunbound on Linux and does not affect -+ unbound resolving daemon itself. This may severely limit the number of -+ available outgoing ports and thus decrease randomness. Define this only -+ when the target system restricts (e.g. some of SELinux enabled -+ distributions) the use of non-ephemeral ports. Define this to enable use of -+ /proc/sys/net/ipv4/ip_local_port_range as a default outgoing port range. */ -+#undef USE_LINUX_IP_LOCAL_PORT_RANGE -+ - /* Define if you want to use internal select based events */ - #undef USE_MINI_EVENT - -diff --git a/configure b/configure -index 16d50d0..36cf3fa 100755 ---- a/configure -+++ b/configure -@@ -878,6 +878,7 @@ enable_dnscrypt - with_libsodium - enable_cachedb - enable_ipsecmod -+enable_linux_ip_local_port_range - with_libunbound_only - ' - ac_precious_vars='build_alias -@@ -1565,6 +1566,16 @@ Optional Features: - storage - --enable-ipsecmod Enable ipsecmod module that facilitates - opportunistic IPsec -+ --enable-linux-ip-local-port-range -+ WARNING! This is only for the libunbound on Linux -+ and does not affect unbound resolving daemon itself. -+ This may severely limit the number of available -+ outgoing ports and thus decrease randomness. Use -+ this option only when the target system restricts -+ the use of non-ephemeral ports. (e.g. some of -+ SELinux enabled distributions) Enable this option to -+ use /proc/sys/net/ipv4/ip_local_port_range as a -+ default outgoing port range - - Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] -@@ -4147,6 +4158,13 @@ else - else on_mingw="no"; fi - fi - -+# are we on Linux? -+if uname -s 2>&1 | grep -i linux >/dev/null; then on_linux="yes" -+else -+ if echo $host $target | grep linux >/dev/null; then on_linux="yes" -+ else on_linux="no"; fi -+fi -+ - # - # Determine configuration file - # the eval is to evaluate shell expansion twice -@@ -20899,6 +20917,23 @@ $as_echo "#define USE_IPSECMOD 1" >>confdefs.h - ;; - esac - -+if test $on_linux = "yes"; then -+ # Check whether --enable-linux-ip-local-port-range was given. -+if test "${enable_linux_ip_local_port_range+set}" = set; then : -+ enableval=$enable_linux_ip_local_port_range; -+fi -+ -+ case "$enable_linux_ip_local_port_range" in -+ yes) -+ -+$as_echo "#define USE_LINUX_IP_LOCAL_PORT_RANGE 1" >>confdefs.h -+ -+ ;; -+ no|*) -+ ;; -+ esac -+fi -+ - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ${MAKE:-make} supports $< with implicit rule in scope" >&5 - $as_echo_n "checking if ${MAKE:-make} supports $< with implicit rule in scope... " >&6; } - # on openBSD, the implicit rule make $< work. -diff --git a/configure.ac b/configure.ac -index 1bff4ed..525ad62 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -131,6 +131,13 @@ else - else on_mingw="no"; fi - fi - -+# are we on Linux? -+if uname -s 2>&1 | grep -i linux >/dev/null; then on_linux="yes" -+else -+ if echo $host $target | grep linux >/dev/null; then on_linux="yes" -+ else on_linux="no"; fi -+fi -+ - # - # Determine configuration file - # the eval is to evaluate shell expansion twice -@@ -1520,6 +1527,17 @@ case "$enable_ipsecmod" in - ;; - esac - -+if test $on_linux = "yes"; then -+ AC_ARG_ENABLE(linux-ip-local-port-range, AC_HELP_STRING([--enable-linux-ip-local-port-range], [WARNING! This is only for the libunbound on Linux and does not affect unbound resolving daemon itself. This may severely limit the number of available outgoing ports and thus decrease randomness. Use this option only when the target system restricts the use of non-ephemeral ports. (e.g. some of SELinux enabled distributions) Enable this option to use /proc/sys/net/ipv4/ip_local_port_range as a default outgoing port range])) -+ case "$enable_linux_ip_local_port_range" in -+ yes) -+ AC_DEFINE([USE_LINUX_IP_LOCAL_PORT_RANGE], [1], [WARNING! This is only for the libunbound on Linux and does not affect unbound resolving daemon itself. This may severely limit the number of available outgoing ports and thus decrease randomness. Define this only when the target system restricts (e.g. some of SELinux enabled distributions) the use of non-ephemeral ports. Define this to enable use of /proc/sys/net/ipv4/ip_local_port_range as a default outgoing port range.]) -+ ;; -+ no|*) -+ ;; -+ esac -+fi -+ - AC_MSG_CHECKING([if ${MAKE:-make} supports $< with implicit rule in scope]) - # on openBSD, the implicit rule make $< work. - # on Solaris, it does not work ($? is changed sources, $^ lists dependencies). -diff --git a/libunbound/context.c b/libunbound/context.c -index 6ac8086..e1fbc64 100644 ---- a/libunbound/context.c -+++ b/libunbound/context.c -@@ -60,6 +60,7 @@ context_finalize(struct ub_ctx* ctx) - if(ctx->logfile_override) - log_file(ctx->log_out); - else log_init(cfg->logfile, cfg->use_syslog, NULL); -+ cfg_apply_local_port_policy(cfg, 65536); - config_apply(cfg); - if(!modstack_setup(&ctx->mods, cfg->module_conf, ctx->env)) - return UB_INITFAIL; -diff --git a/util/config_file.c b/util/config_file.c -index 68a0a15..eaf1ca3 100644 ---- a/util/config_file.c -+++ b/util/config_file.c -@@ -1474,6 +1474,37 @@ int cfg_condense_ports(struct config_file* cfg, int** avail) - return num; - } - -+void cfg_apply_local_port_policy(struct config_file* cfg, int num) { -+(void)cfg; -+(void)num; -+#ifdef USE_LINUX_IP_LOCAL_PORT_RANGE -+ { -+ int i = 0; -+ FILE* range_fd; -+ if ((range_fd = fopen(LINUX_IP_LOCAL_PORT_RANGE_PATH, "r")) != NULL) { -+ int min_port = 0; -+ int max_port = num - 1; -+ if (fscanf(range_fd, "%d %d", &min_port, &max_port) == 2) { -+ for(i=0; ioutgoing_avail_ports[i] = 0; -+ } -+ for(i=max_port+1; ioutgoing_avail_ports[i] = 0; -+ } -+ } else { -+ log_err("unexpected port range in %s", -+ LINUX_IP_LOCAL_PORT_RANGE_PATH); -+ } -+ fclose(range_fd); -+ } else { -+ log_warn("failed to read from file: %s (%s)", -+ LINUX_IP_LOCAL_PORT_RANGE_PATH, -+ strerror(errno)); -+ } -+ } -+#endif -+} -+ - /** print error with file and line number */ - static void ub_c_error_va_list(const char *fmt, va_list args) - { -diff --git a/util/config_file.h b/util/config_file.h -index 1e7f402..3aa71b7 100644 ---- a/util/config_file.h -+++ b/util/config_file.h -@@ -1009,6 +1009,13 @@ int cfg_mark_ports(const char* str, int allow, int* avail, int num); - */ - int cfg_condense_ports(struct config_file* cfg, int** avail); - -+/** -+ * Apply system specific port range policy. -+ * @param cfg: config file. -+ * @param num: size of the array (65536). -+ */ -+void cfg_apply_local_port_policy(struct config_file* cfg, int num); -+ - /** - * Scan ports available - * @param avail: the array from cfg. -@@ -1138,4 +1145,8 @@ void w_config_adjust_directory(struct config_file* cfg); - /** debug option for unit tests. */ - extern int fake_dsa, fake_sha1; - -+#ifdef USE_LINUX_IP_LOCAL_PORT_RANGE -+#define LINUX_IP_LOCAL_PORT_RANGE_PATH "/proc/sys/net/ipv4/ip_local_port_range" -+#endif -+ - #endif /* UTIL_CONFIG_FILE_H */ diff --git a/SOURCES/unbound-1.7.3-security-hardening.patch b/SOURCES/unbound-1.7.3-security-hardening.patch deleted file mode 100644 index 930bbad..0000000 --- a/SOURCES/unbound-1.7.3-security-hardening.patch +++ /dev/null @@ -1,677 +0,0 @@ -diff --git a/config.h.in b/config.h.in -index 04356f3..3b06bfa 100644 ---- a/config.h.in -+++ b/config.h.in -@@ -666,6 +666,9 @@ - /* Shared data */ - #undef SHARE_DIR - -+/* The size of `size_t', as computed by sizeof. */ -+#undef SIZEOF_SIZE_T -+ - /* The size of `time_t', as computed by sizeof. */ - #undef SIZEOF_TIME_T - -diff --git a/configure.ac b/configure.ac -index c5e0c7b..1bff4ed 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -371,6 +371,7 @@ AC_INCLUDES_DEFAULT - # endif - #endif - ]) -+AC_CHECK_SIZEOF(size_t) - - # add option to disable the evil rpath - ACX_ARG_RPATH -diff --git a/contrib/create_unbound_ad_servers.sh b/contrib/create_unbound_ad_servers.sh -index d31f078..49fdbff 100644 ---- a/contrib/create_unbound_ad_servers.sh -+++ b/contrib/create_unbound_ad_servers.sh -@@ -9,12 +9,13 @@ - # Variables - dst_dir="/etc/opt/csw/unbound" - work_dir="/tmp" --list_addr="http://pgl.yoyo.org/adservers/serverlist.php?hostformat=nohtml&showintro=1&startdate%5Bday%5D=&startdate%5Bmonth%5D=&startdate%5Byear%5D=" -+list_addr="https://pgl.yoyo.org/adservers/serverlist.php?hostformat=nohtml&showintro=1&startdate%5Bday%5D=&startdate%5Bmonth%5D=&startdate%5Byear%5D=" - - # OS commands - CAT=`which cat` - ECHO=`which echo` - WGET=`which wget` -+TR=`which tr` - - # Check Wget installed - if [ ! -f $WGET ]; then -@@ -22,8 +23,10 @@ if [ ! -f $WGET ]; then - exit 1 - fi - -+# remove special characters with tr to protect unbound.conf - $WGET -O $work_dir/yoyo_ad_servers "$list_addr" && \ - $CAT $work_dir/yoyo_ad_servers | \ -+$TR -d '";$\\' | \ - while read line ; \ - do \ - $ECHO "local-zone: \"$line\" redirect" ;\ -@@ -36,4 +39,4 @@ echo "Done." - # the unbound_ad_servers file: - # - # include: $dst_dir/unbound_ad_servers --# -\ No newline at end of file -+# -diff --git a/daemon/daemon.c b/daemon/daemon.c -index 6820e11..1b4f329 100644 ---- a/daemon/daemon.c -+++ b/daemon/daemon.c -@@ -426,9 +426,7 @@ daemon_create_workers(struct daemon* daemon) - int* shufport; - log_assert(daemon && daemon->cfg); - if(!daemon->rand) { -- unsigned int seed = (unsigned int)time(NULL) ^ -- (unsigned int)getpid() ^ 0x438; -- daemon->rand = ub_initstate(seed, NULL); -+ daemon->rand = ub_initstate(NULL); - if(!daemon->rand) - fatal_exit("could not init random generator"); - hash_set_raninit((uint32_t)ub_random(daemon->rand)); -diff --git a/daemon/worker.c b/daemon/worker.c -index 3acecc1..8354010 100644 ---- a/daemon/worker.c -+++ b/daemon/worker.c -@@ -1629,18 +1629,14 @@ worker_create(struct daemon* daemon, int id, int* ports, int n) - return NULL; - } - /* create random state here to avoid locking trouble in RAND_bytes */ -- seed = (unsigned int)time(NULL) ^ (unsigned int)getpid() ^ -- (((unsigned int)worker->thread_num)<<17); -- /* shift thread_num so it does not match out pid bits */ -- if(!(worker->rndstate = ub_initstate(seed, daemon->rand))) { -- seed = 0; -+ if(!(worker->rndstate = ub_initstate(daemon->rand))) { - log_err("could not init random numbers."); - tube_delete(worker->cmd); - free(worker->ports); - free(worker); - return NULL; - } -- seed = 0; -+ explicit_bzero(&seed, sizeof(seed)); - #ifdef USE_DNSTAP - if(daemon->cfg->dnstap) { - log_assert(daemon->dtenv != NULL); -diff --git a/dns64/dns64.c b/dns64/dns64.c -index 7889d72..300202c 100644 ---- a/dns64/dns64.c -+++ b/dns64/dns64.c -@@ -782,6 +782,16 @@ dns64_inform_super(struct module_qstate* qstate, int id, - * Signal that the sub-query is finished, no matter whether we are - * successful or not. This lets the state machine terminate. - */ -+ if(!super->minfo[id]) { -+ super->minfo[id] = (enum dns64_qstate *)regional_alloc(super->region, -+ sizeof(*(super->minfo[id]))); -+ if(!super->minfo[id]) { -+ log_err("out of memory"); -+ super->return_rcode = LDNS_RCODE_SERVFAIL; -+ super->return_msg = NULL; -+ return; -+ } -+ } - super->minfo[id] = (void*)DNS64_SUBQUERY_FINISHED; - - /* If there is no successful answer, we're done. */ -diff --git a/dnscrypt/dnscrypt.c b/dnscrypt/dnscrypt.c -index 3545d3d..7dd2ce5 100644 ---- a/dnscrypt/dnscrypt.c -+++ b/dnscrypt/dnscrypt.c -@@ -732,6 +732,11 @@ dnsc_load_local_data(struct dnsc_env* dnscenv, struct config_file *cfg) - ); - continue; - } -+ if((unsigned)strlen(dnscenv->provider_name) >= (unsigned)0xffff0000) { -+ /* guard against integer overflow in rrlen calculation */ -+ verbose(VERB_OPS, "cert #%" PRIu32 " is too long", serial); -+ continue; -+ } - rrlen = strlen(dnscenv->provider_name) + - strlen(ttl_class_type) + - 4 * sizeof(struct SignedCert) + // worst case scenario -diff --git a/doc/Changelog b/doc/Changelog -index bb74461..4cb080e 100644 ---- a/doc/Changelog -+++ b/doc/Changelog -@@ -1,3 +1,55 @@ -+3 December 2019: Wouter -+ - Fix Assert Causing DoS in synth_cname(), -+ reported by X41 D-Sec. -+ - Fix Assert Causing DoS in dname_pkt_copy(), -+ reported by X41 D-Sec. -+ - Fix OOB Read in sldns_wire2str_dname_scan(), -+ reported by X41 D-Sec. -+ - Fix Out of Bounds Write in sldns_str2wire_str_buf(), -+ reported by X41 D-Sec. -+ - Fix Out of Bounds Write in sldns_b64_pton(), -+ fixed by check in sldns_str2wire_int16_data_buf(), -+ reported by X41 D-Sec. -+ - Fix Insufficient Handling of Compressed Names in dname_pkt_copy(), -+ reported by X41 D-Sec. -+ - Fix Out of Bound Write Compressed Names in rdata_copy(), -+ reported by X41 D-Sec. -+ - Fix Hang in sldns_wire2str_pkt_scan(), -+ reported by X41 D-Sec. -+ -+20 November 2019: Wouter -+ - Fix Out of Bounds Read in rrinternal_get_owner(), -+ reported by X41 D-Sec. -+ - Fix Race Condition in autr_tp_create(), -+ reported by X41 D-Sec. -+ - Fix Shared Memory World Writeable, -+ reported by X41 D-Sec. -+ - Adjust unbound-control to make stats_shm a read only operation. -+ - Fix Weak Entropy Used For Nettle, -+ reported by X41 D-Sec. -+ - Fix Randomness Error not Handled Properly, -+ reported by X41 D-Sec. -+ - Fix Out-of-Bounds Read in dname_valid(), -+ reported by X41 D-Sec. -+ - Fix Config Injection in create_unbound_ad_servers.sh, -+ reported by X41 D-Sec. -+ -+19 November 2019: Wouter -+ - Fix Integer Overflow in Regional Allocator, -+ reported by X41 D-Sec. -+ - Fix Unchecked NULL Pointer in dns64_inform_super() -+ and ipsecmod_new(), reported by X41 D-Sec. -+ - Fix Out-of-bounds Read in rr_comment_dnskey(), -+ reported by X41 D-Sec. -+ - Fix Integer Overflows in Size Calculations, -+ reported by X41 D-Sec. -+ - Fix Integer Overflow to Buffer Overflow in -+ sldns_str2wire_dname_buf_origin(), reported by X41 D-Sec. -+ - Fix Out of Bounds Read in sldns_str2wire_dname(), -+ reported by X41 D-Sec. -+ - Fix Out of Bounds Write in sldns_bget_token_par(), -+ reported by X41 D-Sec. -+ - 30 November 2018: Wouter - - log-tag-queryreply: yes in unbound.conf tags the log-queries and - log-replies in the log file for easier log filter maintenance. -diff --git a/ipsecmod/ipsecmod.c b/ipsecmod/ipsecmod.c -index 3572f12..1422a62 100644 ---- a/ipsecmod/ipsecmod.c -+++ b/ipsecmod/ipsecmod.c -@@ -103,11 +103,11 @@ ipsecmod_new(struct module_qstate* qstate, int id) - { - struct ipsecmod_qstate* iq = (struct ipsecmod_qstate*)regional_alloc( - qstate->region, sizeof(struct ipsecmod_qstate)); -- memset(iq, 0, sizeof(*iq)); - qstate->minfo[id] = iq; - if(!iq) - return 0; - /* Initialise it. */ -+ memset(iq, 0, sizeof(*iq)); - iq->enabled = qstate->env->cfg->ipsecmod_enabled; - iq->is_whitelisted = ipsecmod_domain_is_whitelisted( - (struct ipsecmod_env*)qstate->env->modinfo[id], qstate->qinfo.qname, -diff --git a/iterator/iter_scrub.c b/iterator/iter_scrub.c -index 8230d17..942c3d5 100644 ---- a/iterator/iter_scrub.c -+++ b/iterator/iter_scrub.c -@@ -231,6 +231,10 @@ synth_cname(uint8_t* qname, size_t qnamelen, struct rrset_parse* dname_rrset, - size_t dtarglen; - if(!parse_get_cname_target(dname_rrset, &dtarg, &dtarglen, pkt)) - return 0; -+ if(qnamelen <= dname_rrset->dname_len) -+ return 0; -+ if(qnamelen == 0) -+ return 0; - log_assert(qnamelen > dname_rrset->dname_len); - /* DNAME from com. to net. with qname example.com. -> example.net. */ - /* so: \3com\0 to \3net\0 and qname \7example\3com\0 */ -diff --git a/libunbound/libunbound.c b/libunbound/libunbound.c -index 275e8d2..a8979c2 100644 ---- a/libunbound/libunbound.c -+++ b/libunbound/libunbound.c -@@ -83,7 +83,6 @@ - static struct ub_ctx* ub_ctx_create_nopipe(void) - { - struct ub_ctx* ctx; -- unsigned int seed; - #ifdef USE_WINSOCK - int r; - WSADATA wsa_data; -@@ -107,15 +106,12 @@ static struct ub_ctx* ub_ctx_create_nopipe(void) - return NULL; - } - alloc_init(&ctx->superalloc, NULL, 0); -- seed = (unsigned int)time(NULL) ^ (unsigned int)getpid(); -- if(!(ctx->seed_rnd = ub_initstate(seed, NULL))) { -- seed = 0; -+ if(!(ctx->seed_rnd = ub_initstate(NULL))) { - ub_randfree(ctx->seed_rnd); - free(ctx); - errno = ENOMEM; - return NULL; - } -- seed = 0; - lock_basic_init(&ctx->qqpipe_lock); - lock_basic_init(&ctx->rrpipe_lock); - lock_basic_init(&ctx->cfglock); -diff --git a/libunbound/libworker.c b/libunbound/libworker.c -index 3dcaa78..07a08c6 100644 ---- a/libunbound/libworker.c -+++ b/libunbound/libworker.c -@@ -122,7 +122,6 @@ libworker_delete_event(struct libworker* w) - static struct libworker* - libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb) - { -- unsigned int seed; - struct libworker* w = (struct libworker*)calloc(1, sizeof(*w)); - struct config_file* cfg = ctx->env->cfg; - int* ports; -@@ -177,17 +176,13 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb) - } - w->env->worker = (struct worker*)w; - w->env->probe_timer = NULL; -- seed = (unsigned int)time(NULL) ^ (unsigned int)getpid() ^ -- (((unsigned int)w->thread_num)<<17); -- seed ^= (unsigned int)w->env->alloc->next_id; - if(!w->is_bg || w->is_bg_thread) { - lock_basic_lock(&ctx->cfglock); - } -- if(!(w->env->rnd = ub_initstate(seed, ctx->seed_rnd))) { -+ if(!(w->env->rnd = ub_initstate(ctx->seed_rnd))) { - if(!w->is_bg || w->is_bg_thread) { - lock_basic_unlock(&ctx->cfglock); - } -- seed = 0; - libworker_delete(w); - return NULL; - } -@@ -207,7 +202,6 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb) - hash_set_raninit((uint32_t)ub_random(w->env->rnd)); - } - } -- seed = 0; - - if(eb) - w->base = comm_base_create_event(eb); -diff --git a/respip/respip.c b/respip/respip.c -index 2e9313f..7d2a588 100644 ---- a/respip/respip.c -+++ b/respip/respip.c -@@ -475,10 +475,16 @@ copy_rrset(const struct ub_packed_rrset_key* key, struct regional* region) - if(!ck->rk.dname) - return NULL; - -+ if((unsigned)data->count >= 0xffff00U) -+ return NULL; /* guard against integer overflow in dsize */ - dsize = sizeof(struct packed_rrset_data) + data->count * - (sizeof(size_t)+sizeof(uint8_t*)+sizeof(time_t)); -- for(i=0; icount; i++) -+ for(i=0; icount; i++) { -+ if((unsigned)dsize >= 0x0fffffffU || -+ (unsigned)data->rr_len[i] >= 0x0fffffffU) -+ return NULL; /* guard against integer overflow */ - dsize += data->rr_len[i]; -+ } - d = regional_alloc(region, dsize); - if(!d) - return NULL; -diff --git a/sldns/parse.c b/sldns/parse.c -index b62c405..b30264e 100644 ---- a/sldns/parse.c -+++ b/sldns/parse.c -@@ -325,8 +325,14 @@ sldns_bget_token_par(sldns_buffer *b, char *token, const char *delim, - if (c == '\n' && p != 0) { - /* in parentheses */ - /* do not write ' ' if we want to skip spaces */ -- if(!(skipw && (strchr(skipw, c)||strchr(skipw, ' ')))) -+ if(!(skipw && (strchr(skipw, c)||strchr(skipw, ' ')))) { -+ /* check for space for the space character */ -+ if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) { -+ *t = '\0'; -+ return -1; -+ } - *t++ = ' '; -+ } - lc = c; - continue; - } -diff --git a/sldns/str2wire.c b/sldns/str2wire.c -index 1a51bb6..414b7b8 100644 ---- a/sldns/str2wire.c -+++ b/sldns/str2wire.c -@@ -150,6 +150,10 @@ int sldns_str2wire_dname_buf_origin(const char* str, uint8_t* buf, size_t* len, - if(s) return s; - - if(rel && origin && dlen > 0) { -+ if((unsigned)dlen >= 0x00ffffffU || -+ (unsigned)origin_len >= 0x00ffffffU) -+ /* guard against integer overflow in addition */ -+ return RET_ERR(LDNS_WIREPARSE_ERR_GENERAL, *len); - if(dlen + origin_len - 1 > LDNS_MAX_DOMAINLEN) - return RET_ERR(LDNS_WIREPARSE_ERR_DOMAINNAME_OVERFLOW, - LDNS_MAX_DOMAINLEN); -@@ -168,7 +172,9 @@ uint8_t* sldns_str2wire_dname(const char* str, size_t* len) - uint8_t dname[LDNS_MAX_DOMAINLEN+1]; - *len = sizeof(dname); - if(sldns_str2wire_dname_buf(str, dname, len) == 0) { -- uint8_t* r = (uint8_t*)malloc(*len); -+ uint8_t* r; -+ if(*len > sizeof(dname)) return NULL; -+ r = (uint8_t*)malloc(*len); - if(r) return memcpy(r, dname, *len); - } - *len = 0; -@@ -187,6 +193,9 @@ rrinternal_get_owner(sldns_buffer* strbuf, uint8_t* rr, size_t* len, - sldns_buffer_position(strbuf)); - } - -+ if(token_len < 2) /* make sure there is space to read "@" or "" */ -+ return RET_ERR(LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL, -+ sldns_buffer_position(strbuf)); - if(strcmp(token, "@") == 0) { - uint8_t* tocopy; - if (origin) { -@@ -1094,7 +1103,7 @@ int sldns_str2wire_str_buf(const char* str, uint8_t* rd, size_t* len) - while(sldns_parse_char(&ch, &s)) { - if(sl >= 255) - return RET_ERR(LDNS_WIREPARSE_ERR_INVALID_STR, s-str); -- if(*len < sl+1) -+ if(*len < sl+2) - return RET_ERR(LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL, - s-str); - rd[++sl] = ch; -@@ -2095,6 +2104,8 @@ int sldns_str2wire_int16_data_buf(const char* str, uint8_t* rd, size_t* len) - char* s; - int n; - n = strtol(str, &s, 10); -+ if(n < 0) /* negative number not allowed */ -+ return LDNS_WIREPARSE_ERR_SYNTAX; - if(*len < ((size_t)n)+2) - return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL; - if(n > 65535) -diff --git a/sldns/wire2str.c b/sldns/wire2str.c -index 832239f..a95c9b3 100644 ---- a/sldns/wire2str.c -+++ b/sldns/wire2str.c -@@ -585,6 +585,7 @@ static int rr_comment_dnskey(char** s, size_t* slen, uint8_t* rr, - if(rrlen < dname_off + 10) return 0; - rdlen = sldns_read_uint16(rr+dname_off+8); - if(rrlen < dname_off + 10 + rdlen) return 0; -+ if(rdlen < 2) return 0; - rdata = rr + dname_off + 10; - flags = (int)sldns_read_uint16(rdata); - w += sldns_str_print(s, slen, " ;{"); -@@ -781,7 +782,7 @@ int sldns_wire2str_dname_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen, - /* spool labels onto the string, use compression if its there */ - uint8_t* pos = *d; - unsigned i, counter=0; -- const unsigned maxcompr = 1000; /* loop detection, max compr ptrs */ -+ const unsigned maxcompr = 256; /* loop detection, max compr ptrs */ - int in_buf = 1; - if(*dlen == 0) return sldns_str_print(s, slen, "ErrorMissingDname"); - if(*pos == 0) { -@@ -789,7 +790,7 @@ int sldns_wire2str_dname_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen, - (*dlen)--; - return sldns_str_print(s, slen, "."); - } -- while(*pos) { -+ while((!pkt || pos < pkt+pktlen) && *pos) { - /* read label length */ - uint8_t labellen = *pos++; - if(in_buf) { (*d)++; (*dlen)--; } -diff --git a/smallapp/unbound-control.c b/smallapp/unbound-control.c -index d165417..2884309 100644 ---- a/smallapp/unbound-control.c -+++ b/smallapp/unbound-control.c -@@ -407,19 +407,19 @@ static void print_stats_shm(const char* cfgfile) - if(!config_read(cfg, cfgfile, NULL)) - fatal_exit("could not read config file"); - /* get shm segments */ -- id_ctl = shmget(cfg->shm_key, sizeof(int), SHM_R|SHM_W); -+ id_ctl = shmget(cfg->shm_key, sizeof(int), SHM_R); - if(id_ctl == -1) { - fatal_exit("shmget(%d): %s", cfg->shm_key, strerror(errno)); - } -- id_arr = shmget(cfg->shm_key+1, sizeof(int), SHM_R|SHM_W); -+ id_arr = shmget(cfg->shm_key+1, sizeof(int), SHM_R); - if(id_arr == -1) { - fatal_exit("shmget(%d): %s", cfg->shm_key+1, strerror(errno)); - } -- shm_stat = (struct ub_shm_stat_info*)shmat(id_ctl, NULL, 0); -+ shm_stat = (struct ub_shm_stat_info*)shmat(id_ctl, NULL, SHM_RDONLY); - if(shm_stat == (void*)-1) { - fatal_exit("shmat(%d): %s", id_ctl, strerror(errno)); - } -- stats = (struct ub_stats_info*)shmat(id_arr, NULL, 0); -+ stats = (struct ub_stats_info*)shmat(id_arr, NULL, SHM_RDONLY); - if(stats == (void*)-1) { - fatal_exit("shmat(%d): %s", id_arr, strerror(errno)); - } -diff --git a/testcode/unitmain.c b/testcode/unitmain.c -index fecde80..96a6654 100644 ---- a/testcode/unitmain.c -+++ b/testcode/unitmain.c -@@ -537,10 +537,8 @@ rnd_test(void) - struct ub_randstate* r; - int num = 1000, i; - long int a[1000]; -- unsigned int seed = (unsigned)time(NULL); - unit_show_feature("ub_random"); -- printf("ub_random seed is %u\n", seed); -- unit_assert( (r = ub_initstate(seed, NULL)) ); -+ unit_assert( (r = ub_initstate(NULL)) ); - for(i=0; i= 0); -diff --git a/util/data/dname.c b/util/data/dname.c -index b744f06..923be02 100644 ---- a/util/data/dname.c -+++ b/util/data/dname.c -@@ -75,6 +75,8 @@ dname_valid(uint8_t* dname, size_t maxlen) - { - size_t len = 0; - size_t labellen; -+ if(maxlen == 0) -+ return 0; /* too short, shortest is '0' root label */ - labellen = *dname++; - while(labellen) { - if(labellen&0xc0) -@@ -345,11 +347,17 @@ dname_pkt_hash(sldns_buffer* pkt, uint8_t* dname, hashvalue_type h) - void dname_pkt_copy(sldns_buffer* pkt, uint8_t* to, uint8_t* dname) - { - /* copy over the dname and decompress it at the same time */ -+ size_t comprcount = 0; - size_t len = 0; - uint8_t lablen; - lablen = *dname++; - while(lablen) { - if(LABEL_IS_PTR(lablen)) { -+ if(comprcount++ > MAX_COMPRESS_PTRS) { -+ /* too many compression pointers */ -+ *to = 0; /* end the result prematurely */ -+ return; -+ } - /* follow pointer */ - if((size_t)PTR_OFFSET(lablen, *dname) - >= sldns_buffer_limit(pkt)) -@@ -358,6 +366,10 @@ void dname_pkt_copy(sldns_buffer* pkt, uint8_t* to, uint8_t* dname) - lablen = *dname++; - continue; - } -+ if(lablen > LDNS_MAX_LABELLEN) { -+ *to = 0; /* end the result prematurely */ -+ return; -+ } - log_assert(lablen <= LDNS_MAX_LABELLEN); - len += (size_t)lablen+1; - if(len >= LDNS_MAX_DOMAINLEN) { -diff --git a/util/data/msgreply.c b/util/data/msgreply.c -index df2131c..dbae34d 100644 ---- a/util/data/msgreply.c -+++ b/util/data/msgreply.c -@@ -238,10 +238,10 @@ rdata_copy(sldns_buffer* pkt, struct packed_rrset_data* data, uint8_t* to, - break; - } - if(len) { -+ log_assert(len <= pkt_len); - memmove(to, sldns_buffer_current(pkt), len); - to += len; - sldns_buffer_skip(pkt, (ssize_t)len); -- log_assert(len <= pkt_len); - pkt_len -= len; - } - rdf++; -diff --git a/util/random.c b/util/random.c -index 8332960..9380502 100644 ---- a/util/random.c -+++ b/util/random.c -@@ -86,8 +86,7 @@ ub_systemseed(unsigned int ATTR_UNUSED(seed)) - } - - struct ub_randstate* --ub_initstate(unsigned int ATTR_UNUSED(seed), -- struct ub_randstate* ATTR_UNUSED(from)) -+ub_initstate(struct ub_randstate* ATTR_UNUSED(from)) - { - struct ub_randstate* s = (struct ub_randstate*)malloc(1); - if(!s) { -@@ -123,8 +122,8 @@ void ub_systemseed(unsigned int ATTR_UNUSED(seed)) - { - } - --struct ub_randstate* ub_initstate(unsigned int ATTR_UNUSED(seed), -- struct ub_randstate* ATTR_UNUSED(from)) -+struct ub_randstate* -+ub_initstate(struct ub_randstate* ATTR_UNUSED(from)) - { - struct ub_randstate* s = (struct ub_randstate*)calloc(1, sizeof(*s)); - if(!s) { -@@ -140,7 +139,9 @@ long int ub_random(struct ub_randstate* ATTR_UNUSED(state)) - /* random 31 bit value. */ - SECStatus s = PK11_GenerateRandom((unsigned char*)&x, (int)sizeof(x)); - if(s != SECSuccess) { -- log_err("PK11_GenerateRandom error: %s", -+ /* unbound needs secure randomness for randomized -+ * ID bits and port numbers in packets to upstream servers */ -+ fatal_exit("PK11_GenerateRandom error: %s", - PORT_ErrorToString(PORT_GetError())); - } - return x & MAX_VALUE; -@@ -166,8 +167,7 @@ void ub_systemseed(unsigned int ATTR_UNUSED(seed)) - log_err("Re-seeding not supported, generator untouched"); - } - --struct ub_randstate* ub_initstate(unsigned int seed, -- struct ub_randstate* ATTR_UNUSED(from)) -+struct ub_randstate* ub_initstate(struct ub_randstate* ATTR_UNUSED(from)) - { - struct ub_randstate* s = (struct ub_randstate*)calloc(1, sizeof(*s)); - uint8_t buf[YARROW256_SEED_FILE_SIZE]; -@@ -183,15 +183,10 @@ struct ub_randstate* ub_initstate(unsigned int seed, - yarrow256_seed(&s->ctx, YARROW256_SEED_FILE_SIZE, buf); - s->seeded = yarrow256_is_seeded(&s->ctx); - } else { -- /* Stretch the uint32 input seed and feed it to Yarrow */ -- uint32_t v = seed; -- size_t i; -- for(i=0; i < (YARROW256_SEED_FILE_SIZE/sizeof(seed)); i++) { -- memmove(buf+i*sizeof(seed), &v, sizeof(seed)); -- v = v*seed + (uint32_t)i; -- } -- yarrow256_seed(&s->ctx, YARROW256_SEED_FILE_SIZE, buf); -- s->seeded = yarrow256_is_seeded(&s->ctx); -+ log_err("nettle random(yarrow) cannot initialize, " -+ "getentropy failed: %s", strerror(errno)); -+ free(s); -+ return NULL; - } - - return s; -diff --git a/util/random.h b/util/random.h -index a05a994..e75157d 100644 ---- a/util/random.h -+++ b/util/random.h -@@ -57,15 +57,12 @@ void ub_systemseed(unsigned int seed); - - /** - * Initialize a random generator state for use -- * @param seed: seed value to create state contents. -- * (ignored for arc4random). - * @param from: if not NULL, the seed is taken from this random structure. - * can be used to seed random states via a parent-random-state that - * is itself seeded with entropy. - * @return new state or NULL alloc failure. - */ --struct ub_randstate* ub_initstate(unsigned int seed, -- struct ub_randstate* from); -+struct ub_randstate* ub_initstate(struct ub_randstate* from); - - /** - * Generate next random number from the state passed along. -diff --git a/util/regional.c b/util/regional.c -index 899a54e..5be09eb 100644 ---- a/util/regional.c -+++ b/util/regional.c -@@ -120,8 +120,18 @@ regional_destroy(struct regional *r) - void * - regional_alloc(struct regional *r, size_t size) - { -- size_t a = ALIGN_UP(size, ALIGNMENT); -+ size_t a; - void *s; -+ if( -+#if SIZEOF_SIZE_T == 8 -+ (unsigned long long)size >= 0xffffffffffffff00ULL -+#else -+ (unsigned)size >= (unsigned)0xffffff00UL -+#endif -+ ) -+ return NULL; /* protect against integer overflow in -+ malloc and ALIGN_UP */ -+ a = ALIGN_UP(size, ALIGNMENT); - /* large objects */ - if(a > REGIONAL_LARGE_OBJECT_SIZE) { - s = malloc(ALIGNMENT + size); -diff --git a/util/shm_side/shm_main.c b/util/shm_side/shm_main.c -index a783c09..69bee4d 100644 ---- a/util/shm_side/shm_main.c -+++ b/util/shm_side/shm_main.c -@@ -121,7 +121,7 @@ int shm_main_init(struct daemon* daemon) - shmctl(daemon->shm_info->id_arr, IPC_RMID, NULL); - - /* SHM: Create the segment */ -- daemon->shm_info->id_ctl = shmget(daemon->shm_info->key, sizeof(struct ub_shm_stat_info), IPC_CREAT | 0666); -+ daemon->shm_info->id_ctl = shmget(daemon->shm_info->key, sizeof(struct ub_shm_stat_info), IPC_CREAT | 0644); - - if (daemon->shm_info->id_ctl < 0) - { -@@ -134,7 +134,7 @@ int shm_main_init(struct daemon* daemon) - return 0; - } - -- daemon->shm_info->id_arr = shmget(daemon->shm_info->key + 1, shm_size, IPC_CREAT | 0666); -+ daemon->shm_info->id_arr = shmget(daemon->shm_info->key + 1, shm_size, IPC_CREAT | 0644); - - if (daemon->shm_info->id_arr < 0) - { -diff --git a/validator/autotrust.c b/validator/autotrust.c -index 7bc5577..e19bd7b 100644 ---- a/validator/autotrust.c -+++ b/validator/autotrust.c -@@ -370,10 +370,10 @@ autr_tp_create(struct val_anchors* anchors, uint8_t* own, size_t own_len, - free(tp); - return NULL; - } -- lock_basic_unlock(&anchors->lock); - lock_basic_init(&tp->lock); - lock_protect(&tp->lock, tp, sizeof(*tp)); - lock_protect(&tp->lock, tp->autr, sizeof(*tp->autr)); -+ lock_basic_unlock(&anchors->lock); - return tp; - } - diff --git a/SOURCES/unbound-1.7.3-symlink-traversal.patch b/SOURCES/unbound-1.7.3-symlink-traversal.patch deleted file mode 100644 index 0c06794..0000000 --- a/SOURCES/unbound-1.7.3-symlink-traversal.patch +++ /dev/null @@ -1,43 +0,0 @@ -diff --git a/unbound-1.7.3/daemon/unbound.c b/unbound-1.7.3/daemon/unbound.c -index 1383110..66ed61d 100644 ---- a/daemon/unbound.c -+++ b/daemon/unbound.c -@@ -327,18 +327,32 @@ readpid (const char* file) - static void - writepid (const char* pidfile, pid_t pid) - { -- FILE* f; -+ int fd; -+ char pidbuf[32]; -+ size_t count = 0; -+ snprintf(pidbuf, sizeof(pidbuf), "%lu\n", (unsigned long)pid); - -- if ((f = fopen(pidfile, "w")) == NULL ) { -+ if((fd = open(pidfile, O_WRONLY | O_CREAT | O_TRUNC -+#ifdef O_NOFOLLOW -+ | O_NOFOLLOW -+#endif -+ , 0644)) == -1) { - log_err("cannot open pidfile %s: %s", - pidfile, strerror(errno)); - return; - } -- if(fprintf(f, "%lu\n", (unsigned long)pid) < 0) { -- log_err("cannot write to pidfile %s: %s", -- pidfile, strerror(errno)); -+ while(count < strlen(pidbuf)) { -+ ssize_t r = write(fd, pidbuf+count, strlen(pidbuf)-count); -+ if(r == -1) { -+ if(errno == EAGAIN || errno == EINTR) -+ continue; -+ log_err("cannot write to pidfile %s: %s", -+ pidfile, strerror(errno)); -+ break; -+ } -+ count += r; - } -- fclose(f); -+ close(fd); - } - - /** diff --git a/SOURCES/unbound-1.7.3-use-basic-lock.patch b/SOURCES/unbound-1.7.3-use-basic-lock.patch deleted file mode 100644 index d933bec..0000000 --- a/SOURCES/unbound-1.7.3-use-basic-lock.patch +++ /dev/null @@ -1,109 +0,0 @@ -diff --git a/util/log.c b/util/log.c -index 75a58f9..43dd572 100644 ---- a/util/log.c -+++ b/util/log.c -@@ -70,7 +70,7 @@ static int key_created = 0; - static ub_thread_key_type logkey; - #ifndef THREADS_DISABLED - /** pthread mutex to protect FILE* */ --static lock_quick_type log_lock; -+static lock_basic_type log_lock; - #endif - /** the identity of this executable/process */ - static const char* ident="unbound"; -@@ -90,18 +90,18 @@ log_init(const char* filename, int use_syslog, const char* chrootdir) - if(!key_created) { - key_created = 1; - ub_thread_key_create(&logkey, NULL); -- lock_quick_init(&log_lock); -+ lock_basic_init(&log_lock); - } -- lock_quick_lock(&log_lock); -+ lock_basic_lock(&log_lock); - if(logfile - #if defined(HAVE_SYSLOG_H) || defined(UB_ON_WINDOWS) - || logging_to_syslog - #endif - ) { -- lock_quick_unlock(&log_lock); /* verbose() needs the lock */ -+ lock_basic_unlock(&log_lock); /* verbose() needs the lock */ - verbose(VERB_QUERY, "switching log to %s", - use_syslog?"syslog":(filename&&filename[0]?filename:"stderr")); -- lock_quick_lock(&log_lock); -+ lock_basic_lock(&log_lock); - } - if(logfile && logfile != stderr) { - FILE* cl = logfile; -@@ -119,7 +119,7 @@ log_init(const char* filename, int use_syslog, const char* chrootdir) - * chroot and no longer be able to access dev/log and so on */ - openlog(ident, LOG_NDELAY, LOG_DAEMON); - logging_to_syslog = 1; -- lock_quick_unlock(&log_lock); -+ lock_basic_unlock(&log_lock); - return; - } - #elif defined(UB_ON_WINDOWS) -@@ -128,13 +128,13 @@ log_init(const char* filename, int use_syslog, const char* chrootdir) - } - if(use_syslog) { - logging_to_syslog = 1; -- lock_quick_unlock(&log_lock); -+ lock_basic_unlock(&log_lock); - return; - } - #endif /* HAVE_SYSLOG_H */ - if(!filename || !filename[0]) { - logfile = stderr; -- lock_quick_unlock(&log_lock); -+ lock_basic_unlock(&log_lock); - return; - } - /* open the file for logging */ -@@ -143,7 +143,7 @@ log_init(const char* filename, int use_syslog, const char* chrootdir) - filename += strlen(chrootdir); - f = fopen(filename, "a"); - if(!f) { -- lock_quick_unlock(&log_lock); -+ lock_basic_unlock(&log_lock); - log_err("Could not open logfile %s: %s", filename, - strerror(errno)); - return; -@@ -153,14 +153,14 @@ log_init(const char* filename, int use_syslog, const char* chrootdir) - setvbuf(f, NULL, (int)_IOLBF, 0); - #endif - logfile = f; -- lock_quick_unlock(&log_lock); -+ lock_basic_unlock(&log_lock); - } - - void log_file(FILE *f) - { -- lock_quick_lock(&log_lock); -+ lock_basic_lock(&log_lock); - logfile = f; -- lock_quick_unlock(&log_lock); -+ lock_basic_unlock(&log_lock); - } - - void log_thread_set(int* num) -@@ -250,9 +250,9 @@ log_vmsg(int pri, const char* type, - return; - } - #endif /* HAVE_SYSLOG_H */ -- lock_quick_lock(&log_lock); -+ lock_basic_lock(&log_lock); - if(!logfile) { -- lock_quick_unlock(&log_lock); -+ lock_basic_unlock(&log_lock); - return; - } - if(log_now) -@@ -279,7 +279,7 @@ log_vmsg(int pri, const char* type, - /* line buffering does not work on windows */ - fflush(logfile); - #endif -- lock_quick_unlock(&log_lock); -+ lock_basic_unlock(&log_lock); - } - - /** diff --git a/SOURCES/unbound-keygen.service b/SOURCES/unbound-keygen.service index ccb2376..b169002 100644 --- a/SOURCES/unbound-keygen.service +++ b/SOURCES/unbound-keygen.service @@ -2,14 +2,17 @@ Description=Unbound Control Key And Certificate Generator After=syslog.target Before=unbound.service -ConditionPathExists=!/etc/unbound/unbound_control.key +ConditionPathExists=|!/etc/unbound/unbound_control.pem +ConditionPathExists=|!/etc/unbound/unbound_control.key +ConditionPathExists=|!/etc/unbound/unbound_server.pem +ConditionPathExists=|!/etc/unbound/unbound_server.key +PartOf=unbound.service [Service] Type=oneshot Group=unbound ExecStart=/usr/sbin/unbound-control-setup -d /etc/unbound/ ExecStart=/sbin/restorecon /etc/unbound/* -RemainAfterExit=yes [Install] WantedBy=multi-user.target diff --git a/SOURCES/unbound.conf b/SOURCES/unbound.conf index 5efe0d0..977d39f 100644 --- a/SOURCES/unbound.conf +++ b/SOURCES/unbound.conf @@ -5,9 +5,13 @@ # # this is a comment. -#Use this to include other text into the file. +# Use this anywhere in the file to include other text into this file. #include: "otherfile.conf" +# Use this anywhere in the file to include other text, that explicitly starts a +# clause, into this file. Text after this directive needs to start a clause. +#include-toplevel: "otherfile.conf" + # The server clause sets the main parameters. server: # whitespace is not necessary, but looks cleaner. @@ -86,25 +90,29 @@ server: # Set this to yes to prefer ipv6 upstream servers over ipv4. # prefer-ip6: no + # Prefer ipv4 upstream servers, even if ipv6 is available. + # prefer-ip4: no + # number of ports to allocate per thread, determines the size of the # port range that can be open simultaneously. About double the # num-queries-per-thread, or, use as many as the OS will allow you. # outgoing-range: 4096 - # permit unbound to use this port number or port range for + # permit Unbound to use this port number or port range for # making outgoing queries, using an outgoing interface. # Only ephemeral ports are allowed by SElinux outgoing-port-permit: 32768-60999 - # deny unbound the use this of port number or port range for + # deny Unbound the use this of port number or port range for # making outgoing queries, using an outgoing interface. - # Use this to make sure unbound does not grab a UDP port that some + # Use this to make sure Unbound does not grab a UDP port that some # other server on this computer needs. The default is to avoid # IANA-assigned port numbers. # If multiple outgoing-port-permit and outgoing-port-avoid options # are present, they are processed in order. # Our SElinux policy does not allow non-ephemeral ports to be used outgoing-port-avoid: 0-32767 + outgoing-port-avoid: 61000-65535 # number of outgoing simultaneous tcp buffers to hold per thread. # outgoing-num-tcp: 10 @@ -121,6 +129,7 @@ server: # so-sndbuf: 0 # use SO_REUSEPORT to distribute queries over threads. + # at extreme load it could be better to turn it off to distribute even. so-reuseport: yes # use IP_TRANSPARENT so the interface: addresses can be non-local @@ -133,9 +142,14 @@ server: # Linux only. On Linux you also have ip-transparent that is similar. # ip-freebind: no + # the value of the Differentiated Services Codepoint (DSCP) + # in the differentiated services field (DS) of the outgoing + # IP packets + # ip-dscp: 0 + # EDNS reassembly buffer to advertise to UDP peers (the actual buffer - # is set with msg-buffer-size). 1472 can solve fragmentation (timeouts). - # edns-buffer-size: 4096 + # is set with msg-buffer-size). 1472 can solve fragmentation (timeouts) + # edns-buffer-size: 1232 # Maximum UDP response size (not applied to TCP response). # Suggested values are 512 to 4096. Default is 4096. 65536 disables it. @@ -143,6 +157,9 @@ server: # Helps mitigating DDOS max-udp-size: 3072 + # max memory to use for stream(tcp and tls) waiting result buffers. + # stream-wait-size: 4m + # buffer size for handling DNS data. No messages larger than this # size can be sent or received, by UDP or TCP. In bytes. # msg-buffer-size: 65552 @@ -165,6 +182,13 @@ server: # msec to wait before close of port on timeout UDP. 0 disables. # delay-close: 0 + # perform connect for UDP sockets to mitigate ICMP side channel. + # udp-connect: yes + + # msec for waiting for an unknown server to reply. Increase if you + # are behind a slow satellite link, to eg. 1128. + # unknown-server-time-limit: 376 + # the amount of memory to use for the RRset cache. # plain value in bytes or you can append k, m or G. default is "4Mb". # rrset-cache-size: 4m @@ -192,6 +216,9 @@ server: # minimum wait time for responses, increase if uplink is long. In msec. # infra-cache-min-rtt: 50 + # enable to make server probe down hosts more frequently. + # infra-keep-probing: no + # the number of slabs to use for the Infrastructure cache. # the number of slabs must be a power of 2. # more slabs reduce lock contention, but fragment memory usage. @@ -211,7 +238,7 @@ server: # do-ip6: yes # Enable UDP, "yes" or "no". - # NOTE: if setting up an unbound on tls443 for public use, you might want to + # NOTE: if setting up an Unbound on tls443 for public use, you might want to # disable UDP to avoid being used in DNS amplification attacks. # do-udp: yes @@ -234,12 +261,21 @@ server: # Default is 0, system default MSS. # outgoing-tcp-mss: 0 + # Idle TCP timeout, connection closed in milliseconds + # tcp-idle-timeout: 30000 + + # Enable EDNS TCP keepalive option. + edns-tcp-keepalive: yes + + # Timeout for EDNS TCP keepalive, in msec. + # edns-tcp-keepalive-timeout: 120000 + # Fedora note: do not activate this - can cause a crash # Use systemd socket activation for UDP, TCP, and control sockets. # use-systemd: no # Detach from the terminal, run in background, "yes" or "no". - # Set the value to "no" when unbound runs as systemd service. + # Set the value to "no" when Unbound runs as systemd service. # do-daemonize: yes # control which clients are allowed to make (recursive) queries @@ -292,7 +328,7 @@ server: # The pid file can be absolute and outside of the chroot, it is # written just prior to performing the chroot and dropping permissions. # - # Additionally, unbound may need to access /dev/random (for entropy). + # Additionally, Unbound may need to access /dev/urandom (for entropy). # How to do this is specific to your OS. # # If you give "" no chroot is performed. The path must not end in a /. @@ -333,8 +369,19 @@ server: # timetoresolve, fromcache and responsesize. # log-replies: no + # log with tag 'query' and 'reply' instead of 'info' for + # filtering log-queries and log-replies from the log. + # log-tag-queryreply: no + + # log the local-zone actions, like local-zone type inform is enabled + # also for the other local zone types. + # log-local-actions: no + + # print log lines that say why queries return SERVFAIL to clients. + # log-servfail: no + # the pid file. Can be an absolute path outside of chroot/work dir. - pidfile: "/run/unbound/unbound.pid" + pidfile: "/var/run/unbound/unbound.pid" # file to read root hints from. # get one from https://www.internic.net/domain/named.cache @@ -346,15 +393,28 @@ server: # enable to not answer version.server and version.bind queries. # hide-version: no + # enable to not set the User-Agent HTTP header. + # hide-http-user-agent: no + # enable to not answer trustanchor.unbound queries. # hide-trustanchor: no + # enable to not set the User-Agent HTTP header. + # hide-http-user-agent: no + # the identity to report. Leave "" or default to return hostname. # identity: "" # the version to report. Leave "" or default to return package version. # version: "" + # NSID identity (hex string, or "ascii_somestring"). default disabled. + # nsid: "aabbccdd" + + # User-Agent HTTP header to use. Leave "" or default to use package name + # and version. + # http-user-agent: "" + # the target fetch policy. # series of integers describing the policy per dependency depth. # The number of values in the list determines the maximum dependency @@ -366,7 +426,7 @@ server: # target-fetch-policy: "3 2 1 0 0" # Harden against very small EDNS buffer sizes. - # harden-short-bufsize: no + # harden-short-bufsize: yes # Harden against unseemly large queries. # harden-large-queries: no @@ -396,7 +456,7 @@ server: # Sent minimum amount of information to upstream servers to enhance # privacy. Only sent minimum required labels of the QNAME and set QTYPE - # to NS when possible. + # to A when possible. qname-minimisation: yes # QNAME minimisation in strict mode. Do not fall-back to sending full @@ -415,8 +475,8 @@ server: # Domains (and domains in them) without support for dns-0x20 and # the fallback fails because they keep sending different answers. - # caps-whitelist: "licdn.com" - # caps-whitelist: "senderbase.org" + # caps-exempt: "licdn.com" + # caps-exempt: "senderbase.org" # Enforce privacy of these addresses. Strips them away from answers. # It may cause DNSSEC validation to additionally mark it as bogus. @@ -457,6 +517,9 @@ server: # if yes, perform key lookups adjacent to normal lookups. prefetch-key: yes + # deny queries of type ANY with an empty response. + deny-any: yes + # if yes, Unbound rotates RRSet order in response. rrset-roundrobin: yes @@ -469,6 +532,9 @@ server: # module configuration of the server. A string with identifiers # separated by spaces. Syntax: "[dns64] [validator] iterator" + # most modules have to be listed at the beginning of the line, + # except cachedb(just before iterator), and python (at the beginning, + # or, just before the iterator). module-config: "ipsecmod validator iterator" # File with trusted keys, kept uptodate using RFC5011 probes, @@ -476,7 +542,7 @@ server: # Use several entries, one per domain name, to track multiple zones. # # If you want to perform DNSSEC validation, run unbound-anchor before - # you start unbound (i.e. in the system boot scripts). And enable: + # you start Unbound (i.e. in the system boot scripts). And enable: # Please note usage of unbound-anchor root anchor is at your own risk # and under the terms of our LICENSE (see that file in the source). # auto-trust-anchor-file: "/var/lib/unbound/root.key" @@ -487,11 +553,6 @@ server: # Root key trust anchor sentinel (draft-ietf-dnsop-kskroll-sentinel) root-key-sentinel: yes - # File with DLV trusted keys. Same format as trust-anchor-file. - # There can be only one DLV configured, it is trusted from root down. - # DLV is going to be decommissioned. Please do not use it any more. - # dlv-anchor-file: "dlv.isc.org.key" - # File with trusted keys for validation. Specify more than one file # with several entries, one file per entry. # Zone file format, with DS and DNSKEY entries. @@ -533,6 +594,10 @@ server: # val-sig-skew-min: 3600 # val-sig-skew-max: 86400 + # The maximum number the validator should restart validation with + # another authority in case of failed validation. + # val-max-restart: 5 + # Should additional section of secure message also be kept clean of # unsecure data. Useful to shield the users of this validator from # potential bogus data in the additional section. All unsigned data @@ -548,13 +613,40 @@ server: val-permissive-mode: no # Ignore the CD flag in incoming queries and refuse them bogus data. - # Enable it if the only clients of unbound are legacy servers (w2008) + # Enable it if the only clients of Unbound are legacy servers (w2008) # that set CD but cannot validate themselves. # ignore-cd-flag: no - # Serve expired responses from cache, with TTL 0 in the response, - # and then attempt to fetch the data afresh. + # Serve expired responses from cache, with serve-expired-reply-ttl in + # the response, and then attempt to fetch the data afresh. serve-expired: yes + # + # Limit serving of expired responses to configured seconds after + # expiration. 0 disables the limit. + serve-expired-ttl: 14400 + # + # Set the TTL of expired records to the serve-expired-ttl value after a + # failed attempt to retrieve the record from upstream. This makes sure + # that the expired records will be served as long as there are queries + # for it. + # serve-expired-ttl-reset: no + # + # TTL value to use when replying with expired data. + # serve-expired-reply-ttl: 30 + # + # Time in milliseconds before replying to the client with expired data. + # This essentially enables the serve-stale behavior as specified in + # RFC 8767 that first tries to resolve before + # immediately responding with expired data. 0 disables this behavior. + # A recommended value is 1800. + # serve-expired-client-timeout: 0 + + # Return the original TTL as received from the upstream name server rather + # than the decrementing TTL as stored in the cache. Enabling this feature + # does not impact cache expiry, it only changes the TTL Unbound embeds in + # responses to queries. Note that enabling this feature implicitly disables + # enforcement of the configured minimum and maximum TTL. + # serve-original-ttl: no # Have the validator log failed validations for your diagnosis. # 0: off. 1: A line per failed user query. 2: With reason and bad IP. @@ -564,7 +656,10 @@ server: # keysize. Keep this table very short, as linear search is done. # A message with an NSEC3 with larger count is marked insecure. # List in ascending order the keysize and count values. - # val-nsec3-keysize-iterations: "1024 150 2048 500 4096 2500" + # val-nsec3-keysize-iterations: "1024 150 2048 150 4096 150" + + # if enabled, ZONEMD verification failures do not block the zone. + # zonemd-permissive-mode: no # instruct the auto-trust-anchor-file probing to add anchors after ttl. # add-holddown: 2592000 # 30 days @@ -589,7 +684,7 @@ server: # more slabs reduce lock contention, but fragment memory usage. # key-cache-slabs: 4 - # the amount of memory to use for the negative cache (used for DLV). + # the amount of memory to use for the negative cache. # plain value in bytes or you can append k, m or G. default is "1Mb". # neg-cache-size: 1m @@ -638,9 +733,12 @@ server: # local-zone: "8.b.d.0.1.0.0.2.ip6.arpa." nodefault # And for 64.100.in-addr.arpa. to 127.100.in-addr.arpa. - # If unbound is running service for the local host then it is useful + # Add example.com into ipset + # local-zone: "example.com" ipset + + # If Unbound is running service for the local host then it is useful # to perform lan-wide lookups to the upstream, and unblock the - # long list of local-zones above. If this unbound is a dns server + # long list of local-zones above. If this Unbound is a dns server # for a network of computers, disabled is better and stops information # leakage of local lan information. # unblock-lan-zones: no @@ -661,8 +759,11 @@ server: # o typetransparent resolves normally for other types and other names # o inform acts like transparent, but logs client IP address # o inform_deny drops queries and logs client IP address - # o always_transparent, always_refuse, always_nxdomain, resolve in - # that way but ignore local data for that name + # o inform_redirect redirects queries and logs client IP address + # o always_transparent, always_refuse, always_nxdomain, always_nodata, + # always_deny resolve in that way but ignore local data for + # that name + # o always_null returns 0.0.0.0 or ::0 for any name in the zone. # o noview breaks out of that view towards global local-zones. # # defaults are localhost address, reverse for 127.0.0.1 and ::1 @@ -698,14 +799,43 @@ server: # add a netblock specific override to a localzone, with zone type # local-zone-override: "example.com" 192.0.2.0/24 refuse - # service clients over SSL (on the TCP sockets), with plain DNS inside - # the SSL stream. Give the certificate to use and private key. + # service clients over TLS (on the TCP sockets) with plain DNS inside + # the TLS stream, and over HTTPS using HTTP/2 as specified in RFC8484. + # Give the certificate to use and private key. # default is "" (disabled). requires restart to take effect. # tls-service-key: "/etc/unbound/unbound_server.key" # tls-service-pem: "/etc/unbound/unbound_server.pem" # tls-port: 853 - # - # request upstream over SSL (with plain DNS inside the SSL stream). + # https-port: 443 + + # cipher setting for TLSv1.2 + # tls-ciphers: "DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256" + # cipher setting for TLSv1.3 + # tls-ciphersuites: "TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256" + # Fedora/RHEL: use system-wide crypto policies + tls-ciphers: "PROFILE=SYSTEM" + # TODO: ask system-wide crypto people what to use here + #tls-ciphersuites: "PROFILE=SYSTEM" # does not work + + # Pad responses to padded queries received over TLS + # pad-responses: yes + + # Padded responses will be padded to the closest multiple of this size. + # pad-responses-block-size: 468 + + # Use the SNI extension for TLS connections. Default is yes. + # Changing the value requires a reload. + # tls-use-sni: yes + + # Add the secret file for TLS Session Ticket. + # Secret file must be 80 bytes of random data. + # First key use to encrypt and decrypt TLS session tickets. + # Other keys use to decrypt only. + # requires restart to take effect. + # tls-session-ticket-keys: "path/to/secret_file1" + # tls-session-ticket-keys: "path/to/secret_file2" + + # request upstream over TLS (with plain DNS inside the TLS stream). # Default is no. Can be turned on and off with unbound-control. # tls-upstream: no @@ -715,13 +845,41 @@ server: # Add system certs to the cert bundle, from the Windows Cert Store # tls-win-cert: no + # Pad queries over TLS upstreams + # pad-queries: yes + + # Padded queries will be padded to the closest multiple of this size. + # pad-queries-block-size: 128 + # Also serve tls on these port numbers (eg. 443, ...), by listing - # tls-additional-ports: portno for each of the port numbers. + # tls-additional-port: portno for each of the port numbers. + + # HTTP endpoint to provide DNS-over-HTTPS service on. + # http-endpoint: "/dns-query" + + # HTTP/2 SETTINGS_MAX_CONCURRENT_STREAMS value to use. + # http-max-streams: 100 + + # Maximum number of bytes used for all HTTP/2 query buffers. + # http-query-buffer-size: 4m + + # Maximum number of bytes used for all HTTP/2 response buffers. + # http-response-buffer-size: 4m + + # Set TCP_NODELAY socket option on sockets used for DNS-over-HTTPS + # service. + # http-nodelay: yes + + # Disable TLS for DNS-over-HTTP downstream service. + # http-notls-downstream: no # DNS64 prefix. Must be specified when DNS64 is use. # Enable dns64 in module-config. Used to synthesize IPv6 from IPv4. # dns64-prefix: 64:ff9b::0/96 + # DNS64 ignore AAAA records for these domains and use A instead. + # dns64-ignore-aaaa: "example.com" + # ratelimit for uncached, new queries, this limits recursion effort. # ratelimiting is experimental, and may help against randomqueryflood. # if 0(default) it is disabled, otherwise state qps allowed per zone. @@ -735,12 +893,6 @@ server: # 0 blocks when ratelimited, otherwise let 1/xth traffic through # ratelimit-factor: 10 - # what is considered a low rtt (ping time for upstream server), in msec - # low-rtt: 45 - # select low rtt this many times out of 1000. 0 means the fast server - # select is disabled. prefetches are not sped up. - # low-rtt-permil: 0 - # override the ratelimit for a specific domain name. # give this setting multiple times to have multiple overrides. # ratelimit-for-domain: example.com 1000 @@ -761,7 +913,16 @@ server: # 0 blocks when ip is ratelimited, otherwise let 1/xth traffic through # ip-ratelimit-factor: 10 - # Specific options for ipsecmod. unbound needs to be configured with + # Limit the number of connections simultaneous from a netblock + # tcp-connection-limit: 192.0.2.0/24 12 + + # select from the fastest servers this many times out of 1000. 0 means + # the fast server select is disabled. prefetches are not sped up. + # fast-server-permil: 0 + # the number of servers that will be used in the fast server selection. + # fast-server-num: 3 + + # Specific options for ipsecmod. Unbound needs to be configured with # --enable-ipsecmod for these to take effect. # # Enable or disable ipsecmod (it still needs to be defined in @@ -775,7 +936,7 @@ server: # ipsecmod-hook: "./my_executable" ipsecmod-hook:/usr/libexec/ipsec/_unbound-hook - # When enabled unbound will reply with SERVFAIL if the return value of + # When enabled Unbound will reply with SERVFAIL if the return value of # the ipsecmod-hook is not 0. # ipsecmod-strict: no # @@ -787,18 +948,38 @@ server: # ipsecmod-ignore-bogus: no # # Domains for which ipsecmod will be triggered. If not defined (default) - # all domains are treated as being whitelisted. - # ipsecmod-whitelist: "libreswan.org" - # ipsecmod-whitelist: "nlnetlabs.nl" + # all domains are treated as being allowed. + # ipsecmod-allow: "example.com" + # ipsecmod-allow: "nlnetlabs.nl" + + # Timeout for REUSE entries in milliseconds. + # tcp-reuse-timeout: 60000 + # Max number of queries on a reuse connection. + # max-reuse-tcp-queries: 200 + # Timeout in milliseconds for TCP queries to auth servers. + # tcp-auth-query-timeout: 3000 # Python config section. To enable: # o use --with-pythonmodule to configure before compiling. # o list python in the module-config string (above) to enable. +# It can be at the start, it gets validated results, or just before +# the iterator and process before DNSSEC validation. # o and give a python-script to run. python: # Script file to load # python-script: "/etc/unbound/ubmodule-tst.py" +# Dynamic library config section. To enable: +# o use --with-dynlibmodule to configure before compiling. +# o list dynlib in the module-config string (above) to enable. +# It can be placed anywhere, the dynlib module is only a very thin wrapper +# to load modules dynamically. +# o and give a dynlib-file to run. If more than one dynlib entry is listed in +# the module-config then you need one dynlib-file per instance. +dynlib: + # Script file to load + # dynlib-file: "/etc/unbound/dynlib.so" + # Remote control config section. remote-control: # Enable remote control with unbound-control(8) here. @@ -812,16 +993,22 @@ remote-control: # what interfaces are listened to for remote control. # give 0.0.0.0 and ::0 to listen to all interfaces. + # set to an absolute path to use a unix local name pipe, certificates + # are not used for that, so key and cert files need not be present. # control-interface: 127.0.0.1 # control-interface: ::1 # port number for remote control operations. # control-port: 8953 - # unbound server key file. + # for localhost, you can disable use of TLS by setting this to "no" + # For local sockets this option is ignored, and TLS is not used. + control-use-cert: "no" + + # Unbound server key file. server-key-file: "/etc/unbound/unbound_server.key" - # unbound server certificate file. + # Unbound server certificate file. server-cert-file: "/etc/unbound/unbound_server.pem" # unbound-control key file. @@ -847,6 +1034,7 @@ include: /etc/unbound/conf.d/*.conf # stub-prime: no # stub-first: no # stub-tls-upstream: no +# stub-no-cache: no # stub-zone: # name: "example.org" # stub-host: ns.example.com. @@ -867,6 +1055,7 @@ include: /etc/unbound/conf.d/*.conf # forward-addr: 192.0.2.73@5355 # forward to port 5355. # forward-first: no # forward-tls-upstream: no +# forward-no-cache: no # forward-zone: # name: "example.org" # forward-host: fwd.example.com @@ -882,21 +1071,36 @@ include: /etc/unbound/conf.d/*.conf # has a copy of the root for local usage. The second serves example.org # authoritatively. zonefile: reads from file (and writes to it if you also # download it), master: fetches with AXFR and IXFR, or url to zonefile. +# With allow-notify: you can give additional (apart from masters) sources of +# notifies. auth-zone: name: "." + primary: 199.9.14.201 # b.root-servers.net + primary: 192.33.4.12 # c.root-servers.net + primary: 199.7.91.13 # d.root-servers.net + primary: 192.5.5.241 # f.root-servers.net + primary: 192.112.36.4 # g.root-servers.net + primary: 193.0.14.129 # k.root-servers.net + primary: 192.0.47.132 # xfr.cjr.dns.icann.org + primary: 192.0.32.132 # xfr.lax.dns.icann.org + primary: 2001:500:200::b # b.root-servers.net + primary: 2001:500:2::c # c.root-servers.net + primary: 2001:500:2d::d # d.root-servers.net + primary: 2001:500:2f::f # f.root-servers.net + primary: 2001:500:12::d0d # g.root-servers.net + primary: 2001:7fd::1 # k.root-servers.net + primary: 2620:0:2830:202::132 # xfr.cjr.dns.icann.org + primary: 2620:0:2d0:202::132 # xfr.lax.dns.icann.org + fallback-enabled: yes for-downstream: no for-upstream: yes - fallback-enabled: yes - master: b.root-servers.net - master: c.root-servers.net - master: e.root-servers.net - master: f.root-servers.net - master: g.root-servers.net - master: k.root-servers.net + # auth-zone: # name: "example.org" # for-downstream: yes # for-upstream: yes +# zonemd-check: no +# zonemd-reject-absence: no # zonefile: "example.org.zone" # Views @@ -910,7 +1114,7 @@ auth-zone: # name: "viewname" # local-zone: "example.com" redirect # local-data: "example.com A 192.0.2.3" -# local-data-ptr: "192.0.2.3 www.example.com" +# local-data-ptr: "192.0.2.3 www.example.com" # view-first: no # view: # name: "anotherview" @@ -921,7 +1125,7 @@ auth-zone: # # DNSCrypt # Caveats: -# 1. the keys/certs cannot be produced by unbound. You can use dnscrypt-wrapper +# 1. the keys/certs cannot be produced by Unbound. You can use dnscrypt-wrapper # for this: https://github.com/cofyc/dnscrypt-wrapper/blob/master/README.md#usage # 2. dnscrypt channel attaches to an interface. you MUST set interfaces to # listen on `dnscrypt-port` with the follo0wing snippet: @@ -943,11 +1147,12 @@ auth-zone: # Enable external backend DB as auxiliary cache. Specify the backend name # (default is "testframe", which has no use other than for debugging and # testing) and backend-specific options. The 'cachedb' module must be -# included in module-config. +# included in module-config, just before the iterator module. # cachedb: # backend: "testframe" # # secret seed string to calculate hashed keys # secret-seed: "default" +# # # For "redis" backend: # # redis server's IP address or host name # redis-server-host: 127.0.0.1 @@ -955,3 +1160,70 @@ auth-zone: # redis-server-port: 6379 # # timeout (in ms) for communication with the redis server # redis-timeout: 100 +# # set timeout on redis records based on DNS response TTL +# redis-expire-records: no + +# IPSet +# Add specify domain into set via ipset. +# Note: To enable ipset Unbound needs to run as root user. +# ipset: +# # set name for ip v4 addresses +# name-v4: "list-v4" +# # set name for ip v6 addresses +# name-v6: "list-v6" +# + +# Dnstap logging support, if compiled in. To enable, set the dnstap-enable +# to yes and also some of dnstap-log-..-messages to yes. And select an +# upstream log destination, by socket path, TCP or TLS destination. +# dnstap: +# dnstap-enable: no +# # if set to yes frame streams will be used in bidirectional mode +# dnstap-bidirectional: yes +# dnstap-socket-path: "/etc/unbound/dnstap.sock" +# # if "" use the unix socket in dnstap-socket-path, otherwise, +# # set it to "IPaddress[@port]" of the destination. +# dnstap-ip: "" +# # if set to yes if you want to use TLS to dnstap-ip, no for TCP. +# dnstap-tls: yes +# # name for authenticating the upstream server. or "" disabled. +# dnstap-tls-server-name: "" +# # if "", it uses the cert bundle from the main Unbound config. +# dnstap-tls-cert-bundle: "" +# # key file for client authentication, or "" disabled. +# dnstap-tls-client-key-file: "" +# # cert file for client authentication, or "" disabled. +# dnstap-tls-client-cert-file: "" +# dnstap-send-identity: no +# dnstap-send-version: no +# # if "" it uses the hostname. +# dnstap-identity: "" +# # if "" it uses the package version. +# dnstap-version: "" +# dnstap-log-resolver-query-messages: no +# dnstap-log-resolver-response-messages: no +# dnstap-log-client-query-messages: no +# dnstap-log-client-response-messages: no +# dnstap-log-forwarder-query-messages: no +# dnstap-log-forwarder-response-messages: no + +# Response Policy Zones +# RPZ policies. Applied in order of configuration. QNAME, Response IP +# Address, nsdname, nsip and clientip triggers are supported. Supported +# actions are: NXDOMAIN, NODATA, PASSTHRU, DROP, Local Data, tcp-only +# and drop. Policies can be loaded from a file, or using zone +# transfer, or using HTTP. The respip module needs to be added +# to the module-config, e.g.: module-config: "respip validator iterator". +# rpz: +# name: "rpz.example.com" +# zonefile: "rpz.example.com" +# primary: 192.0.2.0 +# allow-notify: 192.0.2.0/32 +# url: http://www.example.com/rpz.example.org.zone +# rpz-action-override: cname +# rpz-cname-override: www.example.org +# rpz-log: yes +# rpz-log-name: "example policy" +# rpz-signal-nxdomain-ra: no +# for-downstream: no +# tags: "example" diff --git a/SPECS/unbound.spec b/SPECS/unbound.spec index 6f3335f..1007706 100644 --- a/SPECS/unbound.spec +++ b/SPECS/unbound.spec @@ -33,8 +33,8 @@ Summary: Validating, recursive, and caching DNS(SEC) resolver Name: unbound -Version: 1.7.3 -Release: 17%{?extra_version:.%{extra_version}}%{?dist} +Version: 1.16.2 +Release: 2%{?extra_version:.%{extra_version}}%{?dist} License: BSD Url: https://www.unbound.net/ Source: https://www.unbound.net/downloads/%{name}-%{version}%{?extra_version}.tar.gz @@ -54,23 +54,12 @@ Source14: unbound.sysconfig Source15: unbound-anchor.timer Source16: unbound-munin.README Source17: unbound-anchor.service +Source18: https://nlnetlabs.nl/downloads/%{name}/%{name}-%{version}%{?extra_version}.tar.gz.asc -Patch2: unbound-1.7.2-python3-devel.patch -Patch3: unbound-1.7.2-python3-pkgconfig.patch -Patch4: unbound-1.7.3-anchor-fallback.patch -Patch5: unbound-1.7.3-host-any.patch -Patch6: unbound-1.7.3-use-basic-lock.patch -Patch7: unbound-1.7.3-ipsec-hook.patch -Patch8: unbound-1.7.3-auth-callback.patch -Patch9: unbound-1.7.3-ksk-2010-revoked.patch -Patch10: unbound-1.7.3-DNS-over-TLS-memory-leak.patch -Patch11: unbound-1.7.3-amplifying-an-incoming-query.patch -Patch12: unbound-1.7.3-crypto-policy-non-compliance-openssl.patch -Patch13: unbound-1.7.3-additional-logging.patch -Patch14: unbound-1.7.3-security-hardening.patch -Patch15: unbound-1.7.3-symlink-traversal.patch -# rhbz#1830625 upstream PR https://github.com/NLnetLabs/unbound/pull/415/files -Patch16: unbound-1.7.3-rh1830625.patch +# Reverts ABI change done in version 1.8.0 (bz#2027735) +# Makes possible backward binary compatibility with a new features +Patch1: unbound-1.15-soversion2-compat.patch +Patch2: unbound-1.15-source-compat.patch BuildRequires: gdb BuildRequires: gcc, make @@ -85,12 +74,14 @@ BuildRequires: python3-devel swig %endif # with_python3 BuildRequires: systemd # Required for SVN versions -# BuildRequires: bison -# BuildRequires: automake autoconf libtool +BuildRequires: bison +BuildRequires: automake autoconf libtool %{?systemd_requires} # Needed because /usr/sbin/unbound links unbound libs staticly Requires: %{name}-libs%{?_isa} = %{version}-%{release} +# unbound-keygen.service requires it, bug #2116790 +Requires: openssl %description Unbound is a validating, recursive, and caching DNS(SEC) resolver. @@ -167,24 +158,10 @@ Python 3 modules and extensions for unbound %setup -qcn %{pkgname} pushd %{pkgname} -%patch2 -p1 -b .python3 -%patch3 -p1 -b .python3 -%patch4 -p1 -b .anchor-fallback -%patch5 -p1 -b .host-any -%patch6 -p1 -b .use-basic-lock -%patch7 -p1 -b .ipsec-hook -%patch8 -p1 -b .auth-callback -%patch9 -p1 -b .ksk-2010-revoked -%patch10 -p1 -b .DNS-over-TLS-memory-leak -%patch11 -p1 -b .amplifying-an-incoming-query -%patch12 -p1 -b .crypto-policy -%patch13 -p1 -b .additional-logging -%patch14 -p1 -b .security-hardening -%patch15 -p1 -b .symlink-traversal -%patch16 -p1 -b .rh1830625 - -# only for snapshots -# autoreconf -iv + +%patch1 -p2 -b .solib2-compat +%patch2 -p1 -b .srccompat + # copy common doc files - after here, since it may be patched cp -pr doc pythonmod libunbound ../ @@ -196,9 +173,6 @@ cp -a %{dir_primary} %{dir_secondary} %endif %build -# This is needed to rebuild the configure script to support Python 3.x -# autoreconf -iv - # ./configure script common arguments %global configure_args --with-libevent --with-pthreads --with-ssl \\\ --disable-rpath --disable-static \\\ @@ -212,6 +186,9 @@ cp -a %{dir_primary} %{dir_secondary} pushd %{dir_primary} +# configure.ac is modified, force refresh +autoreconf -fiv + %configure \ %if 0%{?python_primary:1} --with-pythonmodule --with-pyunbound PYTHON=%{python_primary} \ @@ -456,6 +433,24 @@ popd %verify(not md5 size mtime) %{_sharedstatedir}/%{name}/root.key %changelog +* Tue Aug 09 2022 Petr Menšík - 1.16.2-2 +- Require openssl tool for unbound-keygen (#2018806) + +* Wed Aug 03 2022 Petr Menšík - 1.16.2-1 +- Update to 1.16.2 (#2027735) + +* Wed Jun 15 2022 Petr Menšík - 1.16.0-2 +- Restart keygen service before every unbound start (#1959468) + +* Wed Jun 15 2022 Petr Menšík - 1.16.0-1 +- Upgrade to 9.16.0 (#2027735) +- Update to recent version with compatibility with RHEL8 (#2027735) +- Ensure also source level compatibility with previous version + +* Thu May 19 2022 Richard Lescak - 1.7.3-18 +- Change file mode before owner when configuring remote control unix socket to avoid AVC denials +- Resolves: rhbz#2038251 + * Mon Apr 26 2021 Artem Egorenkov - 1.7.3-17 - Option --enable-linux-ip-local-port-range added to use system configured port range for libunbound on Linux - Resolves: rhbz#1830625