ARTEMIS-212 Unable to parse IPv6 address

This commit is contained in:
jbertram 2015-08-27 10:13:15 -05:00 committed by Clebert Suconic
parent bdd04ebc53
commit c08d791216
2 changed files with 56 additions and 2 deletions

View File

@ -27,8 +27,26 @@ import org.apache.activemq.artemis.utils.uri.URISchema;
import java.net.URI; import java.net.URI;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.regex.Pattern;
public class TCPServerLocatorSchema extends AbstractServerLocatorSchema { public class TCPServerLocatorSchema extends AbstractServerLocatorSchema {
// regex from http://stackoverflow.com/questions/53497/regular-expression-that-matches-valid-ipv6-addresses
private static final Pattern IPV6 = Pattern.compile("(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|" + // 1:2:3:4:5:6:7:8
"([0-9a-fA-F]{1,4}:){1,7}:|" + // 1:: 1:2:3:4:5:6:7::
"([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|" + // 1::8 1:2:3:4:5:6::8 1:2:3:4:5:6::8
"([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|" + // 1::7:8 1:2:3:4:5::7:8 1:2:3:4:5::8
"([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|" + // 1::6:7:8 1:2:3:4::6:7:8 1:2:3:4::8
"([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|" + // 1::5:6:7:8 1:2:3::5:6:7:8 1:2:3::8
"([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|" + // 1::4:5:6:7:8 1:2::4:5:6:7:8 1:2::8
"[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|" + // 1::3:4:5:6:7:8 1::3:4:5:6:7:8 1::8
":((:[0-9a-fA-F]{1,4}){1,7}|:)|" + // ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 ::
"[fF][eE]80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|" + // fe80::7:8%eth0 fe80::7:8%1 (link-local IPv6 addresses with zone index)
"::([fF]{4}(:0{1,4}){0,1}:){0,1}" +
"((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}" +
"(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|" + // ::255.255.255.255 ::ffff:255.255.255.255 ::ffff:0:255.255.255.255 (IPv4-mapped IPv6 addresses and IPv4-translated addresses)
"([0-9a-fA-F]{1,4}:){1,4}:" +
"((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}" +
"(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))"); // 2001:db8:3:4::192.0.2.33 64:ff9b::192.0.2.33 (IPv4-Embedded IPv6 Address)
@Override @Override
public String getSchemaName() { public String getSchemaName() {
@ -64,7 +82,7 @@ public class TCPServerLocatorSchema extends AbstractServerLocatorSchema {
StringBuilder fragment = new StringBuilder(); StringBuilder fragment = new StringBuilder();
for (int i = 1; i < staticConnectors.length; i++) { for (int i = 1; i < staticConnectors.length; i++) {
TransportConfiguration connector = staticConnectors[i]; TransportConfiguration connector = staticConnectors[i];
Map<String, Object> params = connector.getParams(); Map<String, Object> params = escapeIPv6Host(connector.getParams());
URI extraUri = new URI(SchemaConstants.TCP, null, getHost(params), getPort(params), null, createQuery(params, null), null); URI extraUri = new URI(SchemaConstants.TCP, null, getHost(params), getPort(params), null, createQuery(params, null), null);
if (i > 1) { if (i > 1) {
fragment.append(","); fragment.append(",");
@ -72,10 +90,20 @@ public class TCPServerLocatorSchema extends AbstractServerLocatorSchema {
fragment.append(extraUri.toASCIIString()); fragment.append(extraUri.toASCIIString());
} }
Map<String, Object> params = staticConnectors[0].getParams(); Map<String, Object> params = escapeIPv6Host(staticConnectors[0].getParams());
return new URI(SchemaConstants.TCP, null, getHost(params), getPort(params), null, createQuery(params, query), fragment.toString()); return new URI(SchemaConstants.TCP, null, getHost(params), getPort(params), null, createQuery(params, query), fragment.toString());
} }
private static Map<String, Object> escapeIPv6Host(Map<String, Object> params) {
String host = (String) params.get("host");
if (host != null && IPV6.matcher(host).matches()) {
params.put("host", "[" + host + "]");
}
return params;
}
private static int getPort(Map<String, Object> params) { private static int getPort(Map<String, Object> params) {
Object port = params.get("port"); Object port = params.get("port");
if (port instanceof String) { if (port instanceof String) {

View File

@ -18,6 +18,10 @@
package org.apache.activemq.artemis.uri; package org.apache.activemq.artemis.uri;
import java.beans.PropertyDescriptor; import java.beans.PropertyDescriptor;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.net.URI; import java.net.URI;
import java.util.HashMap; import java.util.HashMap;
@ -49,6 +53,28 @@ public class ConnectionFactoryURITest {
ConnectionFactoryParser parser = new ConnectionFactoryParser(); ConnectionFactoryParser parser = new ConnectionFactoryParser();
@Test
public void testIPv6() throws Exception {
String ipv6 = "fe80::baf6:b1ff:fe12:daf7%eth0";
Map<String,Object> params = new HashMap<>();
params.put("host", ipv6);
params.put("port", 5445);
TransportConfiguration transport = new TransportConfiguration(NettyConnectorFactory.class.getName(), params);
ActiveMQConnectionFactory factory = ActiveMQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF, transport);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream outStream = new ObjectOutputStream(baos);
outStream.writeObject(factory);
outStream.close();
baos.close();
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream in = new ObjectInputStream(bais);
factory = (ActiveMQConnectionFactory) in.readObject();
in.close();
bais.close();
Assert.assertEquals("[" + ipv6 + "]", factory.getStaticConnectors()[0].getParams().get("host"));
}
@Test @Test
public void testQUEUE_XA_CF() throws Exception { public void testQUEUE_XA_CF() throws Exception {
ActiveMQConnectionFactory factory = parser.newObject(new URI("tcp://localhost:3030?ha=true&type=QUEUE_XA_CF"), null); ActiveMQConnectionFactory factory = parser.newObject(new URI("tcp://localhost:3030?ha=true&type=QUEUE_XA_CF"), null);