Correctly handle IPV6-mapped-IPV4 addresses in native code when receiving datagrams (#9560)
Motivation:
291f80733a
introduced a change to use a byte[] to construct the InetAddress when receiving datagram messages to reduce the overhead. Unfortunally it introduced a regression when handling IPv6-mapped-IPv4 addresses and so produced an IndexOutOfBoundsException when trying to fill the byte[] in native code.
Modifications:
- Correctly use the offset on the pointer of the address.
- Add testcase
- Make tests more robust and include more details when the test fails
Result:
No more IndexOutOfBoundsException
This commit is contained in:
parent
bcb0d02248
commit
7a547aab65
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.testsuite.transport.socket;
|
||||||
|
|
||||||
|
import io.netty.util.NetUtil;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.SocketAddress;
|
||||||
|
|
||||||
|
public class DatagramUnicastIPv6MappedTest extends DatagramUnicastIPv6Test {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SocketAddress newSocketAddress() {
|
||||||
|
return new InetSocketAddress(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected InetSocketAddress sendToAddress(InetSocketAddress serverAddress) {
|
||||||
|
InetAddress addr = serverAddress.getAddress();
|
||||||
|
if (addr.isAnyLocalAddress()) {
|
||||||
|
return new InetSocketAddress(NetUtil.LOCALHOST4, serverAddress.getPort());
|
||||||
|
}
|
||||||
|
return serverAddress;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.testsuite.transport.socket;
|
||||||
|
|
||||||
|
import io.netty.channel.socket.InternetProtocolFamily;
|
||||||
|
import org.junit.Assume;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.StandardProtocolFamily;
|
||||||
|
import java.nio.channels.Channel;
|
||||||
|
import java.nio.channels.spi.SelectorProvider;
|
||||||
|
|
||||||
|
public class DatagramUnicastIPv6Test extends DatagramUnicastTest {
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void assumeIpv6Supported() {
|
||||||
|
try {
|
||||||
|
Channel channel = SelectorProvider.provider().openDatagramChannel(StandardProtocolFamily.INET6);
|
||||||
|
channel.close();
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
Assume.assumeNoException("IPv6 not supported", e);
|
||||||
|
} catch (IOException ignore) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected InternetProtocolFamily internetProtocolFamily() {
|
||||||
|
return InternetProtocolFamily.IPv6;
|
||||||
|
}
|
||||||
|
}
|
@ -27,8 +27,11 @@ import io.netty.channel.ChannelOption;
|
|||||||
import io.netty.channel.SimpleChannelInboundHandler;
|
import io.netty.channel.SimpleChannelInboundHandler;
|
||||||
import io.netty.channel.socket.DatagramChannel;
|
import io.netty.channel.socket.DatagramChannel;
|
||||||
import io.netty.channel.socket.DatagramPacket;
|
import io.netty.channel.socket.DatagramPacket;
|
||||||
|
import io.netty.util.NetUtil;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.net.Inet6Address;
|
||||||
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.nio.channels.NotYetConnectedException;
|
import java.nio.channels.NotYetConnectedException;
|
||||||
@ -36,6 +39,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
@ -171,30 +175,27 @@ public class DatagramUnicastTest extends AbstractDatagramTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final CountDownLatch latch = new CountDownLatch(count);
|
final CountDownLatch latch = new CountDownLatch(count);
|
||||||
sc = setupServerChannel(sb, bytes, sender, latch, false);
|
AtomicReference<Throwable> errorRef = new AtomicReference<Throwable>();
|
||||||
|
sc = setupServerChannel(sb, bytes, sender, latch, errorRef, false);
|
||||||
|
|
||||||
InetSocketAddress addr = (InetSocketAddress) sc.localAddress();
|
InetSocketAddress addr = sendToAddress((InetSocketAddress) sc.localAddress());
|
||||||
|
List<ChannelFuture> futures = new ArrayList<ChannelFuture>(count);
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
switch (wrapType) {
|
futures.add(write(cc, buf, addr, wrapType));
|
||||||
case DUP:
|
|
||||||
cc.write(new DatagramPacket(buf.retainedDuplicate(), addr));
|
|
||||||
break;
|
|
||||||
case SLICE:
|
|
||||||
cc.write(new DatagramPacket(buf.retainedSlice(), addr));
|
|
||||||
break;
|
|
||||||
case READ_ONLY:
|
|
||||||
cc.write(new DatagramPacket(buf.retain().asReadOnly(), addr));
|
|
||||||
break;
|
|
||||||
case NONE:
|
|
||||||
cc.write(new DatagramPacket(buf.retain(), addr));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new Error("unknown wrap type: " + wrapType);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// release as we used buf.retain() before
|
// release as we used buf.retain() before
|
||||||
cc.flush();
|
cc.flush();
|
||||||
assertTrue(latch.await(10, TimeUnit.SECONDS));
|
|
||||||
|
for (ChannelFuture future: futures) {
|
||||||
|
future.sync();
|
||||||
|
}
|
||||||
|
if (!latch.await(10, TimeUnit.SECONDS)) {
|
||||||
|
Throwable error = errorRef.get();
|
||||||
|
if (error != null) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
fail();
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
// release as we used buf.retain() before
|
// release as we used buf.retain() before
|
||||||
buf.release();
|
buf.release();
|
||||||
@ -204,6 +205,20 @@ public class DatagramUnicastTest extends AbstractDatagramTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static ChannelFuture write(Channel cc, ByteBuf buf, InetSocketAddress remote, WrapType wrapType) {
|
||||||
|
switch (wrapType) {
|
||||||
|
case DUP:
|
||||||
|
return cc.write(new DatagramPacket(buf.retainedDuplicate(), remote));
|
||||||
|
case SLICE:
|
||||||
|
return cc.write(new DatagramPacket(buf.retainedSlice(), remote));
|
||||||
|
case READ_ONLY:
|
||||||
|
return cc.write(new DatagramPacket(buf.retain().asReadOnly(), remote));
|
||||||
|
case NONE:
|
||||||
|
return cc.write(new DatagramPacket(buf.retain(), remote));
|
||||||
|
default:
|
||||||
|
throw new Error("unknown wrap type: " + wrapType);
|
||||||
|
}
|
||||||
|
}
|
||||||
private void testSimpleSendWithConnect(Bootstrap sb, Bootstrap cb, ByteBuf buf, final byte[] bytes, int count)
|
private void testSimpleSendWithConnect(Bootstrap sb, Bootstrap cb, ByteBuf buf, final byte[] bytes, int count)
|
||||||
throws Throwable {
|
throws Throwable {
|
||||||
try {
|
try {
|
||||||
@ -218,31 +233,44 @@ public class DatagramUnicastTest extends AbstractDatagramTest {
|
|||||||
private void testSimpleSendWithConnect0(Bootstrap sb, Bootstrap cb, ByteBuf buf, final byte[] bytes, int count,
|
private void testSimpleSendWithConnect0(Bootstrap sb, Bootstrap cb, ByteBuf buf, final byte[] bytes, int count,
|
||||||
WrapType wrapType) throws Throwable {
|
WrapType wrapType) throws Throwable {
|
||||||
final CountDownLatch clientLatch = new CountDownLatch(count);
|
final CountDownLatch clientLatch = new CountDownLatch(count);
|
||||||
|
final AtomicReference<Throwable> clientErrorRef = new AtomicReference<Throwable>();
|
||||||
cb.handler(new SimpleChannelInboundHandler<DatagramPacket>() {
|
cb.handler(new SimpleChannelInboundHandler<DatagramPacket>() {
|
||||||
@Override
|
@Override
|
||||||
public void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
|
public void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
|
||||||
|
try {
|
||||||
ByteBuf buf = msg.content();
|
ByteBuf buf = msg.content();
|
||||||
assertEquals(bytes.length, buf.readableBytes());
|
assertEquals(bytes.length, buf.readableBytes());
|
||||||
for (int i = 0; i < bytes.length; i++) {
|
for (int i = 0; i < bytes.length; i++) {
|
||||||
assertEquals(bytes[i], buf.getByte(buf.readerIndex() + i));
|
assertEquals(bytes[i], buf.getByte(buf.readerIndex() + i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InetSocketAddress localAddress = (InetSocketAddress) ctx.channel().localAddress();
|
||||||
|
if (localAddress.getAddress().isAnyLocalAddress()) {
|
||||||
|
assertEquals(localAddress.getPort(), msg.recipient().getPort());
|
||||||
|
} else {
|
||||||
// Test that the channel's localAddress is equal to the message's recipient
|
// Test that the channel's localAddress is equal to the message's recipient
|
||||||
assertEquals(ctx.channel().localAddress(), msg.recipient());
|
assertEquals(localAddress, msg.recipient());
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
clientLatch.countDown();
|
clientLatch.countDown();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||||
|
clientErrorRef.compareAndSet(null, cause);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Channel sc = null;
|
Channel sc = null;
|
||||||
DatagramChannel cc = null;
|
DatagramChannel cc = null;
|
||||||
try {
|
try {
|
||||||
final CountDownLatch latch = new CountDownLatch(count);
|
final CountDownLatch latch = new CountDownLatch(count);
|
||||||
|
final AtomicReference<Throwable> errorRef = new AtomicReference<Throwable>();
|
||||||
cc = (DatagramChannel) cb.bind(newSocketAddress()).sync().channel();
|
cc = (DatagramChannel) cb.bind(newSocketAddress()).sync().channel();
|
||||||
sc = setupServerChannel(sb, bytes, cc.localAddress(), latch, true);
|
sc = setupServerChannel(sb, bytes, cc.localAddress(), latch, errorRef, true);
|
||||||
|
|
||||||
cc.connect(sc.localAddress()).syncUninterruptibly();
|
cc.connect(sendToAddress((InetSocketAddress) sc.localAddress())).syncUninterruptibly();
|
||||||
|
|
||||||
List<ChannelFuture> futures = new ArrayList<ChannelFuture>();
|
List<ChannelFuture> futures = new ArrayList<ChannelFuture>();
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
@ -254,8 +282,20 @@ public class DatagramUnicastTest extends AbstractDatagramTest {
|
|||||||
future.sync();
|
future.sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
assertTrue(latch.await(10, TimeUnit.SECONDS));
|
if (!latch.await(10, TimeUnit.SECONDS)) {
|
||||||
assertTrue(clientLatch.await(10, TimeUnit.SECONDS));
|
Throwable cause = errorRef.get();
|
||||||
|
if (cause != null) {
|
||||||
|
throw cause;
|
||||||
|
}
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
if (!clientLatch.await(10, TimeUnit.SECONDS)) {
|
||||||
|
Throwable cause = clientErrorRef.get();
|
||||||
|
if (cause != null) {
|
||||||
|
throw cause;
|
||||||
|
}
|
||||||
|
fail();
|
||||||
|
}
|
||||||
assertTrue(cc.isConnected());
|
assertTrue(cc.isConnected());
|
||||||
|
|
||||||
// Test what happens when we call disconnect()
|
// Test what happens when we call disconnect()
|
||||||
@ -292,7 +332,8 @@ public class DatagramUnicastTest extends AbstractDatagramTest {
|
|||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
private Channel setupServerChannel(Bootstrap sb, final byte[] bytes, final SocketAddress sender,
|
private Channel setupServerChannel(Bootstrap sb, final byte[] bytes, final SocketAddress sender,
|
||||||
final CountDownLatch latch, final boolean echo)
|
final CountDownLatch latch, final AtomicReference<Throwable> errorRef,
|
||||||
|
final boolean echo)
|
||||||
throws Throwable {
|
throws Throwable {
|
||||||
sb.handler(new ChannelInitializer<Channel>() {
|
sb.handler(new ChannelInitializer<Channel>() {
|
||||||
@Override
|
@Override
|
||||||
@ -300,11 +341,17 @@ public class DatagramUnicastTest extends AbstractDatagramTest {
|
|||||||
ch.pipeline().addLast(new SimpleChannelInboundHandler<DatagramPacket>() {
|
ch.pipeline().addLast(new SimpleChannelInboundHandler<DatagramPacket>() {
|
||||||
@Override
|
@Override
|
||||||
public void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
|
public void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
|
||||||
|
try {
|
||||||
if (sender == null) {
|
if (sender == null) {
|
||||||
assertNotNull(msg.sender());
|
assertNotNull(msg.sender());
|
||||||
|
} else {
|
||||||
|
InetSocketAddress senderAddress = (InetSocketAddress) sender;
|
||||||
|
if (senderAddress.getAddress().isAnyLocalAddress()) {
|
||||||
|
assertEquals(senderAddress.getPort(), msg.sender().getPort());
|
||||||
} else {
|
} else {
|
||||||
assertEquals(sender, msg.sender());
|
assertEquals(sender, msg.sender());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ByteBuf buf = msg.content();
|
ByteBuf buf = msg.content();
|
||||||
assertEquals(bytes.length, buf.readableBytes());
|
assertEquals(bytes.length, buf.readableBytes());
|
||||||
@ -318,8 +365,15 @@ public class DatagramUnicastTest extends AbstractDatagramTest {
|
|||||||
if (echo) {
|
if (echo) {
|
||||||
ctx.writeAndFlush(new DatagramPacket(buf.retainedDuplicate(), msg.sender()));
|
ctx.writeAndFlush(new DatagramPacket(buf.retainedDuplicate(), msg.sender()));
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
||||||
|
errorRef.compareAndSet(null, cause);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -331,4 +385,15 @@ public class DatagramUnicastTest extends AbstractDatagramTest {
|
|||||||
channel.close().sync();
|
channel.close().sync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected InetSocketAddress sendToAddress(InetSocketAddress serverAddress) {
|
||||||
|
InetAddress addr = serverAddress.getAddress();
|
||||||
|
if (addr.isAnyLocalAddress()) {
|
||||||
|
if (addr instanceof Inet6Address) {
|
||||||
|
return new InetSocketAddress(NetUtil.LOCALHOST6, serverAddress.getPort());
|
||||||
|
}
|
||||||
|
return new InetSocketAddress(NetUtil.LOCALHOST4, serverAddress.getPort());
|
||||||
|
}
|
||||||
|
return serverAddress;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.channel.epoll;
|
||||||
|
|
||||||
|
import io.netty.bootstrap.Bootstrap;
|
||||||
|
import io.netty.testsuite.transport.TestsuitePermutation.BootstrapComboFactory;
|
||||||
|
import io.netty.testsuite.transport.socket.DatagramUnicastIPv6MappedTest;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class EpollDatagramUnicastIPv6MappedTest extends DatagramUnicastIPv6MappedTest {
|
||||||
|
@Override
|
||||||
|
protected List<BootstrapComboFactory<Bootstrap, Bootstrap>> newFactories() {
|
||||||
|
return EpollSocketTestPermutation.INSTANCE.datagram(internetProtocolFamily());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.channel.epoll;
|
||||||
|
|
||||||
|
import io.netty.bootstrap.Bootstrap;
|
||||||
|
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||||
|
import io.netty.testsuite.transport.socket.DatagramUnicastIPv6Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class EpollDatagramUnicastIPv6Test extends DatagramUnicastIPv6Test {
|
||||||
|
@Override
|
||||||
|
protected List<TestsuitePermutation.BootstrapComboFactory<Bootstrap, Bootstrap>> newFactories() {
|
||||||
|
return EpollSocketTestPermutation.INSTANCE.datagram(internetProtocolFamily());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.channel.kqueue;
|
||||||
|
|
||||||
|
import io.netty.bootstrap.Bootstrap;
|
||||||
|
import io.netty.testsuite.transport.TestsuitePermutation.BootstrapComboFactory;
|
||||||
|
import io.netty.testsuite.transport.socket.DatagramUnicastIPv6MappedTest;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class KQueueDatagramUnicastIPv6MappedTest extends DatagramUnicastIPv6MappedTest {
|
||||||
|
@Override
|
||||||
|
protected List<BootstrapComboFactory<Bootstrap, Bootstrap>> newFactories() {
|
||||||
|
return KQueueSocketTestPermutation.INSTANCE.datagram(internetProtocolFamily());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.channel.kqueue;
|
||||||
|
|
||||||
|
import io.netty.bootstrap.Bootstrap;
|
||||||
|
import io.netty.channel.socket.InternetProtocolFamily;
|
||||||
|
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||||
|
import io.netty.testsuite.transport.socket.DatagramUnicastIPv6Test;
|
||||||
|
import io.netty.testsuite.transport.socket.DatagramUnicastTest;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class KQueueDatagramUnicastIPv6Test extends DatagramUnicastIPv6Test {
|
||||||
|
@Override
|
||||||
|
protected List<TestsuitePermutation.BootstrapComboFactory<Bootstrap, Bootstrap>> newFactories() {
|
||||||
|
return KQueueSocketTestPermutation.INSTANCE.datagram(internetProtocolFamily());
|
||||||
|
}
|
||||||
|
}
|
@ -103,7 +103,8 @@ static jobject createDatagramSocketAddress(JNIEnv* env, const struct sockaddr_st
|
|||||||
} else {
|
} else {
|
||||||
offset = 0;
|
offset = 0;
|
||||||
}
|
}
|
||||||
(*env)->SetByteArrayRegion(env, addressBytes, offset, ipLength, (jbyte*) &s->sin6_addr.s6_addr);
|
jbyte* addr = (jbyte*) &s->sin6_addr.s6_addr;
|
||||||
|
(*env)->SetByteArrayRegion(env, addressBytes, 0, ipLength, addr + offset);
|
||||||
}
|
}
|
||||||
jobject obj = (*env)->NewObject(env, datagramSocketAddressClass, datagramSocketAddrMethodId, addressBytes, scopeId, port, len, local);
|
jobject obj = (*env)->NewObject(env, datagramSocketAddressClass, datagramSocketAddrMethodId, addressBytes, scopeId, port, len, local);
|
||||||
if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
|
if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
|
||||||
|
Loading…
Reference in New Issue
Block a user