diff --git a/gradle.properties b/gradle.properties
index 30aa3f0a755a..4119558fc171 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -11,8 +11,8 @@ checkstyleToolVersion=10.12.4
commonsCodecVersion=1.21.0
graalVersion=25
hamcrestVersion=3.0
-jackson2Version=2.21.3
-jacksonVersion=3.1.3
+jackson2Version=2.21.4
+jacksonVersion=3.1.4
javaFormatVersion=0.0.47
junitJupiterVersion=6.0.3
kotlinVersion=2.3.21
diff --git a/module/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/InetAddressFilter.java b/module/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/InetAddressFilter.java
index 2dfd54be6936..94ebc86ebe08 100644
--- a/module/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/InetAddressFilter.java
+++ b/module/spring-boot-http-client/src/main/java/org/springframework/boot/http/client/InetAddressFilter.java
@@ -185,12 +185,16 @@ default InetAddressFilter negate() {
/**
* Return a filter that will match external (non-private) IP addresses. External
- * addresses are all non-{@link #internalAddresses() internal addresses}
+ * addresses are all {@link #routable() routable} addresses that are not:
+ *
+ * - {@link #multicast() multicast}
+ * - {@link #specialPurpose() special purpose}
+ *
* @return a filter for external IP addresses
* @see #internalAddresses()
*/
static InetAddressFilter externalAddresses() {
- return routable().andNot(InternalInetAddressFilter.instance);
+ return routable().andNot(multicast(), specialPurpose());
}
/**
@@ -224,6 +228,27 @@ static InetAddressFilter routable() {
};
}
+ /**
+ * Returns a filter that will match all multicast addresses.
+ * @return a filter for multicast IP addresses
+ */
+ static InetAddressFilter multicast() {
+ return InetAddress::isMulticastAddress;
+ }
+
+ /**
+ * Returns a filter that will match special purpose IP addresses as defined by
+ * RFC 6890.
+ * @return a filter for this network
+ */
+ static InetAddressFilter specialPurpose() {
+ return of("0.0.0.0/8", "100.64.0.0/10", "127.0.0.0/8", "169.254.0.0/16", "192.0.0.0/24", "192.0.0.0/29",
+ "192.0.2.0/24", "192.88.99.0/24", "198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", "240.0.0.0/4",
+ "255.255.255.255/32", "::1/128", "::/128", "64:ff9b::/96", "100::/64", "2001::/23", "2001::/32",
+ "2001:2::/48", "2001:db8::/32", "2001:10::/28", "2002::/16", "fc00::/7", "fe80::/10")
+ .or(InternalInetAddressFilter.instance);
+ }
+
/**
* Return a filter that is the negation of all the given addresses.
* @param addresses the addresses to negate in any form supported by
diff --git a/module/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/InetAddressFilterTests.java b/module/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/InetAddressFilterTests.java
index 3eb8d4089138..31106bacb945 100644
--- a/module/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/InetAddressFilterTests.java
+++ b/module/spring-boot-http-client/src/test/java/org/springframework/boot/http/client/InetAddressFilterTests.java
@@ -327,6 +327,65 @@ void ipv6NonRoutable() {
assertThat(filter).doesNotMatch("::");
}
+ @Test
+ void ipv4CurrentLocalThisNetwork() {
+ InetAddressFilter filter = InetAddressFilter.externalAddresses();
+ assertThat(filter).doesNotMatch("0.0.0.4");
+ }
+
+ @Test
+ void ipv4Subnet() {
+ InetAddressFilter filter = InetAddressFilter.externalAddresses();
+ assertThat(filter).doesNotMatch("169.254.0.1");
+ assertThat(filter).doesNotMatch("255.255.255.255");
+ }
+
+ @Test
+ void ipv4Documentation() {
+ InetAddressFilter filter = InetAddressFilter.externalAddresses();
+ assertThat(filter).doesNotMatch("192.0.2.1");
+ assertThat(filter).doesNotMatch("203.0.113.1");
+ }
+
+ @Test
+ void ipv4Multicast() {
+ InetAddressFilter filter = InetAddressFilter.externalAddresses();
+ assertThat(filter).doesNotMatch("224.0.0.1");
+ }
+
+ @Test
+ void ipv4ReservedForFutureUse() {
+ InetAddressFilter filter = InetAddressFilter.externalAddresses();
+ assertThat(filter).doesNotMatch("240.0.0.1");
+ }
+
+ @Test
+ void ipv4SharedAddressSpace() {
+ InetAddressFilter filter = InetAddressFilter.externalAddresses();
+ assertThat(filter).doesNotMatch("100.64.0.1");
+ assertThat(filter).doesNotMatch("100.127.255.254");
+ }
+
+ @Test
+ void ipv4PerformanceBenchmarking() {
+ InetAddressFilter filter = InetAddressFilter.externalAddresses();
+ assertThat(filter).doesNotMatch("198.18.0.1");
+ assertThat(filter).doesNotMatch("198.19.255.255");
+ }
+
+ @Test
+ void ipv4AllHostsMulticastGroup() {
+ InetAddressFilter filter = InetAddressFilter.externalAddresses();
+ assertThat(filter).doesNotMatch("224.0.0.1");
+ assertThat(filter).doesNotMatch("239.255.255.250");
+ }
+
+ @Test
+ void ipv6NodeLinkMulticastAddress() {
+ InetAddressFilter filter = InetAddressFilter.externalAddresses();
+ assertThat(filter).doesNotMatch("ff02::1");
+ }
+
}
@Nested
@@ -521,6 +580,163 @@ void routable() {
}
+ @Nested
+ class Multicast {
+
+ @Test
+ void multicast() {
+ InetAddressFilter filter = InetAddressFilter.multicast();
+ assertThat(filter).matches("239.255.255.255");
+ assertThat(filter).matches("FF00:0000:0000:0000:0000:0000:0000:0001");
+ }
+
+ }
+
+ @Nested
+ class SpecialPurpose {
+
+ @Test
+ void publicAddress() {
+ InetAddressFilter filter = InetAddressFilter.specialPurpose();
+ assertThat(filter).doesNotMatch("8.8.8.8");
+ }
+
+ @Test
+ void thisHostNetwork() {
+ InetAddressFilter filter = InetAddressFilter.specialPurpose();
+ assertThat(filter).matches("0.0.0.1");
+ }
+
+ @Test
+ void privateUseNetwork() {
+ InetAddressFilter filter = InetAddressFilter.specialPurpose();
+ assertThat(filter).matches("10.0.0.1");
+ assertThat(filter).matches("172.16.0.1");
+ assertThat(filter).matches("192.168.0.1");
+ }
+
+ @Test
+ void sharedAddressSpace() {
+ InetAddressFilter filter = InetAddressFilter.specialPurpose();
+ assertThat(filter).matches("100.64.0.1");
+ }
+
+ @Test
+ void loopback() {
+ InetAddressFilter filter = InetAddressFilter.specialPurpose();
+ assertThat(filter).matches("127.0.0.0");
+ assertThat(filter).matches("::1");
+ }
+
+ @Test
+ void linkLocal() {
+ InetAddressFilter filter = InetAddressFilter.specialPurpose();
+ assertThat(filter).matches("169.254.0.1");
+ }
+
+ @Test
+ void protocolAssignments() {
+ InetAddressFilter filter = InetAddressFilter.specialPurpose();
+ assertThat(filter).matches("192.0.0.1");
+ assertThat(filter).matches("2001:0000:0000:0000:0000:0000:0000:0001");
+ }
+
+ @Test
+ void dsLite() {
+ InetAddressFilter filter = InetAddressFilter.specialPurpose();
+ assertThat(filter).matches("192.0.0.1");
+ }
+
+ @Test
+ void documentation() {
+ InetAddressFilter filter = InetAddressFilter.specialPurpose();
+ assertThat(filter).matches("192.0.2.1");
+ assertThat(filter).matches("198.51.100.1");
+ assertThat(filter).matches("203.0.113.1");
+ assertThat(filter).matches("2001:0db8:0000:0000:0000:0000:0000:0001");
+ }
+
+ @Test
+ void SixToFourRelay() {
+ InetAddressFilter filter = InetAddressFilter.specialPurpose();
+ assertThat(filter).matches("192.88.99.1");
+ }
+
+ @Test
+ void deviceBenchmarking() {
+ InetAddressFilter filter = InetAddressFilter.specialPurpose();
+ assertThat(filter).matches("198.18.0.1");
+ assertThat(filter).matches("2001:0002:0000:0000:0000:0000:0000:0001");
+ }
+
+ @Test
+ void futureUse() {
+ InetAddressFilter filter = InetAddressFilter.specialPurpose();
+ assertThat(filter).matches("240.0.0.1");
+ }
+
+ @Test
+ void limitedBroadcast() {
+ InetAddressFilter filter = InetAddressFilter.specialPurpose();
+ assertThat(filter).matches("255.255.255.255");
+ }
+
+ @Test
+ void unspecifiedAddress() {
+ InetAddressFilter filter = InetAddressFilter.specialPurpose();
+ assertThat(filter).matches("0000:0000:0000:0000:0000:0000:0000:0001");
+ }
+
+ @Test
+ void ipv4ToIpv6AddressTranslation() {
+ InetAddressFilter filter = InetAddressFilter.specialPurpose();
+ assertThat(filter).matches("0064:ff9b:0000:0000:0000:0000:0000:0001");
+ }
+
+ @Test
+ void ipv4MappedAddress() {
+ InetAddressFilter filter = InetAddressFilter.specialPurpose();
+ assertThat(filter).matches("0000:0000:0000:0000:0000:ffff:0000:0001");
+ }
+
+ @Test
+ void discardOnly() {
+ InetAddressFilter filter = InetAddressFilter.specialPurpose();
+ assertThat(filter).matches("0100:0000:0000:0000:0000:0000:0000:0001");
+ }
+
+ @Test
+ void teredo() {
+ InetAddressFilter filter = InetAddressFilter.specialPurpose();
+ assertThat(filter).matches("2001:0000:0000:0000:0000:0000:0000:0001");
+ }
+
+ @Test
+ void orchid() {
+ InetAddressFilter filter = InetAddressFilter.specialPurpose();
+ assertThat(filter).matches("2001:10:0000:0000:0000:0000:0000:0001");
+ }
+
+ @Test
+ void sixToFour() {
+ InetAddressFilter filter = InetAddressFilter.specialPurpose();
+ assertThat(filter).matches("2002:0000:0000:0000:0000:0000:0000:0001");
+ }
+
+ @Test
+ void uniqueLocal() {
+ InetAddressFilter filter = InetAddressFilter.specialPurpose();
+ assertThat(filter).matches("fc00:0000:0000:0000:0000:0000:0000:0001");
+ }
+
+ @Test
+ void linkedScopedUnicast() {
+ InetAddressFilter filter = InetAddressFilter.specialPurpose();
+ assertThat(filter).matches("fe80:0000:0000:0000:0000:0000:0000:0001");
+ }
+
+ }
+
@Nested
class NotTests {
diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle
index c77954e2dcc4..ac109d51a86b 100644
--- a/platform/spring-boot-dependencies/build.gradle
+++ b/platform/spring-boot-dependencies/build.gradle
@@ -31,7 +31,7 @@ bom {
]
}
}
- library("ActiveMQ", "6.2.5") {
+ library("ActiveMQ", "6.2.6") {
group("org.apache.activemq") {
modules = [
"activemq-console",
@@ -186,7 +186,7 @@ bom {
releaseNotes("https://github.com/mojohaus/build-helper-maven-plugin/releases/tag/{version}")
}
}
- library("Byte Buddy", "1.18.8") {
+ library("Byte Buddy", "1.18.9") {
group("net.bytebuddy") {
modules = [
"byte-buddy",
@@ -231,7 +231,7 @@ bom {
releaseNotes("https://github.com/ben-manes/caffeine/releases/tag/v{version}")
}
}
- library("Cassandra Driver", "4.19.2") {
+ library("Cassandra Driver", "4.19.3") {
group("org.apache.cassandra") {
bom("java-driver-bom") {
permit("com.datastax.oss:native-protocol")
@@ -401,7 +401,7 @@ bom {
releaseNotes("https://github.com/ehcache/ehcache3/releases/tag/v{version}")
}
}
- library("Elasticsearch Client", "9.4.1") {
+ library("Elasticsearch Client", "9.4.2") {
prohibit {
contains "-alpha"
contains "-beta"
@@ -484,7 +484,7 @@ bom {
releaseNotes("https://github.com/git-commit-id/git-commit-id-maven-plugin/releases/tag/v{version}")
}
}
- library("Glassfish JAXB", "4.0.8") {
+ library("Glassfish JAXB", "4.0.9") {
alignWith {
dependencyManagementDeclaredIn("org.glassfish.jaxb:jaxb-bom") {
excluding { candidate -> candidate.classifier().equals("sources") }
@@ -854,7 +854,7 @@ bom {
releaseNotes("https://github.com/jakartaee/jsonp-api/releases/tag/{version}-RELEASE")
}
}
- library("Jakarta Json Bind", "3.0.1") {
+ library("Jakarta Json Bind", "3.0.2") {
group("jakarta.json.bind") {
modules = [
"jakarta.json.bind-api"
@@ -1035,7 +1035,7 @@ bom {
]
}
}
- library("Jaxen", "2.0.3") {
+ library("Jaxen", "2.0.5") {
group("jaxen") {
modules = [
"jaxen"
@@ -1115,7 +1115,7 @@ bom {
]
}
}
- library("Jetty", "12.1.8") {
+ library("Jetty", "12.1.10") {
prohibit {
contains ".alpha"
because "we don't want alpha dependencies"
@@ -1241,7 +1241,7 @@ bom {
releaseNotes("https://junit.org/junit5/docs/{version}/release-notes")
}
}
- library("Kafka", "4.2.0") {
+ library("Kafka", "4.2.1") {
group("org.apache.kafka") {
modules = [
"connect",
@@ -1373,7 +1373,7 @@ bom {
releaseNotes("https://github.com/apache/logging-log4j2/releases/tag/rel%2F{version}")
}
}
- library("Logback", "1.5.32") {
+ library("Logback", "1.5.34") {
group("ch.qos.logback") {
modules = [
"logback-classic",
@@ -1490,7 +1490,7 @@ bom {
releaseNotes("https://github.com/apache/maven-enforcer/releases/tag/enforcer-{version}")
}
}
- library("Maven Failsafe Plugin", "3.5.5") {
+ library("Maven Failsafe Plugin", "3.5.6") {
group("org.apache.maven.plugins") {
plugins = [
"maven-failsafe-plugin"
@@ -1593,7 +1593,7 @@ bom {
releaseNotes("https://github.com/apache/maven-source-plugin/releases/tag/maven-source-plugin-{version}")
}
}
- library("Maven Surefire Plugin", "3.5.5") {
+ library("Maven Surefire Plugin", "3.5.6") {
group("org.apache.maven.plugins") {
plugins = [
"maven-surefire-plugin"
@@ -1752,7 +1752,7 @@ bom {
releaseNotes("https://github.com/neo4j/neo4j-java-driver/releases/tag/{version}")
}
}
- library("Netty", "4.2.14.Final") {
+ library("Netty", "4.2.15.Final") {
prohibit {
contains ".Alpha"
contains ".Beta"
@@ -1791,7 +1791,7 @@ bom {
releaseNotes("https://github.com/open-telemetry/opentelemetry-java/releases/tag/v{version}")
}
}
- library("Oracle Database", "23.26.1.0.0") {
+ library("Oracle Database", "23.26.2.0.0") {
alignWith {
dependencyManagementDeclaredIn("com.oracle.database.jdbc:ojdbc-bom")
}