Add workaround for connection problems with IPv6 link-local addresses and jdk < 7. See #267
This commit is contained in:
parent
aa6c16b136
commit
2db3e59a6c
78
common/src/main/java/io/netty/util/internal/SocketUtil.java
Normal file
78
common/src/main/java/io/netty/util/internal/SocketUtil.java
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you under the Apache License,
|
||||
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package io.netty.util.internal;
|
||||
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
public final class SocketUtil {
|
||||
|
||||
|
||||
private static final String ZONE_ID_SEPARATOR = "%";
|
||||
|
||||
|
||||
/**
|
||||
* Takes care of stripping the zone id from the {@link InetAddress} if its an {@link Inet6Address} and the java
|
||||
* version is < 7. After that a new {@link InetSocketAddress} is created based on the old one. This is needed because of a bug that exists in java
|
||||
* versions < 7.
|
||||
*
|
||||
* See https://github.com/netty/netty/issues/267
|
||||
*
|
||||
*/
|
||||
public static InetSocketAddress stripZoneId(InetSocketAddress socketAddress) throws UnknownHostException {
|
||||
return new InetSocketAddress(socketAddress.getAddress(), socketAddress.getPort());
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes care of stripping the zone id from the {@link InetAddress} if its an {@link Inet6Address} and the java
|
||||
* version is < 7. This is needed because of a bug that exists in java versions < 7.
|
||||
*
|
||||
* See https://github.com/netty/netty/issues/267
|
||||
*
|
||||
*/
|
||||
public static InetAddress stripZoneId(InetAddress address) throws UnknownHostException {
|
||||
// If we have a java version which is >= 7 we can just return the given
|
||||
// InetSocketAddress as this bug only seems
|
||||
// to exist in java 6 (and maybe also versions before)
|
||||
if (DetectionUtil.javaVersion() >= 7) {
|
||||
return address;
|
||||
}
|
||||
|
||||
if (address instanceof Inet6Address) {
|
||||
Inet6Address inet6Address = (Inet6Address) address;
|
||||
|
||||
// Check if its a LinkLocalAddress as this is the only one which is
|
||||
// affected
|
||||
if (inet6Address.isLinkLocalAddress()) {
|
||||
String hostaddress = inet6Address.getHostAddress();
|
||||
|
||||
int separator = hostaddress.indexOf(ZONE_ID_SEPARATOR);
|
||||
|
||||
// strip of the zoneId
|
||||
String withoutZonedId = inet6Address.getHostAddress().substring(0, separator);
|
||||
return InetAddress.getByName(withoutZonedId);
|
||||
}
|
||||
}
|
||||
return address;
|
||||
|
||||
}
|
||||
|
||||
private SocketUtil() {
|
||||
|
||||
}
|
||||
}
|
@ -27,7 +27,9 @@ import io.netty.channel.ChannelStateEvent;
|
||||
import io.netty.channel.MessageEvent;
|
||||
import io.netty.logging.InternalLogger;
|
||||
import io.netty.logging.InternalLoggerFactory;
|
||||
import io.netty.util.internal.SocketUtil;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
|
||||
@ -99,6 +101,7 @@ class NioClientSocketPipelineSink extends AbstractNioChannelSink {
|
||||
final NioClientSocketChannel channel, final ChannelFuture cf,
|
||||
SocketAddress remoteAddress) {
|
||||
try {
|
||||
remoteAddress = SocketUtil.stripZoneId((InetSocketAddress) remoteAddress);
|
||||
channel.getJdkChannel().connect(remoteAddress);
|
||||
channel.getCloseFuture().addListener(new ChannelFutureListener() {
|
||||
@Override
|
||||
|
@ -18,6 +18,7 @@ package io.netty.channel.socket.oio;
|
||||
import static io.netty.channel.Channels.*;
|
||||
|
||||
import java.io.PushbackInputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@ -29,6 +30,7 @@ import io.netty.channel.ChannelState;
|
||||
import io.netty.channel.ChannelStateEvent;
|
||||
import io.netty.channel.MessageEvent;
|
||||
import io.netty.util.internal.DeadLockProofWorker;
|
||||
import io.netty.util.internal.SocketUtil;
|
||||
|
||||
class OioClientSocketPipelineSink extends AbstractOioChannelSink {
|
||||
|
||||
@ -102,6 +104,8 @@ class OioClientSocketPipelineSink extends AbstractOioChannelSink {
|
||||
future.addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
|
||||
|
||||
try {
|
||||
remoteAddress = SocketUtil.stripZoneId((InetSocketAddress) remoteAddress);
|
||||
|
||||
channel.socket.connect(
|
||||
remoteAddress, channel.getConfig().getConnectTimeoutMillis());
|
||||
connected = true;
|
||||
|
Loading…
Reference in New Issue
Block a user