From de14b9a16084a566673a73d6bc1c0205ec3991de Mon Sep 17 00:00:00 2001 From: Masaori Koshiba Date: Fri, 26 Jun 2026 18:52:17 +0900 Subject: [PATCH 1/3] proxy/unit_tests: restore IpAllow::subjects stub definition #13278 dropped this definition, but test_proxy links ts::http (which references IpAllow::subjects) ahead of ts::proxy (which defines it). GNU ld's single-pass archive scan then leaves the symbol unresolved, breaking the Linux build; macOS links fine. master avoids this incidentally via test_PluginYAML.cc from the unbackported plugin.yaml migration (#13070). --- src/proxy/unit_tests/stub.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/proxy/unit_tests/stub.cc b/src/proxy/unit_tests/stub.cc index ba279051a34..a1a95fe8ccb 100644 --- a/src/proxy/unit_tests/stub.cc +++ b/src/proxy/unit_tests/stub.cc @@ -22,3 +22,5 @@ */ #include "proxy/IPAllow.h" + +uint8_t IpAllow::subjects[IpAllow::Subject::MAX_SUBJECTS]; From cb22905df9d55ec53931a9ab4e8966280afa8367 Mon Sep 17 00:00:00 2001 From: Masaori Koshiba Date: Fri, 26 Jun 2026 20:46:41 +0900 Subject: [PATCH 2/3] tls autests: use ssl_multicert.config instead of yaml These tests were backported from master, where the default cert config is ssl_multicert.yaml and the harness exposes ts.Disk.ssl_multicert_yaml. On 10.2.x the default is still legacy ssl_multicert.config and no ssl_multicert_yaml Disk attribute is registered, so the tests failed at collection. Switch them to the ssl_multicert.config one-liner used by the other 10.2.x TLS tests. --- tests/gold_tests/tls/tls_flow_control.test.py | 8 +------- tests/gold_tests/tls/tls_record_size.test.py | 8 +------- tests/gold_tests/tls/tls_reload_under_load.test.py | 12 +++--------- tests/gold_tests/tls/tls_renegotiation.test.py | 8 +------- .../gold_tests/tls/tls_renegotiation_allowed.test.py | 8 +------- 5 files changed, 7 insertions(+), 37 deletions(-) diff --git a/tests/gold_tests/tls/tls_flow_control.test.py b/tests/gold_tests/tls/tls_flow_control.test.py index f1da9221825..4ff3886f6e2 100644 --- a/tests/gold_tests/tls/tls_flow_control.test.py +++ b/tests/gold_tests/tls/tls_flow_control.test.py @@ -70,13 +70,7 @@ def _configure_trafficserver(self) -> 'Process': TestTlsFlowControl._ts_counter += 1 ts.addDefaultSSLFiles() - ts.Disk.ssl_multicert_yaml.AddLines( - """ -ssl_multicert: - - dest_ip: "*" - ssl_cert_name: server.pem - ssl_key_name: server.key -""".split("\n")) + ts.Disk.ssl_multicert_config.AddLine('dest_ip=* ssl_cert_name=server.pem ssl_key_name=server.key') ts.Disk.remap_config.AddLine(f'map / http://127.0.0.1:{self._server.Variables.Port}') ts.Disk.records_config.update( { diff --git a/tests/gold_tests/tls/tls_record_size.test.py b/tests/gold_tests/tls/tls_record_size.test.py index b40c33a6fa5..da1960a30d1 100644 --- a/tests/gold_tests/tls/tls_record_size.test.py +++ b/tests/gold_tests/tls/tls_record_size.test.py @@ -75,13 +75,7 @@ def _configure_trafficserver(self) -> 'Process': TestRecordSizeClamp._ts_counter += 1 ts.addDefaultSSLFiles() - ts.Disk.ssl_multicert_yaml.AddLines( - """ -ssl_multicert: - - dest_ip: "*" - ssl_cert_name: server.pem - ssl_key_name: server.key -""".split("\n")) + ts.Disk.ssl_multicert_config.AddLine('dest_ip=* ssl_cert_name=server.pem ssl_key_name=server.key') ts.Disk.remap_config.AddLine(f'map / http://127.0.0.1:{self._server.Variables.Port}') ts.Disk.records_config.update( { diff --git a/tests/gold_tests/tls/tls_reload_under_load.test.py b/tests/gold_tests/tls/tls_reload_under_load.test.py index 1828da760d2..1726a112d72 100644 --- a/tests/gold_tests/tls/tls_reload_under_load.test.py +++ b/tests/gold_tests/tls/tls_reload_under_load.test.py @@ -1,6 +1,6 @@ ''' Existing cert/SNI reload tests reload while the server is idle. This one drives -continuous concurrent TLS handshakes and reloads ssl_multicert.yaml on top of +continuous concurrent TLS handshakes and reloads ssl_multicert.config on top of them, stressing the SSL/BIO ownership boundary of the layered TLS VConnection. The swapped-in certificate must take effect, every handshake must succeed, and ATS must not crash. @@ -51,13 +51,7 @@ def _configure_trafficserver(self) -> 'Process': ts.addSSLfile("ssl/signed-bar.key") ts.addSSLfile("ssl/signed2-bar.pem") - ts.Disk.ssl_multicert_yaml.AddLines( - """ -ssl_multicert: - - dest_ip: "*" - ssl_cert_name: signed-bar.pem - ssl_key_name: signed-bar.key -""".split("\n")) + ts.Disk.ssl_multicert_config.AddLine('dest_ip=* ssl_cert_name=signed-bar.pem ssl_key_name=signed-bar.key') ts.Disk.records_config.update( { 'proxy.config.ssl.server.cert.path': f'{ts.Variables.SSLDir}', @@ -69,7 +63,7 @@ def _configure_trafficserver(self) -> 'Process': # The reload must actually have run (otherwise the test would be vacuous). ts.Disk.diags_log.Content = Testers.ContainsExpression( - "ssl_multicert.yaml finished loading", "the cert configuration must reload while load is in flight") + "ssl_multicert.config finished loading", "the cert configuration must reload while load is in flight") # The reload-under-load must not crash or trip an assertion / sanitizer. ts.Disk.traffic_out.Content = Testers.ExcludesExpression( "received signal|failed assertion", "ATS must not crash reloading certs under load") diff --git a/tests/gold_tests/tls/tls_renegotiation.test.py b/tests/gold_tests/tls/tls_renegotiation.test.py index 70fecc14df4..a65979bb232 100644 --- a/tests/gold_tests/tls/tls_renegotiation.test.py +++ b/tests/gold_tests/tls/tls_renegotiation.test.py @@ -61,13 +61,7 @@ def _configure_trafficserver(self) -> 'Process': ts.addSSLfile("ssl/server.pem") ts.addSSLfile("ssl/server.key") - ts.Disk.ssl_multicert_yaml.AddLines( - """ -ssl_multicert: - - dest_ip: "*" - ssl_cert_name: server.pem - ssl_key_name: server.key -""".split("\n")) + ts.Disk.ssl_multicert_config.AddLine('dest_ip=* ssl_cert_name=server.pem ssl_key_name=server.key') ts.Disk.records_config.update( { 'proxy.config.ssl.server.cert.path': f'{ts.Variables.SSLDir}', diff --git a/tests/gold_tests/tls/tls_renegotiation_allowed.test.py b/tests/gold_tests/tls/tls_renegotiation_allowed.test.py index a5f58ff3581..c903bfcd0b8 100644 --- a/tests/gold_tests/tls/tls_renegotiation_allowed.test.py +++ b/tests/gold_tests/tls/tls_renegotiation_allowed.test.py @@ -83,13 +83,7 @@ def _configure_trafficserver(self) -> 'Process': ts.addSSLfile("ssl/server.pem") ts.addSSLfile("ssl/server.key") - ts.Disk.ssl_multicert_yaml.AddLines( - """ -ssl_multicert: - - dest_ip: "*" - ssl_cert_name: server.pem - ssl_key_name: server.key -""".split("\n")) + ts.Disk.ssl_multicert_config.AddLine('dest_ip=* ssl_cert_name=server.pem ssl_key_name=server.key') ts.Disk.records_config.update( { 'proxy.config.ssl.server.cert.path': f'{ts.Variables.SSLDir}', From bc30f068398a010c7bce4d848f88794bb2ea2a56 Mon Sep 17 00:00:00 2001 From: Brian Neradt Date: Thu, 4 Jun 2026 15:40:15 -0500 Subject: [PATCH 3/3] curl 8.20 test update: curl PROXY destination changes (#13239) curl 8.20 intentionally mirrors --haproxy-clientip into both PROXY addresses to keep the header address family consistent. The TSVConnPPInfo AuTest still expected the older destination address, so jobs with newer curl failed even though ATS preserved the PROXY metadata it received. This relaxes the destination-address expectation to accept either curl behavior while continuing to verify the source address and PROXY metadata. This also wraps the long curl command strings while leaving the test's request flow unchanged. (cherry picked from commit ad0ce02abf550455896167fa79ca1224f939cf1c) --- .../pluginTest/tsapi/test_TSVConnPPInfo.test.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/gold_tests/pluginTest/tsapi/test_TSVConnPPInfo.test.py b/tests/gold_tests/pluginTest/tsapi/test_TSVConnPPInfo.test.py index 0c45109d971..e74e2c40d61 100644 --- a/tests/gold_tests/pluginTest/tsapi/test_TSVConnPPInfo.test.py +++ b/tests/gold_tests/pluginTest/tsapi/test_TSVConnPPInfo.test.py @@ -73,7 +73,9 @@ # plaintext HTTP tr = Test.AddTestRun() tr.TimeOut = 10 -tr.Processes.Default.Command = f"curl --haproxy-protocol --haproxy-clientip 1.2.3.4 'http://127.0.0.1:{ts.Variables.proxy_protocol_port}/httpbin/get'" +tr.Processes.Default.Command = ( + f"curl --haproxy-protocol --haproxy-clientip 1.2.3.4 " + f"'http://127.0.0.1:{ts.Variables.proxy_protocol_port}/httpbin/get'") tr.Processes.Default.ReturnCode = 0 tr.Processes.Default.StartBefore(httpbin) tr.Processes.Default.StartBefore(Test.Processes.ts) @@ -84,7 +86,9 @@ # HTTPS tr = Test.AddTestRun() tr.TimeOut = 10 -tr.Processes.Default.Command = f"curl --haproxy-protocol --haproxy-clientip 5.6.7.8 -k 'https://127.0.0.1:{ts.Variables.proxy_protocol_ssl_port}/httpbin/get'" +tr.Processes.Default.Command = ( + f"curl --haproxy-protocol --haproxy-clientip 5.6.7.8 -k " + f"'https://127.0.0.1:{ts.Variables.proxy_protocol_ssl_port}/httpbin/get'") tr.Processes.Default.ReturnCode = 0 tr.Processes.Default.Streams.stdout = "test_TSVConnPPInfo_curl1.gold" tr.StillRunningAfter = httpbin @@ -95,7 +99,8 @@ tr.Processes.Default.ReturnCode = 0 f = tr.Disk.File(log_path) f.Content = "test_TSVConnPPInfo_plugin_log.gold" +# curl 8.20+ intentionally uses --haproxy-clientip for both PROXY addresses so the address family matches. f.Content += Testers.ContainsExpression( - "PP Info Received:V1,P2,T1,SRC1.2.3.4,DST127.0.0.1", "Expected information should be received") + r"PP Info Received:V1,P2,T1,SRC1\.2\.3\.4,DST(127\.0\.0\.1|1\.2\.3\.4)", "Expected information should be received") f.Content += Testers.ContainsExpression( - "PP Info Received:V1,P2,T1,SRC5.6.7.8,DST127.0.0.1", "Expected information should be received") + r"PP Info Received:V1,P2,T1,SRC5\.6\.7\.8,DST(127\.0\.0\.1|5\.6\.7\.8)", "Expected information should be received")