add epoll native
This commit is contained in:
parent
49b6c772a5
commit
3d532a821f
180 changed files with 19923 additions and 9 deletions
|
@ -25,6 +25,7 @@ The following changes were performed on the original source code:
|
|||
- removed all macos related code (including kqueue)
|
||||
- removed all aarch64 related code
|
||||
- removed the direct brotli4j dependency by rewriting Brotli4jOptions to not use Encoder.Parameters
|
||||
- removed deprecated channel-udt (transport-udt)
|
||||
|
||||
Challenges for Netty build on JDK 21
|
||||
|
||||
|
|
|
@ -10,13 +10,11 @@ dependencies {
|
|||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
failFast = true
|
||||
failFast = false
|
||||
testLogging {
|
||||
events 'STARTED', 'PASSED', 'FAILED', 'SKIPPED'
|
||||
showStandardStreams = true
|
||||
}
|
||||
minHeapSize = "1g" // initial heap size
|
||||
maxHeapSize = "2g" // maximum heap size
|
||||
jvmArgs '--add-exports=java.base/jdk.internal=ALL-UNNAMED',
|
||||
'--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED',
|
||||
'--add-exports=java.base/sun.nio.ch=ALL-UNNAMED',
|
||||
|
@ -30,11 +28,6 @@ test {
|
|||
'--add-opens=jdk.unsupported/sun.misc=ALL-UNNAMED',
|
||||
'-Dio.netty.bootstrap.extensions=serviceload'
|
||||
systemProperty 'java.util.logging.config.file', 'src/test/resources/logging.properties'
|
||||
// we have remove native images, this is no longer used
|
||||
systemProperty "nativeImage.handlerMetadataGroupId", "io.netty"
|
||||
// we have remove native images
|
||||
// we have remove native images, this is no longer used
|
||||
systemProperty "nativeimage.handlerMetadataArtifactId", "netty-transport"
|
||||
afterSuite { desc, result ->
|
||||
if (!desc.parent) {
|
||||
println "\nTest result: ${result.resultType}"
|
||||
|
|
82
netty-channel-epoll-native/build.gradle
Normal file
82
netty-channel-epoll-native/build.gradle
Normal file
|
@ -0,0 +1,82 @@
|
|||
|
||||
apply plugin: 'com.google.osdetector'
|
||||
|
||||
dependencies {
|
||||
testImplementation project(':netty-channel-unix')
|
||||
testImplementation project(':netty-channel-epoll')
|
||||
testImplementation project(':netty-testsuite')
|
||||
testImplementation project(':netty-handler')
|
||||
testImplementation testLibs.assertj
|
||||
testImplementation testLibs.rerunner.jupiter
|
||||
testRuntimeOnly project(path: ':netty-tcnative-boringssl-static', configuration: osdetector.classifier)
|
||||
}
|
||||
|
||||
task nettyEpollLinuxX8664(type: Jar) {
|
||||
archiveBaseName.set('netty-channel-epoll-native')
|
||||
archiveClassifier.set('linux-x86_64')
|
||||
version rootProject.version
|
||||
from (sourceSets.main.output) {
|
||||
include 'META-INF/native/libnetty_transport_native_epoll_x86_64.so'
|
||||
}
|
||||
}
|
||||
assemble.dependsOn(nettyEpollLinuxX8664)
|
||||
|
||||
configurations {
|
||||
'linux-x86_64' {
|
||||
canBeConsumed = true
|
||||
canBeResolved = false
|
||||
extendsFrom runtimeOnly
|
||||
}
|
||||
}
|
||||
|
||||
artifacts {
|
||||
'linux-x86_64'(nettyEpollLinuxX8664)
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
publishNettyEpollLinuxX8664(MavenPublication) {
|
||||
groupId rootProject.group
|
||||
artifactId project.name
|
||||
version rootProject.version
|
||||
artifact nettyEpollLinuxX8664
|
||||
pom {
|
||||
artifactId = project.name
|
||||
name = project.name
|
||||
version = project.version
|
||||
description = rootProject.ext.description
|
||||
url = rootProject.ext.url
|
||||
inceptionYear = rootProject.ext.inceptionYear
|
||||
packaging = 'jar'
|
||||
organization {
|
||||
name = rootProject.ext.organizationName
|
||||
url = rootProject.ext.organizationUrl
|
||||
}
|
||||
developers {
|
||||
developer {
|
||||
id = 'jprante'
|
||||
name = 'Jörg Prante'
|
||||
email = 'joergprante@gmail.com'
|
||||
url = 'https://xbib.org/joerg'
|
||||
}
|
||||
}
|
||||
scm {
|
||||
url = rootProject.ext.scmUrl
|
||||
connection = rootProject.ext.scmConnection
|
||||
developerConnection = rootProject.ext.scmDeveloperConnection
|
||||
}
|
||||
issueManagement {
|
||||
system = rootProject.ext.issueManagementSystem
|
||||
url = rootProject.ext.issueManagementUrl
|
||||
}
|
||||
licenses {
|
||||
license {
|
||||
name = rootProject.ext.licenseName
|
||||
url = rootProject.ext.licenseUrl
|
||||
distribution = 'repo'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
* Copyright 2017 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.FixedRecvByteBufAllocator;
|
||||
import io.netty.channel.ServerChannel;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.Timeout;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public abstract class DetectPeerCloseWithoutReadTest {
|
||||
protected abstract EventLoopGroup newGroup();
|
||||
protected abstract Class<? extends ServerChannel> serverChannel();
|
||||
protected abstract Class<? extends Channel> clientChannel();
|
||||
|
||||
@Test
|
||||
@Timeout(value = 10000, unit = TimeUnit.MILLISECONDS)
|
||||
public void clientCloseWithoutServerReadIsDetectedNoExtraReadRequested() throws InterruptedException {
|
||||
clientCloseWithoutServerReadIsDetected0(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Timeout(value = 10000, unit = TimeUnit.MILLISECONDS)
|
||||
public void clientCloseWithoutServerReadIsDetectedExtraReadRequested() throws InterruptedException {
|
||||
clientCloseWithoutServerReadIsDetected0(true);
|
||||
}
|
||||
|
||||
private void clientCloseWithoutServerReadIsDetected0(final boolean extraReadRequested)
|
||||
throws InterruptedException {
|
||||
EventLoopGroup serverGroup = null;
|
||||
EventLoopGroup clientGroup = null;
|
||||
Channel serverChannel = null;
|
||||
try {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
final AtomicInteger bytesRead = new AtomicInteger();
|
||||
final int expectedBytes = 100;
|
||||
serverGroup = newGroup();
|
||||
clientGroup = newGroup();
|
||||
ServerBootstrap sb = new ServerBootstrap();
|
||||
sb.group(serverGroup);
|
||||
sb.channel(serverChannel());
|
||||
// Ensure we read only one message per read() call and that we need multiple read()
|
||||
// calls to consume everything.
|
||||
sb.childOption(ChannelOption.AUTO_READ, false);
|
||||
sb.childOption(ChannelOption.MAX_MESSAGES_PER_READ, 1);
|
||||
sb.childOption(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(expectedBytes / 10));
|
||||
sb.childHandler(new ChannelInitializer<Channel>() {
|
||||
@Override
|
||||
protected void initChannel(Channel ch) {
|
||||
ch.pipeline().addLast(new TestHandler(bytesRead, extraReadRequested, latch));
|
||||
}
|
||||
});
|
||||
|
||||
serverChannel = sb.bind(new InetSocketAddress(0)).syncUninterruptibly().channel();
|
||||
|
||||
Bootstrap cb = new Bootstrap();
|
||||
cb.group(serverGroup);
|
||||
cb.channel(clientChannel());
|
||||
cb.handler(new ChannelInboundHandlerAdapter());
|
||||
Channel clientChannel = cb.connect(serverChannel.localAddress()).syncUninterruptibly().channel();
|
||||
ByteBuf buf = clientChannel.alloc().buffer(expectedBytes);
|
||||
buf.writerIndex(buf.writerIndex() + expectedBytes);
|
||||
clientChannel.writeAndFlush(buf).addListener(ChannelFutureListener.CLOSE);
|
||||
|
||||
latch.await();
|
||||
assertEquals(expectedBytes, bytesRead.get());
|
||||
} finally {
|
||||
if (serverChannel != null) {
|
||||
serverChannel.close().syncUninterruptibly();
|
||||
}
|
||||
if (serverGroup != null) {
|
||||
serverGroup.shutdownGracefully();
|
||||
}
|
||||
if (clientGroup != null) {
|
||||
clientGroup.shutdownGracefully();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Timeout(value = 10000, unit = TimeUnit.MILLISECONDS)
|
||||
public void serverCloseWithoutClientReadIsDetectedNoExtraReadRequested() throws InterruptedException {
|
||||
serverCloseWithoutClientReadIsDetected0(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Timeout(value = 10000, unit = TimeUnit.MILLISECONDS)
|
||||
public void serverCloseWithoutClientReadIsDetectedExtraReadRequested() throws InterruptedException {
|
||||
serverCloseWithoutClientReadIsDetected0(true);
|
||||
}
|
||||
|
||||
private void serverCloseWithoutClientReadIsDetected0(final boolean extraReadRequested) throws InterruptedException {
|
||||
EventLoopGroup serverGroup = null;
|
||||
EventLoopGroup clientGroup = null;
|
||||
Channel serverChannel = null;
|
||||
Channel clientChannel = null;
|
||||
try {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
final AtomicInteger bytesRead = new AtomicInteger();
|
||||
final int expectedBytes = 100;
|
||||
serverGroup = newGroup();
|
||||
clientGroup = newGroup();
|
||||
ServerBootstrap sb = new ServerBootstrap();
|
||||
sb.group(serverGroup);
|
||||
sb.channel(serverChannel());
|
||||
sb.childHandler(new ChannelInitializer<Channel>() {
|
||||
@Override
|
||||
protected void initChannel(Channel ch) {
|
||||
ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
|
||||
@Override
|
||||
public void channelActive(ChannelHandlerContext ctx) {
|
||||
ByteBuf buf = ctx.alloc().buffer(expectedBytes);
|
||||
buf.writerIndex(buf.writerIndex() + expectedBytes);
|
||||
ctx.writeAndFlush(buf).addListener(ChannelFutureListener.CLOSE);
|
||||
ctx.fireChannelActive();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
serverChannel = sb.bind(new InetSocketAddress(0)).syncUninterruptibly().channel();
|
||||
|
||||
Bootstrap cb = new Bootstrap();
|
||||
cb.group(serverGroup);
|
||||
cb.channel(clientChannel());
|
||||
// Ensure we read only one message per read() call and that we need multiple read()
|
||||
// calls to consume everything.
|
||||
cb.option(ChannelOption.AUTO_READ, false);
|
||||
cb.option(ChannelOption.MAX_MESSAGES_PER_READ, 1);
|
||||
cb.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(expectedBytes / 10));
|
||||
cb.handler(new ChannelInitializer<Channel>() {
|
||||
@Override
|
||||
protected void initChannel(Channel ch) throws Exception {
|
||||
ch.pipeline().addLast(new TestHandler(bytesRead, extraReadRequested, latch));
|
||||
}
|
||||
});
|
||||
clientChannel = cb.connect(serverChannel.localAddress()).syncUninterruptibly().channel();
|
||||
|
||||
latch.await();
|
||||
assertEquals(expectedBytes, bytesRead.get());
|
||||
} finally {
|
||||
if (serverChannel != null) {
|
||||
serverChannel.close().syncUninterruptibly();
|
||||
}
|
||||
if (clientChannel != null) {
|
||||
clientChannel.close().syncUninterruptibly();
|
||||
}
|
||||
if (serverGroup != null) {
|
||||
serverGroup.shutdownGracefully();
|
||||
}
|
||||
if (clientGroup != null) {
|
||||
clientGroup.shutdownGracefully();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class TestHandler extends SimpleChannelInboundHandler<ByteBuf> {
|
||||
private final AtomicInteger bytesRead;
|
||||
private final boolean extraReadRequested;
|
||||
private final CountDownLatch latch;
|
||||
|
||||
TestHandler(AtomicInteger bytesRead, boolean extraReadRequested, CountDownLatch latch) {
|
||||
this.bytesRead = bytesRead;
|
||||
this.extraReadRequested = extraReadRequested;
|
||||
this.latch = latch;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) {
|
||||
bytesRead.addAndGet(msg.readableBytes());
|
||||
|
||||
if (extraReadRequested) {
|
||||
// Because autoread is off, we call read to consume all data until we detect the close.
|
||||
ctx.read();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelInactive(ChannelHandlerContext ctx) {
|
||||
latch.countDown();
|
||||
ctx.fireChannelInactive();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright 2015 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:
|
||||
*
|
||||
* https://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.channel.unix.DomainSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.UUID;
|
||||
|
||||
public class EpollAbstractDomainSocketEchoTest extends EpollDomainSocketEchoTest {
|
||||
@Override
|
||||
protected SocketAddress newSocketAddress() {
|
||||
// these don't actually show up in the file system so creating a temp file isn't reliable
|
||||
return new DomainSocketAddress("\0" + System.getProperty("java.io.tmpdir") + UUID.randomUUID());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright 2015 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:
|
||||
*
|
||||
* https://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.channel.ChannelException;
|
||||
|
||||
import io.netty.channel.unix.Buffer;
|
||||
import io.netty.channel.unix.IntegerUnixChannelOption;
|
||||
import io.netty.channel.unix.RawUnixChannelOption;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
public class EpollChannelConfigTest {
|
||||
|
||||
@Test
|
||||
public void testOptionGetThrowsChannelException() throws Exception {
|
||||
Epoll.ensureAvailability();
|
||||
EpollSocketChannel channel = new EpollSocketChannel();
|
||||
channel.config().getSoLinger();
|
||||
channel.fd().close();
|
||||
try {
|
||||
channel.config().getSoLinger();
|
||||
fail();
|
||||
} catch (ChannelException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOptionSetThrowsChannelException() throws Exception {
|
||||
Epoll.ensureAvailability();
|
||||
EpollSocketChannel channel = new EpollSocketChannel();
|
||||
channel.config().setKeepAlive(true);
|
||||
channel.fd().close();
|
||||
try {
|
||||
channel.config().setKeepAlive(true);
|
||||
fail();
|
||||
} catch (ChannelException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntegerOption() throws Exception {
|
||||
Epoll.ensureAvailability();
|
||||
EpollSocketChannel channel = new EpollSocketChannel();
|
||||
IntegerUnixChannelOption opt = new IntegerUnixChannelOption("INT_OPT", 1, 2);
|
||||
Integer zero = 0;
|
||||
assertEquals(zero, channel.config().getOption(opt));
|
||||
channel.config().setOption(opt, 1);
|
||||
assertNotEquals(zero, channel.config().getOption(opt));
|
||||
channel.fd().close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRawOption() throws Exception {
|
||||
Epoll.ensureAvailability();
|
||||
EpollSocketChannel channel = new EpollSocketChannel();
|
||||
// Value for SOL_SOCKET and SO_REUSEADDR
|
||||
// See https://github.com/torvalds/linux/blob/v5.17/include/uapi/asm-generic/socket.h
|
||||
RawUnixChannelOption opt = new RawUnixChannelOption("RAW_OPT", 1, 2, 4);
|
||||
|
||||
ByteBuffer disabled = Buffer.allocateDirectWithNativeOrder(4);
|
||||
disabled.putInt(0).flip();
|
||||
assertEquals(disabled, channel.config().getOption(opt));
|
||||
|
||||
ByteBuffer enabled = Buffer.allocateDirectWithNativeOrder(4);
|
||||
enabled.putInt(1).flip();
|
||||
|
||||
channel.config().setOption(opt, enabled);
|
||||
assertNotEquals(disabled, channel.config().getOption(opt));
|
||||
channel.fd().close();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2017 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.ChannelConfig;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.CompositeBufferGatheringWriteTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollCompositeBufferGatheringWriteTest extends CompositeBufferGatheringWriteTest {
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.socketWithoutFastOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compositeBufferPartialWriteDoesNotCorruptDataInitServerConfig(ChannelConfig config,
|
||||
int soSndBuf) {
|
||||
if (config instanceof EpollChannelConfig) {
|
||||
((EpollChannelConfig) config).setMaxBytesPerGatheringWrite(soSndBuf);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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:
|
||||
*
|
||||
* https://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 org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class EpollDatagramChannelConfigTest {
|
||||
|
||||
@Test
|
||||
public void testIpFreeBind() throws Exception {
|
||||
Epoll.ensureAvailability();
|
||||
EpollDatagramChannel channel = new EpollDatagramChannel();
|
||||
assertTrue(channel.config().setOption(EpollChannelOption.IP_FREEBIND, true));
|
||||
assertTrue(channel.config().getOption(EpollChannelOption.IP_FREEBIND));
|
||||
channel.fd().close();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* 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:
|
||||
*
|
||||
* https://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.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.socket.InternetProtocolFamily;
|
||||
import io.netty.channel.unix.Socket;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
|
||||
import static io.netty.util.NetUtil.LOCALHOST;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class EpollDatagramChannelTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
Epoll.ensureAvailability();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultMaxMessagePerRead() {
|
||||
EpollDatagramChannel channel = new EpollDatagramChannel();
|
||||
assertEquals(16, channel.config().getMaxMessagesPerRead());
|
||||
channel.unsafe().closeForcibly();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotActiveNoLocalRemoteAddress() throws IOException {
|
||||
checkNotActiveNoLocalRemoteAddress(new EpollDatagramChannel());
|
||||
checkNotActiveNoLocalRemoteAddress(new EpollDatagramChannel(InternetProtocolFamily.IPv4));
|
||||
checkNotActiveNoLocalRemoteAddress(new EpollDatagramChannel(InternetProtocolFamily.IPv6));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActiveHasLocalAddress() throws IOException {
|
||||
Socket socket = Socket.newSocketDgram();
|
||||
EpollDatagramChannel channel = new EpollDatagramChannel(socket.intValue());
|
||||
InetSocketAddress localAddress = channel.localAddress();
|
||||
assertTrue(channel.active);
|
||||
assertNotNull(localAddress);
|
||||
assertEquals(socket.localAddress(), localAddress);
|
||||
channel.fd().close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalAddressBeforeAndAfterBind() {
|
||||
EventLoopGroup group = new EpollEventLoopGroup(1);
|
||||
try {
|
||||
TestHandler handler = new TestHandler();
|
||||
InetSocketAddress localAddressBeforeBind = new InetSocketAddress(LOCALHOST, 0);
|
||||
|
||||
Bootstrap bootstrap = new Bootstrap();
|
||||
bootstrap.group(group)
|
||||
.channel(EpollDatagramChannel.class)
|
||||
.localAddress(localAddressBeforeBind)
|
||||
.handler(handler);
|
||||
|
||||
ChannelFuture future = bootstrap.bind().syncUninterruptibly();
|
||||
|
||||
assertNull(handler.localAddress);
|
||||
|
||||
SocketAddress localAddressAfterBind = future.channel().localAddress();
|
||||
assertNotNull(localAddressAfterBind);
|
||||
assertTrue(localAddressAfterBind instanceof InetSocketAddress);
|
||||
assertTrue(((InetSocketAddress) localAddressAfterBind).getPort() != 0);
|
||||
|
||||
future.channel().close().syncUninterruptibly();
|
||||
} finally {
|
||||
group.shutdownGracefully();
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkNotActiveNoLocalRemoteAddress(EpollDatagramChannel channel) throws IOException {
|
||||
assertFalse(channel.active);
|
||||
assertNull(channel.localAddress());
|
||||
assertNull(channel.remoteAddress());
|
||||
channel.fd().close();
|
||||
}
|
||||
|
||||
private static final class TestHandler extends ChannelInboundHandlerAdapter {
|
||||
private volatile SocketAddress localAddress;
|
||||
|
||||
@Override
|
||||
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
|
||||
this.localAddress = ctx.channel().localAddress();
|
||||
super.channelRegistered(ctx);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright 2017 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:
|
||||
*
|
||||
* https://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.DatagramConnectNotExistsTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollDatagramConnectNotExistsTest extends DatagramConnectNotExistsTest {
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapFactory<Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.datagramSocket();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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:
|
||||
*
|
||||
* https://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.DatagramMulticastIPv6Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollDatagramMulticastIPv6Test extends DatagramMulticastIPv6Test {
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<Bootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.datagram(internetProtocolFamily());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright 2021 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:
|
||||
*
|
||||
* https://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.channel.socket.InternetProtocolFamily;
|
||||
import io.netty.testsuite.transport.socket.DatagramMulticastTest;
|
||||
|
||||
public class EpollDatagramMulticastIpv6WithIpv4AddrTest extends DatagramMulticastTest {
|
||||
|
||||
@Override
|
||||
protected InternetProtocolFamily groupInternetProtocalFamily() {
|
||||
return InternetProtocolFamily.IPv4;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InternetProtocolFamily socketInternetProtocalFamily() {
|
||||
return InternetProtocolFamily.IPv6;
|
||||
}
|
||||
}
|
|
@ -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:
|
||||
*
|
||||
* https://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.DatagramMulticastTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollDatagramMulticastTest extends DatagramMulticastTest {
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<Bootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.datagram(internetProtocolFamily());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,307 @@
|
|||
/*
|
||||
* 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:
|
||||
*
|
||||
* https://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.channel.AdaptiveRecvByteBufAllocator;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.channel.socket.DatagramPacket;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.AbstractDatagramTest;
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInfo;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
||||
|
||||
public class EpollDatagramScatteringReadTest extends AbstractDatagramTest {
|
||||
|
||||
@BeforeAll
|
||||
public static void assumeRecvmmsgSupported() {
|
||||
assumeTrue(Native.IS_SUPPORTING_RECVMMSG);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<Bootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.epollOnlyDatagram(internetProtocolFamily());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScatteringReadPartial(TestInfo testInfo) throws Throwable {
|
||||
run(testInfo, new Runner<Bootstrap, Bootstrap>() {
|
||||
@Override
|
||||
public void run(Bootstrap bootstrap, Bootstrap bootstrap2) throws Throwable {
|
||||
testScatteringReadPartial(bootstrap, bootstrap2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testScatteringReadPartial(Bootstrap sb, Bootstrap cb) throws Throwable {
|
||||
testScatteringRead(sb, cb, false, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScatteringRead(TestInfo testInfo) throws Throwable {
|
||||
run(testInfo, new Runner<Bootstrap, Bootstrap>() {
|
||||
@Override
|
||||
public void run(Bootstrap bootstrap, Bootstrap bootstrap2) throws Throwable {
|
||||
testScatteringRead(bootstrap, bootstrap2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testScatteringRead(Bootstrap sb, Bootstrap cb) throws Throwable {
|
||||
testScatteringRead(sb, cb, false, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScatteringReadConnectedPartial(TestInfo testInfo) throws Throwable {
|
||||
run(testInfo, new Runner<Bootstrap, Bootstrap>() {
|
||||
@Override
|
||||
public void run(Bootstrap bootstrap, Bootstrap bootstrap2) throws Throwable {
|
||||
testScatteringReadConnectedPartial(bootstrap, bootstrap2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testScatteringReadConnectedPartial(Bootstrap sb, Bootstrap cb) throws Throwable {
|
||||
testScatteringRead(sb, cb, true, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScatteringConnectedRead(TestInfo testInfo) throws Throwable {
|
||||
run(testInfo, new Runner<Bootstrap, Bootstrap>() {
|
||||
@Override
|
||||
public void run(Bootstrap bootstrap, Bootstrap bootstrap2) throws Throwable {
|
||||
testScatteringConnectedRead(bootstrap, bootstrap2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testScatteringConnectedRead(Bootstrap sb, Bootstrap cb) throws Throwable {
|
||||
testScatteringRead(sb, cb, true, false);
|
||||
}
|
||||
|
||||
private void testScatteringRead(Bootstrap sb, Bootstrap cb, boolean connected, boolean partial) throws Throwable {
|
||||
int packetSize = 8;
|
||||
int numPackets = 4;
|
||||
|
||||
sb.option(ChannelOption.RCVBUF_ALLOCATOR, new AdaptiveRecvByteBufAllocator(
|
||||
packetSize, packetSize * (partial ? numPackets / 2 : numPackets), 64 * 1024));
|
||||
// Set the MAX_DATAGRAM_PAYLOAD_SIZE to something bigger then the actual packet size.
|
||||
// This will allow us to check if we correctly thread the received len.
|
||||
sb.option(EpollChannelOption.MAX_DATAGRAM_PAYLOAD_SIZE, packetSize * 2);
|
||||
|
||||
Channel sc = null;
|
||||
Channel cc = null;
|
||||
|
||||
try {
|
||||
cb.handler(new SimpleChannelInboundHandler<Object>() {
|
||||
@Override
|
||||
public void channelRead0(ChannelHandlerContext ctx, Object msgs) throws Exception {
|
||||
// Nothing will be sent.
|
||||
}
|
||||
});
|
||||
cc = cb.bind(newSocketAddress()).sync().channel();
|
||||
final SocketAddress ccAddress = cc.localAddress();
|
||||
|
||||
final AtomicReference<Throwable> errorRef = new AtomicReference<Throwable>();
|
||||
|
||||
final CountDownLatch latch = new CountDownLatch(numPackets);
|
||||
sb.handler(new SimpleChannelInboundHandler<DatagramPacket>() {
|
||||
private long numRead;
|
||||
private int counter;
|
||||
@Override
|
||||
public void channelReadComplete(ChannelHandlerContext ctx) {
|
||||
assertTrue(counter > 1);
|
||||
counter = 0;
|
||||
ctx.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) {
|
||||
assertEquals(ccAddress, msg.sender());
|
||||
|
||||
// Each packet contains a long which represent the write iteration.
|
||||
assertEquals(8, msg.content().readableBytes());
|
||||
assertEquals(numRead, msg.content().readLong());
|
||||
numRead++;
|
||||
counter++;
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
||||
errorRef.compareAndSet(null, cause);
|
||||
}
|
||||
});
|
||||
|
||||
sb.option(ChannelOption.AUTO_READ, false);
|
||||
sc = sb.bind(newSocketAddress()).sync().channel();
|
||||
|
||||
if (connected) {
|
||||
sc.connect(cc.localAddress()).syncUninterruptibly();
|
||||
}
|
||||
|
||||
InetSocketAddress addr = (InetSocketAddress) sc.localAddress();
|
||||
|
||||
List<ChannelFuture> futures = new ArrayList<ChannelFuture>(numPackets);
|
||||
for (int i = 0; i < numPackets; i++) {
|
||||
futures.add(cc.write(new DatagramPacket(cc.alloc().directBuffer().writeLong(i), addr)));
|
||||
}
|
||||
|
||||
cc.flush();
|
||||
|
||||
for (ChannelFuture f: futures) {
|
||||
f.sync();
|
||||
}
|
||||
|
||||
// Enable autoread now which also triggers a read, this should cause scattering reads (recvmmsg) to happen.
|
||||
sc.config().setAutoRead(true);
|
||||
|
||||
if (!latch.await(10, TimeUnit.SECONDS)) {
|
||||
Throwable error = errorRef.get();
|
||||
if (error != null) {
|
||||
throw error;
|
||||
}
|
||||
fail("Timeout while waiting for packets");
|
||||
}
|
||||
} finally {
|
||||
if (cc != null) {
|
||||
cc.close().syncUninterruptibly();
|
||||
}
|
||||
if (sc != null) {
|
||||
sc.close().syncUninterruptibly();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScatteringReadWithSmallBuffer(TestInfo testInfo) throws Throwable {
|
||||
run(testInfo, new Runner<Bootstrap, Bootstrap>() {
|
||||
@Override
|
||||
public void run(Bootstrap bootstrap, Bootstrap bootstrap2) throws Throwable {
|
||||
testScatteringReadWithSmallBuffer(bootstrap, bootstrap2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testScatteringReadWithSmallBuffer(Bootstrap sb, Bootstrap cb) throws Throwable {
|
||||
testScatteringReadWithSmallBuffer0(sb, cb, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScatteringConnectedReadWithSmallBuffer(TestInfo testInfo) throws Throwable {
|
||||
run(testInfo, new Runner<Bootstrap, Bootstrap>() {
|
||||
@Override
|
||||
public void run(Bootstrap bootstrap, Bootstrap bootstrap2) throws Throwable {
|
||||
testScatteringConnectedReadWithSmallBuffer(bootstrap, bootstrap2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testScatteringConnectedReadWithSmallBuffer(Bootstrap sb, Bootstrap cb) throws Throwable {
|
||||
testScatteringReadWithSmallBuffer0(sb, cb, true);
|
||||
}
|
||||
|
||||
private void testScatteringReadWithSmallBuffer0(Bootstrap sb, Bootstrap cb, boolean connected) throws Throwable {
|
||||
int packetSize = 16;
|
||||
|
||||
sb.option(ChannelOption.RCVBUF_ALLOCATOR, new AdaptiveRecvByteBufAllocator(1400, 1400, 64 * 1024));
|
||||
sb.option(EpollChannelOption.MAX_DATAGRAM_PAYLOAD_SIZE, 1400);
|
||||
|
||||
Channel sc = null;
|
||||
Channel cc = null;
|
||||
|
||||
try {
|
||||
cb.handler(new SimpleChannelInboundHandler<Object>() {
|
||||
@Override
|
||||
public void channelRead0(ChannelHandlerContext ctx, Object msgs) {
|
||||
// Nothing will be sent.
|
||||
}
|
||||
});
|
||||
cc = cb.bind(newSocketAddress()).sync().channel();
|
||||
final SocketAddress ccAddress = cc.localAddress();
|
||||
|
||||
final AtomicReference<Throwable> errorRef = new AtomicReference<Throwable>();
|
||||
final byte[] bytes = new byte[packetSize];
|
||||
PlatformDependent.threadLocalRandom().nextBytes(bytes);
|
||||
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
sb.handler(new SimpleChannelInboundHandler<DatagramPacket>() {
|
||||
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) {
|
||||
assertEquals(ccAddress, msg.sender());
|
||||
|
||||
assertEquals(bytes.length, msg.content().readableBytes());
|
||||
byte[] receivedBytes = new byte[bytes.length];
|
||||
msg.content().readBytes(receivedBytes);
|
||||
assertArrayEquals(bytes, receivedBytes);
|
||||
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
||||
errorRef.compareAndSet(null, cause);
|
||||
}
|
||||
});
|
||||
|
||||
sc = sb.bind(newSocketAddress()).sync().channel();
|
||||
|
||||
if (connected) {
|
||||
sc.connect(cc.localAddress()).syncUninterruptibly();
|
||||
}
|
||||
|
||||
InetSocketAddress addr = (InetSocketAddress) sc.localAddress();
|
||||
|
||||
cc.writeAndFlush(new DatagramPacket(cc.alloc().directBuffer().writeBytes(bytes), addr)).sync();
|
||||
|
||||
if (!latch.await(10, TimeUnit.SECONDS)) {
|
||||
Throwable error = errorRef.get();
|
||||
if (error != null) {
|
||||
throw error;
|
||||
}
|
||||
fail("Timeout while waiting for packets");
|
||||
}
|
||||
} finally {
|
||||
if (cc != null) {
|
||||
cc.close().syncUninterruptibly();
|
||||
}
|
||||
if (sc != null) {
|
||||
sc.close().syncUninterruptibly();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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:
|
||||
*
|
||||
* https://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:
|
||||
*
|
||||
* https://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,190 @@
|
|||
/*
|
||||
* Copyright 2014 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:
|
||||
*
|
||||
* https://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.buffer.ByteBuf;
|
||||
import io.netty.buffer.CompositeByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.FixedRecvByteBufAllocator;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.channel.socket.DatagramPacket;
|
||||
import io.netty.channel.socket.InternetProtocolFamily;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.DatagramUnicastInetTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInfo;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
||||
|
||||
public class EpollDatagramUnicastTest extends DatagramUnicastInetTest {
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<Bootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.datagram(InternetProtocolFamily.IPv4);
|
||||
}
|
||||
|
||||
public void testSimpleSendWithConnect(Bootstrap sb, Bootstrap cb) throws Throwable {
|
||||
// Run this test with IP_RECVORIGDSTADDR option enabled
|
||||
sb.option(EpollChannelOption.IP_RECVORIGDSTADDR, true);
|
||||
super.testSimpleSendWithConnect(sb, cb);
|
||||
sb.option(EpollChannelOption.IP_RECVORIGDSTADDR, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendSegmentedDatagramPacket(TestInfo testInfo) throws Throwable {
|
||||
run(testInfo, new Runner<Bootstrap, Bootstrap>() {
|
||||
@Override
|
||||
public void run(Bootstrap bootstrap, Bootstrap bootstrap2) throws Throwable {
|
||||
testSendSegmentedDatagramPacket(bootstrap, bootstrap2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testSendSegmentedDatagramPacket(Bootstrap sb, Bootstrap cb) throws Throwable {
|
||||
testSegmentedDatagramPacket(sb, cb, false, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendSegmentedDatagramPacketComposite(TestInfo testInfo) throws Throwable {
|
||||
run(testInfo, new Runner<Bootstrap, Bootstrap>() {
|
||||
@Override
|
||||
public void run(Bootstrap bootstrap, Bootstrap bootstrap2) throws Throwable {
|
||||
testSendSegmentedDatagramPacketComposite(bootstrap, bootstrap2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testSendSegmentedDatagramPacketComposite(Bootstrap sb, Bootstrap cb) throws Throwable {
|
||||
testSegmentedDatagramPacket(sb, cb, true, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendAndReceiveSegmentedDatagramPacket(TestInfo testInfo) throws Throwable {
|
||||
run(testInfo, new Runner<Bootstrap, Bootstrap>() {
|
||||
@Override
|
||||
public void run(Bootstrap bootstrap, Bootstrap bootstrap2) throws Throwable {
|
||||
testSendAndReceiveSegmentedDatagramPacket(bootstrap, bootstrap2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testSendAndReceiveSegmentedDatagramPacket(Bootstrap sb, Bootstrap cb) throws Throwable {
|
||||
testSegmentedDatagramPacket(sb, cb, false, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendAndReceiveSegmentedDatagramPacketComposite(TestInfo testInfo) throws Throwable {
|
||||
run(testInfo, new Runner<Bootstrap, Bootstrap>() {
|
||||
@Override
|
||||
public void run(Bootstrap bootstrap, Bootstrap bootstrap2) throws Throwable {
|
||||
testSendAndReceiveSegmentedDatagramPacketComposite(bootstrap, bootstrap2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testSendAndReceiveSegmentedDatagramPacketComposite(Bootstrap sb, Bootstrap cb) throws Throwable {
|
||||
testSegmentedDatagramPacket(sb, cb, true, true);
|
||||
}
|
||||
|
||||
private void testSegmentedDatagramPacket(Bootstrap sb, Bootstrap cb, boolean composite, boolean gro)
|
||||
throws Throwable {
|
||||
if (!(cb.group() instanceof EpollEventLoopGroup)) {
|
||||
// Only supported for the native epoll transport.
|
||||
return;
|
||||
}
|
||||
if (gro && !(sb.group() instanceof EpollEventLoopGroup)) {
|
||||
// Only supported for the native epoll transport.
|
||||
return;
|
||||
}
|
||||
assumeTrue(EpollDatagramChannel.isSegmentedDatagramPacketSupported());
|
||||
Channel sc = null;
|
||||
Channel cc = null;
|
||||
|
||||
try {
|
||||
cb.handler(new SimpleChannelInboundHandler<Object>() {
|
||||
@Override
|
||||
public void channelRead0(ChannelHandlerContext ctx, Object msgs) {
|
||||
// Nothing will be sent.
|
||||
}
|
||||
});
|
||||
|
||||
cc = cb.bind(newSocketAddress()).sync().channel();
|
||||
|
||||
final int numBuffers = 16;
|
||||
final int segmentSize = 512;
|
||||
int bufferCapacity = numBuffers * segmentSize;
|
||||
final CountDownLatch latch = new CountDownLatch(numBuffers);
|
||||
AtomicReference<Throwable> errorRef = new AtomicReference<Throwable>();
|
||||
if (gro) {
|
||||
// Enable GRO and also ensure we can read everything with one read as otherwise
|
||||
// we will drop things on the floor.
|
||||
sb.option(EpollChannelOption.UDP_GRO, true);
|
||||
sb.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(bufferCapacity));
|
||||
}
|
||||
sc = sb.handler(new SimpleChannelInboundHandler<DatagramPacket>() {
|
||||
@Override
|
||||
public void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) {
|
||||
if (packet.content().readableBytes() == segmentSize) {
|
||||
latch.countDown();
|
||||
}
|
||||
}
|
||||
}).bind(newSocketAddress()).sync().channel();
|
||||
|
||||
if (sc instanceof EpollDatagramChannel) {
|
||||
assertEquals(gro, sc.config().getOption(EpollChannelOption.UDP_GRO));
|
||||
}
|
||||
InetSocketAddress addr = sendToAddress((InetSocketAddress) sc.localAddress());
|
||||
final ByteBuf buffer;
|
||||
if (composite) {
|
||||
CompositeByteBuf compositeBuffer = Unpooled.compositeBuffer();
|
||||
for (int i = 0; i < numBuffers; i++) {
|
||||
compositeBuffer.addComponent(true,
|
||||
Unpooled.directBuffer(segmentSize).writeZero(segmentSize));
|
||||
}
|
||||
buffer = compositeBuffer;
|
||||
} else {
|
||||
buffer = Unpooled.directBuffer(bufferCapacity).writeZero(bufferCapacity);
|
||||
}
|
||||
cc.writeAndFlush(new io.netty.channel.unix.SegmentedDatagramPacket(buffer, segmentSize, addr)).sync();
|
||||
|
||||
if (!latch.await(10, TimeUnit.SECONDS)) {
|
||||
Throwable error = errorRef.get();
|
||||
if (error != null) {
|
||||
throw error;
|
||||
}
|
||||
fail();
|
||||
}
|
||||
} finally {
|
||||
if (cc != null) {
|
||||
cc.close().sync();
|
||||
}
|
||||
if (sc != null) {
|
||||
sc.close().sync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright 2017 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:
|
||||
*
|
||||
* https://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.channel.Channel;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.ServerChannel;
|
||||
|
||||
public class EpollDetectPeerCloseWithoutReadTest extends DetectPeerCloseWithoutReadTest {
|
||||
@Override
|
||||
protected EventLoopGroup newGroup() {
|
||||
return new EpollEventLoopGroup(2);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<? extends ServerChannel> serverChannel() {
|
||||
return EpollServerSocketChannel.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<? extends Channel> clientChannel() {
|
||||
return EpollSocketChannel.class;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2023 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:
|
||||
*
|
||||
* https://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 org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class EpollDomainDatagramChannelTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
Epoll.ensureAvailability();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultMaxMessagePerRead() {
|
||||
EpollDomainDatagramChannel channel = new EpollDomainDatagramChannel();
|
||||
assertEquals(16, channel.config().getMaxMessagesPerRead());
|
||||
channel.unsafe().closeForcibly();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright 2021 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:
|
||||
*
|
||||
* https://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.buffer.Unpooled;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.unix.DomainDatagramPacket;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.AbstractClientSocketTest;
|
||||
import io.netty.util.CharsetUtil;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInfo;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
class EpollDomainDatagramPathTest extends AbstractClientSocketTest {
|
||||
|
||||
@Test
|
||||
void testConnectPathDoesNotExist(TestInfo testInfo) throws Throwable {
|
||||
run(testInfo, new Runner<Bootstrap>() {
|
||||
@Override
|
||||
public void run(Bootstrap bootstrap) {
|
||||
try {
|
||||
bootstrap.handler(new ChannelInboundHandlerAdapter())
|
||||
.connect(EpollSocketTestPermutation.newDomainSocketAddress()).sync().channel();
|
||||
fail("Expected FileNotFoundException");
|
||||
} catch (Exception e) {
|
||||
assertTrue(e instanceof FileNotFoundException);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWriteReceiverPathDoesNotExist(TestInfo testInfo) throws Throwable {
|
||||
run(testInfo, new Runner<Bootstrap>() {
|
||||
@Override
|
||||
public void run(Bootstrap bootstrap) {
|
||||
try {
|
||||
Channel ch = bootstrap.handler(new ChannelInboundHandlerAdapter())
|
||||
.bind(EpollSocketTestPermutation.newDomainSocketAddress()).sync().channel();
|
||||
ch.writeAndFlush(new DomainDatagramPacket(
|
||||
Unpooled.copiedBuffer("test", CharsetUtil.US_ASCII),
|
||||
EpollSocketTestPermutation.newDomainSocketAddress())).sync();
|
||||
fail("Expected FileNotFoundException");
|
||||
} catch (Exception e) {
|
||||
assertTrue(e instanceof FileNotFoundException);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapFactory<Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.domainDatagramSocket();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* Copyright 2021 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:
|
||||
*
|
||||
* https://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.buffer.ByteBuf;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.channel.unix.DomainDatagramChannel;
|
||||
import io.netty.channel.unix.DomainDatagramPacket;
|
||||
import io.netty.channel.unix.DomainSocketAddress;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.DatagramUnicastTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInfo;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
class EpollDomainDatagramUnicastTest extends DatagramUnicastTest {
|
||||
|
||||
@Test
|
||||
void testBind(TestInfo testInfo) throws Throwable {
|
||||
run(testInfo, new Runner<Bootstrap, Bootstrap>() {
|
||||
@Override
|
||||
public void run(Bootstrap bootstrap, Bootstrap bootstrap2) throws Throwable {
|
||||
testBind(bootstrap2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void testBind(Bootstrap cb) throws Throwable {
|
||||
Channel channel = null;
|
||||
try {
|
||||
channel = cb.handler(new ChannelInboundHandlerAdapter())
|
||||
.bind(newSocketAddress()).sync().channel();
|
||||
assertThat(channel.localAddress()).isNotNull()
|
||||
.isInstanceOf(DomainSocketAddress.class);
|
||||
} finally {
|
||||
closeChannel(channel);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportDisconnect() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isConnected(Channel channel) {
|
||||
return ((DomainDatagramChannel) channel).isConnected();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<Bootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.domainDatagram();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SocketAddress newSocketAddress() {
|
||||
return EpollSocketTestPermutation.newDomainSocketAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Channel setupClientChannel(Bootstrap cb, final byte[] bytes, final CountDownLatch latch,
|
||||
final AtomicReference<Throwable> errorRef) throws Throwable {
|
||||
cb.handler(new SimpleChannelInboundHandler<DomainDatagramPacket>() {
|
||||
|
||||
@Override
|
||||
public void channelRead0(ChannelHandlerContext ctx, DomainDatagramPacket msg) {
|
||||
try {
|
||||
ByteBuf buf = msg.content();
|
||||
assertEquals(bytes.length, buf.readableBytes());
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
assertEquals(bytes[i], buf.getByte(buf.readerIndex() + i));
|
||||
}
|
||||
|
||||
assertEquals(ctx.channel().localAddress(), msg.recipient());
|
||||
} finally {
|
||||
latch.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
||||
errorRef.compareAndSet(null, cause);
|
||||
}
|
||||
});
|
||||
return cb.bind(newSocketAddress()).sync().channel();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Channel setupServerChannel(Bootstrap sb, final byte[] bytes, final SocketAddress sender,
|
||||
final CountDownLatch latch, final AtomicReference<Throwable> errorRef,
|
||||
final boolean echo) throws Throwable {
|
||||
sb.handler(new SimpleChannelInboundHandler<DomainDatagramPacket>() {
|
||||
|
||||
@Override
|
||||
public void channelRead0(ChannelHandlerContext ctx, DomainDatagramPacket msg) {
|
||||
try {
|
||||
if (sender == null) {
|
||||
assertNotNull(msg.sender());
|
||||
} else {
|
||||
assertEquals(sender, msg.sender());
|
||||
}
|
||||
|
||||
ByteBuf buf = msg.content();
|
||||
assertEquals(bytes.length, buf.readableBytes());
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
assertEquals(bytes[i], buf.getByte(buf.readerIndex() + i));
|
||||
}
|
||||
|
||||
assertEquals(ctx.channel().localAddress(), msg.recipient());
|
||||
|
||||
if (echo) {
|
||||
ctx.writeAndFlush(new DomainDatagramPacket(buf.retainedDuplicate(), msg.sender()));
|
||||
}
|
||||
} finally {
|
||||
latch.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
||||
errorRef.compareAndSet(null, cause);
|
||||
}
|
||||
});
|
||||
return sb.bind(newSocketAddress()).sync().channel();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ChannelFuture write(Channel cc, ByteBuf buf, SocketAddress remote, WrapType wrapType) {
|
||||
switch (wrapType) {
|
||||
case DUP:
|
||||
return cc.write(new DomainDatagramPacket(buf.retainedDuplicate(), (DomainSocketAddress) remote));
|
||||
case SLICE:
|
||||
return cc.write(new DomainDatagramPacket(buf.retainedSlice(), (DomainSocketAddress) remote));
|
||||
case READ_ONLY:
|
||||
return cc.write(new DomainDatagramPacket(buf.retain().asReadOnly(), (DomainSocketAddress) remote));
|
||||
case NONE:
|
||||
return cc.write(new DomainDatagramPacket(buf.retain(), (DomainSocketAddress) remote));
|
||||
default:
|
||||
throw new Error("unknown wrap type: " + wrapType);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright 2023 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.unix.DomainSocketAddress;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketAddressesTest;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
class EpollDomainSocketAddressesTest extends SocketAddressesTest {
|
||||
|
||||
@Override
|
||||
protected SocketAddress newSocketAddress() {
|
||||
return EpollSocketTestPermutation.newDomainSocketAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.domainSocket();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assertAddress(SocketAddress address) {
|
||||
assertNotNull(((DomainSocketAddress) address).path());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2018 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketDataReadInitialStateTest;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.util.List;
|
||||
|
||||
public class EpollDomainSocketDataReadInitialStateTest extends SocketDataReadInitialStateTest {
|
||||
@Override
|
||||
protected SocketAddress newSocketAddress() {
|
||||
return EpollSocketTestPermutation.newDomainSocketAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.domainSocket();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright 2015 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.util.List;
|
||||
|
||||
public class EpollDomainSocketEchoTest extends EpollSocketEchoTest {
|
||||
@Override
|
||||
protected SocketAddress newSocketAddress() {
|
||||
return EpollSocketTestPermutation.newDomainSocketAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.domainSocket();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Copyright 2015 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.unix.DomainSocketReadMode;
|
||||
import io.netty.channel.unix.FileDescriptor;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.AbstractSocketTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInfo;
|
||||
import org.junit.jupiter.api.Timeout;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class EpollDomainSocketFdTest extends AbstractSocketTest {
|
||||
@Override
|
||||
protected SocketAddress newSocketAddress() {
|
||||
return EpollSocketTestPermutation.newDomainSocketAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.domainSocket();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Timeout(value = 30000, unit = TimeUnit.MILLISECONDS)
|
||||
public void testSendRecvFd(TestInfo testInfo) throws Throwable {
|
||||
run(testInfo, new Runner<ServerBootstrap, Bootstrap>() {
|
||||
@Override
|
||||
public void run(ServerBootstrap serverBootstrap, Bootstrap bootstrap) throws Throwable {
|
||||
testSendRecvFd(serverBootstrap, bootstrap);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testSendRecvFd(ServerBootstrap sb, Bootstrap cb) throws Throwable {
|
||||
final BlockingQueue<Object> queue = new LinkedBlockingQueue<Object>(1);
|
||||
sb.childHandler(new ChannelInboundHandlerAdapter() {
|
||||
@Override
|
||||
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
||||
// Create new channel and obtain a file descriptor from it.
|
||||
final EpollDomainSocketChannel ch = new EpollDomainSocketChannel();
|
||||
|
||||
ctx.writeAndFlush(ch.fd()).addListener(new ChannelFutureListener() {
|
||||
@Override
|
||||
public void operationComplete(ChannelFuture future) throws Exception {
|
||||
if (!future.isSuccess()) {
|
||||
Throwable cause = future.cause();
|
||||
queue.offer(cause);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
cb.handler(new ChannelInboundHandlerAdapter() {
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
FileDescriptor fd = (FileDescriptor) msg;
|
||||
queue.offer(fd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
queue.add(cause);
|
||||
ctx.close();
|
||||
}
|
||||
});
|
||||
cb.option(EpollChannelOption.DOMAIN_SOCKET_READ_MODE,
|
||||
DomainSocketReadMode.FILE_DESCRIPTORS);
|
||||
Channel sc = sb.bind().sync().channel();
|
||||
Channel cc = cb.connect(sc.localAddress()).sync().channel();
|
||||
|
||||
Object received = queue.take();
|
||||
cc.close().sync();
|
||||
sc.close().sync();
|
||||
|
||||
if (received instanceof FileDescriptor) {
|
||||
FileDescriptor fd = (FileDescriptor) received;
|
||||
assertTrue(fd.isOpen());
|
||||
fd.close();
|
||||
assertFalse(fd.isOpen());
|
||||
assertNull(queue.poll());
|
||||
} else {
|
||||
throw (Throwable) received;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright 2015 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.util.List;
|
||||
|
||||
public class EpollDomainSocketFileRegionTest extends EpollSocketFileRegionTest {
|
||||
@Override
|
||||
protected SocketAddress newSocketAddress() {
|
||||
return EpollSocketTestPermutation.newDomainSocketAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.domainSocket();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright 2015 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketFixedLengthEchoTest;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.util.List;
|
||||
|
||||
public class EpollDomainSocketFixedLengthEchoTest extends SocketFixedLengthEchoTest {
|
||||
|
||||
@Override
|
||||
protected SocketAddress newSocketAddress() {
|
||||
return EpollSocketTestPermutation.newDomainSocketAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.domainSocket();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright 2015 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketGatheringWriteTest;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.util.List;
|
||||
|
||||
public class EpollDomainSocketGatheringWriteTest extends SocketGatheringWriteTest {
|
||||
|
||||
@Override
|
||||
protected SocketAddress newSocketAddress() {
|
||||
return EpollSocketTestPermutation.newDomainSocketAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.domainSocket();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2015 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketObjectEchoTest;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.util.List;
|
||||
|
||||
public class EpollDomainSocketObjectEchoTest extends SocketObjectEchoTest {
|
||||
@Override
|
||||
protected SocketAddress newSocketAddress() {
|
||||
return EpollSocketTestPermutation.newDomainSocketAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.domainSocket();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.AbstractSocketReuseFdTest;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.util.List;
|
||||
|
||||
public class EpollDomainSocketReuseFdTest extends AbstractSocketReuseFdTest {
|
||||
@Override
|
||||
protected SocketAddress newSocketAddress() {
|
||||
return EpollSocketTestPermutation.newDomainSocketAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.domainSocket();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* 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:
|
||||
*
|
||||
* https://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.ServerBootstrap;
|
||||
import io.netty.channel.unix.Buffer;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation.BootstrapFactory;
|
||||
import io.netty.testsuite.transport.socket.AbstractSocketShutdownOutputByPeerTest;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.SocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
public class EpollDomainSocketShutdownOutputByPeerTest extends AbstractSocketShutdownOutputByPeerTest<LinuxSocket> {
|
||||
|
||||
@Override
|
||||
protected List<BootstrapFactory<ServerBootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.serverDomainSocket();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SocketAddress newSocketAddress() {
|
||||
return EpollSocketTestPermutation.newDomainSocketAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutdownOutput(LinuxSocket s) throws IOException {
|
||||
s.shutdown(false, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void connect(LinuxSocket s, SocketAddress address) throws IOException {
|
||||
s.connect(address);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void close(LinuxSocket s) throws IOException {
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void write(LinuxSocket s, int data) throws IOException {
|
||||
final ByteBuffer buf = Buffer.allocateDirectWithNativeOrder(4);
|
||||
buf.putInt(data);
|
||||
buf.flip();
|
||||
s.send(buf, buf.position(), buf.limit());
|
||||
Buffer.free(buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LinuxSocket newSocket() {
|
||||
return LinuxSocket.newSocketDomain();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketSslClientRenegotiateTest;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.util.List;
|
||||
|
||||
public class EpollDomainSocketSslClientRenegotiateTest extends SocketSslClientRenegotiateTest {
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.domainSocket();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SocketAddress newSocketAddress() {
|
||||
return EpollSocketTestPermutation.newDomainSocketAddress();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2015 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketSslEchoTest;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.util.List;
|
||||
|
||||
public class EpollDomainSocketSslEchoTest extends SocketSslEchoTest {
|
||||
@Override
|
||||
protected SocketAddress newSocketAddress() {
|
||||
return EpollSocketTestPermutation.newDomainSocketAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.domainSocket();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2015 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketSslGreetingTest;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.util.List;
|
||||
|
||||
public class EpollDomainSocketSslGreetingTest extends SocketSslGreetingTest {
|
||||
@Override
|
||||
protected SocketAddress newSocketAddress() {
|
||||
return EpollSocketTestPermutation.newDomainSocketAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.domainSocket();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2015 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketStartTlsTest;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.util.List;
|
||||
|
||||
public class EpollDomainSocketStartTlsTest extends SocketStartTlsTest {
|
||||
@Override
|
||||
protected SocketAddress newSocketAddress() {
|
||||
return EpollSocketTestPermutation.newDomainSocketAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.domainSocket();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2015 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketStringEchoTest;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.util.List;
|
||||
|
||||
public class EpollDomainSocketStringEchoTest extends SocketStringEchoTest {
|
||||
@Override
|
||||
protected SocketAddress newSocketAddress() {
|
||||
return EpollSocketTestPermutation.newDomainSocketAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.domainSocket();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2016 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketAutoReadTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollETSocketAutoReadTest extends SocketAutoReadTest {
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.socketWithFastOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(ServerBootstrap bootstrap, Bootstrap bootstrap2, ByteBufAllocator allocator) {
|
||||
super.configure(bootstrap, bootstrap2, allocator);
|
||||
bootstrap.option(EpollChannelOption.EPOLL_MODE, EpollMode.EDGE_TRIGGERED)
|
||||
.childOption(EpollChannelOption.EPOLL_MODE, EpollMode.EDGE_TRIGGERED);
|
||||
bootstrap2.option(EpollChannelOption.EPOLL_MODE, EpollMode.EDGE_TRIGGERED);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2018 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketConditionalWritabilityTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollETSocketConditionalWritabilityTest extends SocketConditionalWritabilityTest {
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.socketWithFastOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(ServerBootstrap bootstrap, Bootstrap bootstrap2, ByteBufAllocator allocator) {
|
||||
super.configure(bootstrap, bootstrap2, allocator);
|
||||
bootstrap.option(EpollChannelOption.EPOLL_MODE, EpollMode.EDGE_TRIGGERED)
|
||||
.childOption(EpollChannelOption.EPOLL_MODE, EpollMode.EDGE_TRIGGERED);
|
||||
bootstrap2.option(EpollChannelOption.EPOLL_MODE, EpollMode.EDGE_TRIGGERED);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2018 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketDataReadInitialStateTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollETSocketDataReadInitialStateTest extends SocketDataReadInitialStateTest {
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.socketWithFastOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(ServerBootstrap bootstrap, Bootstrap bootstrap2, ByteBufAllocator allocator) {
|
||||
super.configure(bootstrap, bootstrap2, allocator);
|
||||
bootstrap.option(EpollChannelOption.EPOLL_MODE, EpollMode.EDGE_TRIGGERED)
|
||||
.childOption(EpollChannelOption.EPOLL_MODE, EpollMode.EDGE_TRIGGERED);
|
||||
bootstrap2.option(EpollChannelOption.EPOLL_MODE, EpollMode.EDGE_TRIGGERED);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2016 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketExceptionHandlingTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollETSocketExceptionHandlingTest extends SocketExceptionHandlingTest {
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.socketWithFastOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(ServerBootstrap bootstrap, Bootstrap bootstrap2, ByteBufAllocator allocator) {
|
||||
super.configure(bootstrap, bootstrap2, allocator);
|
||||
bootstrap.option(EpollChannelOption.EPOLL_MODE, EpollMode.EDGE_TRIGGERED)
|
||||
.childOption(EpollChannelOption.EPOLL_MODE, EpollMode.EDGE_TRIGGERED);
|
||||
bootstrap2.option(EpollChannelOption.EPOLL_MODE, EpollMode.EDGE_TRIGGERED);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2017 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketHalfClosedTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollETSocketHalfClosedTest extends SocketHalfClosedTest {
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.socketWithoutFastOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(ServerBootstrap bootstrap, Bootstrap bootstrap2, ByteBufAllocator allocator) {
|
||||
super.configure(bootstrap, bootstrap2, allocator);
|
||||
bootstrap.option(EpollChannelOption.EPOLL_MODE, EpollMode.EDGE_TRIGGERED)
|
||||
.childOption(EpollChannelOption.EPOLL_MODE, EpollMode.EDGE_TRIGGERED);
|
||||
bootstrap2.option(EpollChannelOption.EPOLL_MODE, EpollMode.EDGE_TRIGGERED);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2016 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketReadPendingTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollETSocketReadPendingTest extends SocketReadPendingTest {
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.socketWithFastOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(ServerBootstrap bootstrap, Bootstrap bootstrap2, ByteBufAllocator allocator) {
|
||||
super.configure(bootstrap, bootstrap2, allocator);
|
||||
bootstrap.option(EpollChannelOption.EPOLL_MODE, EpollMode.EDGE_TRIGGERED)
|
||||
.childOption(EpollChannelOption.EPOLL_MODE, EpollMode.EDGE_TRIGGERED);
|
||||
bootstrap2.option(EpollChannelOption.EPOLL_MODE, EpollMode.EDGE_TRIGGERED);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright 2018 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
|
||||
public class EpollETSocketStringEchoBusyWaitTest extends EpollSocketStringEchoBusyWaitTest {
|
||||
|
||||
@Override
|
||||
protected void configure(ServerBootstrap bootstrap, Bootstrap bootstrap2, ByteBufAllocator allocator) {
|
||||
super.configure(bootstrap, bootstrap2, allocator);
|
||||
bootstrap.option(EpollChannelOption.EPOLL_MODE, EpollMode.EDGE_TRIGGERED)
|
||||
.childOption(EpollChannelOption.EPOLL_MODE, EpollMode.EDGE_TRIGGERED);
|
||||
bootstrap2.option(EpollChannelOption.EPOLL_MODE, EpollMode.EDGE_TRIGGERED);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
* Copyright 2017 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:
|
||||
*
|
||||
* https://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.testsuite.transport.AbstractSingleThreadEventLoopTest;
|
||||
import io.netty.channel.DefaultSelectStrategyFactory;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.ServerChannel;
|
||||
import io.netty.channel.socket.ServerSocketChannel;
|
||||
import io.netty.channel.unix.FileDescriptor;
|
||||
import io.netty.util.concurrent.DefaultThreadFactory;
|
||||
import io.netty.util.concurrent.Future;
|
||||
import io.netty.util.concurrent.RejectedExecutionHandlers;
|
||||
import io.netty.util.concurrent.ThreadPerTaskExecutor;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class EpollEventLoopTest extends AbstractSingleThreadEventLoopTest {
|
||||
|
||||
@Override
|
||||
protected boolean supportsChannelIteration() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EventLoopGroup newEventLoopGroup() {
|
||||
return new EpollEventLoopGroup();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ServerSocketChannel newChannel() {
|
||||
return new EpollServerSocketChannel();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<? extends ServerChannel> serverChannelClass() {
|
||||
return EpollServerSocketChannel.class;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScheduleBigDelayNotOverflow() {
|
||||
final AtomicReference<Throwable> capture = new AtomicReference<Throwable>();
|
||||
|
||||
final EventLoopGroup group = new EpollEventLoop(null,
|
||||
new ThreadPerTaskExecutor(new DefaultThreadFactory(getClass())), 0,
|
||||
DefaultSelectStrategyFactory.INSTANCE.newSelectStrategy(), RejectedExecutionHandlers.reject(),
|
||||
null, null) {
|
||||
@Override
|
||||
void handleLoopException(Throwable t) {
|
||||
capture.set(t);
|
||||
super.handleLoopException(t);
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
final EventLoop eventLoop = group.next();
|
||||
Future<?> future = eventLoop.schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// NOOP
|
||||
}
|
||||
}, Long.MAX_VALUE, TimeUnit.MILLISECONDS);
|
||||
|
||||
assertFalse(future.awaitUninterruptibly(1000));
|
||||
assertTrue(future.cancel(true));
|
||||
assertNull(capture.get());
|
||||
} finally {
|
||||
group.shutdownGracefully();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEventFDETSemantics() throws Throwable {
|
||||
final FileDescriptor epoll = Native.newEpollCreate();
|
||||
final FileDescriptor eventFd = Native.newEventFd();
|
||||
final FileDescriptor timerFd = Native.newTimerFd();
|
||||
final EpollEventArray array = new EpollEventArray(1024);
|
||||
try {
|
||||
Native.epollCtlAdd(epoll.intValue(), eventFd.intValue(), Native.EPOLLIN | Native.EPOLLET);
|
||||
final AtomicReference<Throwable> causeRef = new AtomicReference<Throwable>();
|
||||
final AtomicInteger integer = new AtomicInteger();
|
||||
final Thread t = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
int ready = Native.epollWait(epoll, array, timerFd, -1, -1);
|
||||
assertEquals(1, ready);
|
||||
assertEquals(eventFd.intValue(), array.fd(0));
|
||||
integer.incrementAndGet();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
causeRef.set(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
Native.eventFdWrite(eventFd.intValue(), 1);
|
||||
|
||||
// Spin until we was the wakeup.
|
||||
while (integer.get() != 1) {
|
||||
Thread.sleep(10);
|
||||
}
|
||||
// Sleep for a short moment to ensure there is not other wakeup.
|
||||
Thread.sleep(1000);
|
||||
assertEquals(1, integer.get());
|
||||
Native.eventFdWrite(eventFd.intValue(), 1);
|
||||
t.join();
|
||||
Throwable cause = causeRef.get();
|
||||
if (cause != null) {
|
||||
throw cause;
|
||||
}
|
||||
assertEquals(2, integer.get());
|
||||
} finally {
|
||||
array.free();
|
||||
epoll.close();
|
||||
eventFd.close();
|
||||
timerFd.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResultNoTimeoutCorrectlyEncoded() throws Throwable {
|
||||
final FileDescriptor epoll = Native.newEpollCreate();
|
||||
final FileDescriptor eventFd = Native.newEventFd();
|
||||
final FileDescriptor timerFd = Native.newTimerFd();
|
||||
final EpollEventArray array = new EpollEventArray(1024);
|
||||
try {
|
||||
Native.epollCtlAdd(epoll.intValue(), eventFd.intValue(), Native.EPOLLIN | Native.EPOLLET);
|
||||
final AtomicReference<Throwable> causeRef = new AtomicReference<Throwable>();
|
||||
final Thread t = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
for (;;) {
|
||||
long ready = Native.epollWait(epoll, array, timerFd, 0, 0, 10);
|
||||
if (ready > 0) {
|
||||
assertEquals(1, Native.epollReady(ready));
|
||||
assertEquals(eventFd.intValue(), array.fd(0));
|
||||
return;
|
||||
}
|
||||
Thread.sleep(100);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
causeRef.set(e);
|
||||
} catch (InterruptedException ignore) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
Native.eventFdWrite(eventFd.intValue(), 1);
|
||||
|
||||
t.join();
|
||||
Throwable cause = causeRef.get();
|
||||
if (cause != null) {
|
||||
throw cause;
|
||||
}
|
||||
} finally {
|
||||
array.free();
|
||||
epoll.close();
|
||||
eventFd.close();
|
||||
timerFd.close();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright 2021 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:
|
||||
*
|
||||
* https://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 java.net.SocketAddress;
|
||||
|
||||
public class EpollJdkLoopbackSocketSslEchoTest extends EpollSocketSslEchoTest {
|
||||
@Override
|
||||
protected SocketAddress newSocketAddress() {
|
||||
return UnixTestUtils.newInetLoopbackSocketAddress();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright 2020 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:
|
||||
*
|
||||
* https://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 org.junit.jupiter.api.BeforeAll;
|
||||
|
||||
public class EpollKQueueIovArrayTest extends IovArrayTest {
|
||||
|
||||
@BeforeAll
|
||||
public static void loadNative() {
|
||||
Epoll.ensureAvailability();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2016 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketAutoReadTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollLTSocketAutoReadTest extends SocketAutoReadTest {
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.socketWithFastOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(ServerBootstrap bootstrap, Bootstrap bootstrap2, ByteBufAllocator allocator) {
|
||||
super.configure(bootstrap, bootstrap2, allocator);
|
||||
bootstrap.option(EpollChannelOption.EPOLL_MODE, EpollMode.LEVEL_TRIGGERED)
|
||||
.childOption(EpollChannelOption.EPOLL_MODE, EpollMode.LEVEL_TRIGGERED);
|
||||
bootstrap2.option(EpollChannelOption.EPOLL_MODE, EpollMode.LEVEL_TRIGGERED);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2018 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketConditionalWritabilityTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollLTSocketConditionalWritabilityTest extends SocketConditionalWritabilityTest {
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.socketWithFastOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(ServerBootstrap bootstrap, Bootstrap bootstrap2, ByteBufAllocator allocator) {
|
||||
super.configure(bootstrap, bootstrap2, allocator);
|
||||
bootstrap.option(EpollChannelOption.EPOLL_MODE, EpollMode.LEVEL_TRIGGERED)
|
||||
.childOption(EpollChannelOption.EPOLL_MODE, EpollMode.LEVEL_TRIGGERED);
|
||||
bootstrap2.option(EpollChannelOption.EPOLL_MODE, EpollMode.LEVEL_TRIGGERED);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2018 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketDataReadInitialStateTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollLTSocketDataReadInitialStateTest extends SocketDataReadInitialStateTest {
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.socketWithFastOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(ServerBootstrap bootstrap, Bootstrap bootstrap2, ByteBufAllocator allocator) {
|
||||
super.configure(bootstrap, bootstrap2, allocator);
|
||||
bootstrap.option(EpollChannelOption.EPOLL_MODE, EpollMode.LEVEL_TRIGGERED)
|
||||
.childOption(EpollChannelOption.EPOLL_MODE, EpollMode.LEVEL_TRIGGERED);
|
||||
bootstrap2.option(EpollChannelOption.EPOLL_MODE, EpollMode.LEVEL_TRIGGERED);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2016 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketExceptionHandlingTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollLTSocketExceptionHandlingTest extends SocketExceptionHandlingTest {
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.socketWithFastOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(ServerBootstrap bootstrap, Bootstrap bootstrap2, ByteBufAllocator allocator) {
|
||||
super.configure(bootstrap, bootstrap2, allocator);
|
||||
bootstrap.option(EpollChannelOption.EPOLL_MODE, EpollMode.LEVEL_TRIGGERED)
|
||||
.childOption(EpollChannelOption.EPOLL_MODE, EpollMode.LEVEL_TRIGGERED);
|
||||
bootstrap2.option(EpollChannelOption.EPOLL_MODE, EpollMode.LEVEL_TRIGGERED);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2017 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketHalfClosedTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollLTSocketHalfClosedTest extends SocketHalfClosedTest {
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.socketWithoutFastOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(ServerBootstrap bootstrap, Bootstrap bootstrap2, ByteBufAllocator allocator) {
|
||||
super.configure(bootstrap, bootstrap2, allocator);
|
||||
bootstrap.option(EpollChannelOption.EPOLL_MODE, EpollMode.LEVEL_TRIGGERED)
|
||||
.childOption(EpollChannelOption.EPOLL_MODE, EpollMode.LEVEL_TRIGGERED);
|
||||
bootstrap2.option(EpollChannelOption.EPOLL_MODE, EpollMode.LEVEL_TRIGGERED);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2016 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketReadPendingTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollLTSocketReadPendingTest extends SocketReadPendingTest {
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.socketWithFastOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(ServerBootstrap bootstrap, Bootstrap bootstrap2, ByteBufAllocator allocator) {
|
||||
super.configure(bootstrap, bootstrap2, allocator);
|
||||
bootstrap.option(EpollChannelOption.EPOLL_MODE, EpollMode.LEVEL_TRIGGERED)
|
||||
.childOption(EpollChannelOption.EPOLL_MODE, EpollMode.LEVEL_TRIGGERED);
|
||||
bootstrap2.option(EpollChannelOption.EPOLL_MODE, EpollMode.LEVEL_TRIGGERED);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright 2018 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
|
||||
public class EpollLTSocketStringEchoBusyWaitTest extends EpollSocketStringEchoBusyWaitTest {
|
||||
|
||||
@Override
|
||||
protected void configure(ServerBootstrap bootstrap, Bootstrap bootstrap2, ByteBufAllocator allocator) {
|
||||
super.configure(bootstrap, bootstrap2, allocator);
|
||||
bootstrap.option(EpollChannelOption.EPOLL_MODE, EpollMode.LEVEL_TRIGGERED)
|
||||
.childOption(EpollChannelOption.EPOLL_MODE, EpollMode.LEVEL_TRIGGERED);
|
||||
bootstrap2.option(EpollChannelOption.EPOLL_MODE, EpollMode.LEVEL_TRIGGERED);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,263 @@
|
|||
/*
|
||||
* Copyright 2014 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:
|
||||
*
|
||||
* https://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.AbstractBootstrap;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerAdapter;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.handler.logging.LogLevel;
|
||||
import io.netty.handler.logging.LoggingHandler;
|
||||
import io.netty.util.NetUtil;
|
||||
import io.netty.util.ReferenceCountUtil;
|
||||
import io.netty.util.ResourceLeakDetector;
|
||||
import io.netty.util.internal.logging.InternalLogLevel;
|
||||
import io.netty.util.internal.logging.InternalLogger;
|
||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.Timeout;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
||||
|
||||
public class EpollReuseAddrTest {
|
||||
private static final InternalLogger LOGGER = InternalLoggerFactory.getInstance(EpollReuseAddrTest.class);
|
||||
|
||||
private static final int MAJOR;
|
||||
private static final int MINOR;
|
||||
private static final int BUGFIX;
|
||||
static {
|
||||
String kernelVersion = Native.KERNEL_VERSION;
|
||||
int index = kernelVersion.indexOf('-');
|
||||
if (index > -1) {
|
||||
kernelVersion = kernelVersion.substring(0, index);
|
||||
}
|
||||
String[] versionParts = kernelVersion.split("\\.");
|
||||
if (versionParts.length <= 3) {
|
||||
MAJOR = Integer.parseInt(versionParts[0]);
|
||||
MINOR = Integer.parseInt(versionParts[1]);
|
||||
if (versionParts.length == 3) {
|
||||
int bugFix;
|
||||
try {
|
||||
bugFix = Integer.parseInt(versionParts[2]);
|
||||
} catch (NumberFormatException ignore) {
|
||||
// the last part of the version may include all kind of different things. Especially when
|
||||
// someone compiles his / her own kernel.
|
||||
// Just ignore a parse error here and use 0.
|
||||
bugFix = 0;
|
||||
}
|
||||
BUGFIX = bugFix;
|
||||
} else {
|
||||
BUGFIX = 0;
|
||||
}
|
||||
} else {
|
||||
LOGGER.log(InternalLogLevel.INFO, "Unable to parse kernel version: " + kernelVersion);
|
||||
MAJOR = 0;
|
||||
MINOR = 0;
|
||||
BUGFIX = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleBindSocketChannelWithoutReusePortFails() {
|
||||
assumeTrue(versionEqOrGt(3, 9, 0));
|
||||
testMultipleBindDatagramChannelWithoutReusePortFails0(createServerBootstrap());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleBindDatagramChannelWithoutReusePortFails() {
|
||||
assumeTrue(versionEqOrGt(3, 9, 0));
|
||||
testMultipleBindDatagramChannelWithoutReusePortFails0(createBootstrap());
|
||||
}
|
||||
|
||||
private static void testMultipleBindDatagramChannelWithoutReusePortFails0(AbstractBootstrap<?, ?> bootstrap) {
|
||||
bootstrap.handler(new LoggingHandler(LogLevel.ERROR));
|
||||
ChannelFuture future = bootstrap.bind().syncUninterruptibly();
|
||||
try {
|
||||
bootstrap.bind(future.channel().localAddress()).syncUninterruptibly();
|
||||
fail();
|
||||
} catch (Exception e) {
|
||||
assertTrue(e instanceof IOException);
|
||||
}
|
||||
future.channel().close().syncUninterruptibly();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Timeout(value = 10000, unit = TimeUnit.MILLISECONDS)
|
||||
public void testMultipleBindSocketChannel() throws Exception {
|
||||
assumeTrue(versionEqOrGt(3, 9, 0));
|
||||
ServerBootstrap bootstrap = createServerBootstrap();
|
||||
bootstrap.option(EpollChannelOption.SO_REUSEPORT, true);
|
||||
final AtomicBoolean accepted1 = new AtomicBoolean();
|
||||
bootstrap.childHandler(new ServerSocketTestHandler(accepted1));
|
||||
ChannelFuture future = bootstrap.bind().syncUninterruptibly();
|
||||
InetSocketAddress address1 = (InetSocketAddress) future.channel().localAddress();
|
||||
|
||||
final AtomicBoolean accepted2 = new AtomicBoolean();
|
||||
bootstrap.childHandler(new ServerSocketTestHandler(accepted2));
|
||||
ChannelFuture future2 = bootstrap.bind(address1).syncUninterruptibly();
|
||||
InetSocketAddress address2 = (InetSocketAddress) future2.channel().localAddress();
|
||||
|
||||
assertEquals(address1, address2);
|
||||
while (!accepted1.get() || !accepted2.get()) {
|
||||
Socket socket = new Socket(address1.getAddress(), address1.getPort());
|
||||
socket.setReuseAddress(true);
|
||||
socket.close();
|
||||
}
|
||||
future.channel().close().syncUninterruptibly();
|
||||
future2.channel().close().syncUninterruptibly();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Timeout(value = 10000, unit = TimeUnit.MILLISECONDS)
|
||||
@Disabled // TODO: Unignore after making it pass on centos6-1 and debian7-1
|
||||
public void testMultipleBindDatagramChannel() throws Exception {
|
||||
ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.ADVANCED);
|
||||
assumeTrue(versionEqOrGt(3, 9, 0));
|
||||
Bootstrap bootstrap = createBootstrap();
|
||||
bootstrap.option(EpollChannelOption.SO_REUSEPORT, true);
|
||||
final AtomicBoolean received1 = new AtomicBoolean();
|
||||
bootstrap.handler(new DatagramSocketTestHandler(received1));
|
||||
ChannelFuture future = bootstrap.bind().syncUninterruptibly();
|
||||
final InetSocketAddress address1 = (InetSocketAddress) future.channel().localAddress();
|
||||
|
||||
final AtomicBoolean received2 = new AtomicBoolean();
|
||||
bootstrap.handler(new DatagramSocketTestHandler(received2));
|
||||
ChannelFuture future2 = bootstrap.bind(address1).syncUninterruptibly();
|
||||
final InetSocketAddress address2 = (InetSocketAddress) future2.channel().localAddress();
|
||||
|
||||
assertEquals(address1, address2);
|
||||
final byte[] bytes = "data".getBytes();
|
||||
|
||||
// fire up 16 Threads and send DatagramPackets to make sure we stress it enough to see DatagramPackets received
|
||||
// on both sockets.
|
||||
int count = 16;
|
||||
final CountDownLatch latch = new CountDownLatch(count);
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
DatagramSocket socket = new DatagramSocket();
|
||||
while (!received1.get() || !received2.get()) {
|
||||
socket.send(new DatagramPacket(
|
||||
bytes, 0, bytes.length, address1.getAddress(), address1.getPort()));
|
||||
}
|
||||
socket.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
latch.countDown();
|
||||
}
|
||||
};
|
||||
|
||||
ExecutorService executor = Executors.newFixedThreadPool(count);
|
||||
for (int i = 0 ; i < count; i++) {
|
||||
executor.execute(r);
|
||||
}
|
||||
latch.await();
|
||||
executor.shutdown();
|
||||
future.channel().close().syncUninterruptibly();
|
||||
future2.channel().close().syncUninterruptibly();
|
||||
assertTrue(received1.get());
|
||||
assertTrue(received2.get());
|
||||
}
|
||||
|
||||
private static ServerBootstrap createServerBootstrap() {
|
||||
ServerBootstrap bootstrap = new ServerBootstrap();
|
||||
bootstrap.group(EpollSocketTestPermutation.EPOLL_BOSS_GROUP, EpollSocketTestPermutation.EPOLL_WORKER_GROUP);
|
||||
bootstrap.channel(EpollServerSocketChannel.class);
|
||||
bootstrap.childHandler(new DummyHandler());
|
||||
InetSocketAddress address = new InetSocketAddress(NetUtil.LOCALHOST, 0);
|
||||
bootstrap.localAddress(address);
|
||||
return bootstrap;
|
||||
}
|
||||
|
||||
private static Bootstrap createBootstrap() {
|
||||
Bootstrap bootstrap = new Bootstrap();
|
||||
bootstrap.group(EpollSocketTestPermutation.EPOLL_WORKER_GROUP);
|
||||
bootstrap.channel(EpollDatagramChannel.class);
|
||||
InetSocketAddress address = new InetSocketAddress(NetUtil.LOCALHOST, 0);
|
||||
bootstrap.localAddress(address);
|
||||
return bootstrap;
|
||||
}
|
||||
|
||||
private static boolean versionEqOrGt(int major, int minor, int bugfix) {
|
||||
if (MAJOR > major) {
|
||||
return true;
|
||||
}
|
||||
if (MAJOR == major) {
|
||||
if (MINOR > minor) {
|
||||
return true;
|
||||
} else if (MINOR == minor) {
|
||||
if (BUGFIX >= bugfix) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ChannelHandler.Sharable
|
||||
private static class ServerSocketTestHandler extends ChannelInboundHandlerAdapter {
|
||||
private final AtomicBoolean accepted;
|
||||
|
||||
ServerSocketTestHandler(AtomicBoolean accepted) {
|
||||
this.accepted = accepted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
||||
accepted.set(true);
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
@ChannelHandler.Sharable
|
||||
private static class DatagramSocketTestHandler extends ChannelInboundHandlerAdapter {
|
||||
private final AtomicBoolean received;
|
||||
|
||||
DatagramSocketTestHandler(AtomicBoolean received) {
|
||||
this.received = received;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
ReferenceCountUtil.release(msg);
|
||||
received.set(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ChannelHandler.Sharable
|
||||
private static final class DummyHandler extends ChannelHandlerAdapter { }
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright 2016 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:
|
||||
*
|
||||
* https://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.ServerBootstrap;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.function.Executable;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class EpollServerSocketChannelConfigTest {
|
||||
|
||||
private static EventLoopGroup group;
|
||||
private static EpollServerSocketChannel ch;
|
||||
|
||||
@BeforeAll
|
||||
public static void before() {
|
||||
group = new EpollEventLoopGroup(1);
|
||||
ServerBootstrap bootstrap = new ServerBootstrap();
|
||||
ch = (EpollServerSocketChannel) bootstrap.group(group)
|
||||
.channel(EpollServerSocketChannel.class)
|
||||
.childHandler(new ChannelInboundHandlerAdapter())
|
||||
.bind(new InetSocketAddress(0)).syncUninterruptibly().channel();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void after() {
|
||||
try {
|
||||
ch.close().syncUninterruptibly();
|
||||
} finally {
|
||||
group.shutdownGracefully();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTcpDeferAccept() {
|
||||
ch.config().setTcpDeferAccept(0);
|
||||
assertEquals(0, ch.config().getTcpDeferAccept());
|
||||
ch.config().setTcpDeferAccept(10);
|
||||
// The returned value may be bigger then what we set.
|
||||
// See https://www.spinics.net/lists/netdev/msg117330.html
|
||||
assertTrue(10 <= ch.config().getTcpDeferAccept());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReusePort() {
|
||||
ch.config().setReusePort(false);
|
||||
assertFalse(ch.config().isReusePort());
|
||||
ch.config().setReusePort(true);
|
||||
assertTrue(ch.config().isReusePort());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFreeBind() {
|
||||
ch.config().setFreeBind(false);
|
||||
assertFalse(ch.config().isFreeBind());
|
||||
ch.config().setFreeBind(true);
|
||||
assertTrue(ch.config().isFreeBind());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getGetOptions() {
|
||||
Map<ChannelOption<?>, Object> map = ch.config().getOptions();
|
||||
assertFalse(map.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFastOpen() {
|
||||
assertThrows(IllegalArgumentException.class, new Executable() {
|
||||
@Override
|
||||
public void execute() {
|
||||
ch.config().setTcpFastopen(-1);
|
||||
}
|
||||
});
|
||||
ch.config().setTcpFastopen(10);
|
||||
assertEquals(10, ch.config().getTcpFastopen());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright 2023 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketAddressesTest;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class EpollSocketAddressesTest extends SocketAddressesTest {
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.socketWithFastOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assertAddress(SocketAddress address) {
|
||||
assertTrue(((InetSocketAddress) address).getPort() > 0);
|
||||
assertFalse(((InetSocketAddress) address).getAddress().isAnyLocalAddress());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
* Copyright 2015 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:
|
||||
*
|
||||
* https://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.github.artsok.RepeatedIfExceptionsTest;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.ChannelException;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.function.Executable;
|
||||
import org.opentest4j.TestAbortedException;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
public class EpollSocketChannelConfigTest {
|
||||
|
||||
private static EventLoopGroup group;
|
||||
private static EpollSocketChannel ch;
|
||||
private static Random rand;
|
||||
|
||||
@BeforeAll
|
||||
public static void beforeClass() {
|
||||
rand = new Random();
|
||||
group = new EpollEventLoopGroup(1);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void afterClass() {
|
||||
group.shutdownGracefully();
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
Bootstrap bootstrap = new Bootstrap();
|
||||
ch = (EpollSocketChannel) bootstrap.group(group)
|
||||
.channel(EpollSocketChannel.class)
|
||||
.handler(new ChannelInboundHandlerAdapter())
|
||||
.bind(new InetSocketAddress(0)).syncUninterruptibly().channel();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void teardown() {
|
||||
ch.close().syncUninterruptibly();
|
||||
}
|
||||
|
||||
private static long randLong(long min, long max) {
|
||||
return min + nextLong(max - min + 1);
|
||||
}
|
||||
|
||||
private static long nextLong(long n) {
|
||||
long bits, val;
|
||||
do {
|
||||
bits = (rand.nextLong() << 1) >>> 1;
|
||||
val = bits % n;
|
||||
} while (bits - val + (n - 1) < 0L);
|
||||
return val;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRandomTcpNotSentLowAt() {
|
||||
final long expected = randLong(0, 0xFFFFFFFFL);
|
||||
final long actual;
|
||||
try {
|
||||
ch.config().setTcpNotSentLowAt(expected);
|
||||
actual = ch.config().getTcpNotSentLowAt();
|
||||
} catch (RuntimeException e) {
|
||||
throw new TestAbortedException("assumeNoException", e);
|
||||
}
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidHighTcpNotSentLowAt() {
|
||||
try {
|
||||
final long value = 0xFFFFFFFFL + 1;
|
||||
ch.config().setTcpNotSentLowAt(value);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return;
|
||||
} catch (RuntimeException e) {
|
||||
throw new TestAbortedException("assumeNoException", e);
|
||||
}
|
||||
fail();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidLowTcpNotSentLowAt() {
|
||||
try {
|
||||
final long value = -1;
|
||||
ch.config().setTcpNotSentLowAt(value);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return;
|
||||
} catch (RuntimeException e) {
|
||||
throw new TestAbortedException("assumeNoException", e);
|
||||
}
|
||||
fail();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTcpCork() {
|
||||
ch.config().setTcpCork(false);
|
||||
assertFalse(ch.config().isTcpCork());
|
||||
ch.config().setTcpCork(true);
|
||||
assertTrue(ch.config().isTcpCork());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTcpQickAck() {
|
||||
ch.config().setTcpQuickAck(false);
|
||||
assertFalse(ch.config().isTcpQuickAck());
|
||||
ch.config().setTcpQuickAck(true);
|
||||
assertTrue(ch.config().isTcpQuickAck());
|
||||
}
|
||||
|
||||
// For this test to pass, we are relying on the sockets file descriptor not being reused after the socket is closed.
|
||||
// This is inherently racy, so we allow getSoLinger to throw ChannelException a few of times, but eventually we do
|
||||
// want to see a ClosedChannelException for the test to pass.
|
||||
@RepeatedIfExceptionsTest(repeats = 4)
|
||||
public void testSetOptionWhenClosed() {
|
||||
ch.close().syncUninterruptibly();
|
||||
ChannelException e = assertThrows(ChannelException.class, new Executable() {
|
||||
@Override
|
||||
public void execute() throws Throwable {
|
||||
ch.config().setSoLinger(0);
|
||||
}
|
||||
});
|
||||
assertThat(e).hasCauseInstanceOf(ClosedChannelException.class);
|
||||
}
|
||||
|
||||
// For this test to pass, we are relying on the sockets file descriptor not being reused after the socket is closed.
|
||||
// This is inherently racy, so we allow getSoLinger to throw ChannelException a few of times, but eventually we do
|
||||
// want to see a ClosedChannelException for the test to pass.
|
||||
@RepeatedIfExceptionsTest(repeats = 4)
|
||||
public void testGetOptionWhenClosed() {
|
||||
ch.close().syncUninterruptibly();
|
||||
ChannelException e = assertThrows(ChannelException.class, new Executable() {
|
||||
@Override
|
||||
public void execute() throws Throwable {
|
||||
ch.config().getSoLinger();
|
||||
}
|
||||
});
|
||||
assertThat(e).hasCauseInstanceOf(ClosedChannelException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getGetOptions() {
|
||||
Map<ChannelOption<?>, Object> map = ch.config().getOptions();
|
||||
assertFalse(map.isEmpty());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright 2016 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:
|
||||
*
|
||||
* https://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.SocketChannelNotYetConnectedTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollSocketChannelNotYetConnectedTest extends SocketChannelNotYetConnectedTest {
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapFactory<Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.clientSocketWithFastOpen();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Copyright 2014 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:
|
||||
*
|
||||
* https://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.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class EpollSocketChannelTest {
|
||||
|
||||
@Test
|
||||
public void testTcpInfo() throws Exception {
|
||||
EventLoopGroup group = new EpollEventLoopGroup(1);
|
||||
|
||||
try {
|
||||
Bootstrap bootstrap = new Bootstrap();
|
||||
EpollSocketChannel ch = (EpollSocketChannel) bootstrap.group(group)
|
||||
.channel(EpollSocketChannel.class)
|
||||
.handler(new ChannelInboundHandlerAdapter())
|
||||
.bind(new InetSocketAddress(0)).syncUninterruptibly().channel();
|
||||
EpollTcpInfo info = ch.tcpInfo();
|
||||
assertTcpInfo0(info);
|
||||
ch.close().syncUninterruptibly();
|
||||
} finally {
|
||||
group.shutdownGracefully();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTcpInfoReuse() throws Exception {
|
||||
EventLoopGroup group = new EpollEventLoopGroup(1);
|
||||
|
||||
try {
|
||||
Bootstrap bootstrap = new Bootstrap();
|
||||
EpollSocketChannel ch = (EpollSocketChannel) bootstrap.group(group)
|
||||
.channel(EpollSocketChannel.class)
|
||||
.handler(new ChannelInboundHandlerAdapter())
|
||||
.bind(new InetSocketAddress(0)).syncUninterruptibly().channel();
|
||||
EpollTcpInfo info = new EpollTcpInfo();
|
||||
ch.tcpInfo(info);
|
||||
assertTcpInfo0(info);
|
||||
ch.close().syncUninterruptibly();
|
||||
} finally {
|
||||
group.shutdownGracefully();
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertTcpInfo0(EpollTcpInfo info) throws Exception {
|
||||
assertNotNull(info);
|
||||
|
||||
assertTrue(info.state() >= 0);
|
||||
assertTrue(info.caState() >= 0);
|
||||
assertTrue(info.retransmits() >= 0);
|
||||
assertTrue(info.probes() >= 0);
|
||||
assertTrue(info.backoff() >= 0);
|
||||
assertTrue(info.options() >= 0);
|
||||
assertTrue(info.sndWscale() >= 0);
|
||||
assertTrue(info.rcvWscale() >= 0);
|
||||
assertTrue(info.rto() >= 0);
|
||||
assertTrue(info.ato() >= 0);
|
||||
assertTrue(info.sndMss() >= 0);
|
||||
assertTrue(info.rcvMss() >= 0);
|
||||
assertTrue(info.unacked() >= 0);
|
||||
assertTrue(info.sacked() >= 0);
|
||||
assertTrue(info.lost() >= 0);
|
||||
assertTrue(info.retrans() >= 0);
|
||||
assertTrue(info.fackets() >= 0);
|
||||
assertTrue(info.lastDataSent() >= 0);
|
||||
assertTrue(info.lastAckSent() >= 0);
|
||||
assertTrue(info.lastDataRecv() >= 0);
|
||||
assertTrue(info.lastAckRecv() >= 0);
|
||||
assertTrue(info.pmtu() >= 0);
|
||||
assertTrue(info.rcvSsthresh() >= 0);
|
||||
assertTrue(info.rtt() >= 0);
|
||||
assertTrue(info.rttvar() >= 0);
|
||||
assertTrue(info.sndSsthresh() >= 0);
|
||||
assertTrue(info.sndCwnd() >= 0);
|
||||
assertTrue(info.advmss() >= 0);
|
||||
assertTrue(info.reordering() >= 0);
|
||||
assertTrue(info.rcvRtt() >= 0);
|
||||
assertTrue(info.rcvSpace() >= 0);
|
||||
assertTrue(info.totalRetrans() >= 0);
|
||||
}
|
||||
|
||||
// See https://github.com/netty/netty/issues/7159
|
||||
@Test
|
||||
public void testSoLingerNoAssertError() throws Exception {
|
||||
EventLoopGroup group = new EpollEventLoopGroup(1);
|
||||
|
||||
try {
|
||||
Bootstrap bootstrap = new Bootstrap();
|
||||
EpollSocketChannel ch = (EpollSocketChannel) bootstrap.group(group)
|
||||
.channel(EpollSocketChannel.class)
|
||||
.option(ChannelOption.SO_LINGER, 10)
|
||||
.handler(new ChannelInboundHandlerAdapter())
|
||||
.bind(new InetSocketAddress(0)).syncUninterruptibly().channel();
|
||||
ch.close().syncUninterruptibly();
|
||||
} finally {
|
||||
group.shutdownGracefully();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright 2017 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketCloseForciblyTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollSocketCloseForciblyTest extends SocketCloseForciblyTest {
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.socketWithoutFastOpen();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright 2016 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketConnectTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollSocketConnectTest extends SocketConnectTest {
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.socketWithoutFastOpen();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright 2015 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:
|
||||
*
|
||||
* https://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.SocketConnectionAttemptTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollSocketConnectionAttemptTest extends SocketConnectionAttemptTest {
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapFactory<Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.clientSocket();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright 2014 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketEchoTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollSocketEchoTest extends SocketEchoTest {
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.socketWithFastOpen();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright 2014 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketFileRegionTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollSocketFileRegionTest extends SocketFileRegionTest {
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.socketWithFastOpen();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright 2014 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketFixedLengthEchoTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollSocketFixedLengthEchoTest extends SocketFixedLengthEchoTest {
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.socketWithFastOpen();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright 2014 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketGatheringWriteTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollSocketGatheringWriteTest extends SocketGatheringWriteTest {
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.socketWithoutFastOpen();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright 2016 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketMultipleConnectTest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class EpollSocketMultipleConnectTest extends SocketMultipleConnectTest {
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> factories
|
||||
= new ArrayList<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>>();
|
||||
for (TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap> comboFactory
|
||||
: EpollSocketTestPermutation.INSTANCE.socketWithFastOpen()) {
|
||||
EventLoopGroup group = comboFactory.newClientInstance().config().group();
|
||||
if (group instanceof NioEventLoopGroup || group instanceof EpollEventLoopGroup) {
|
||||
factories.add(comboFactory);
|
||||
}
|
||||
}
|
||||
return factories;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright 2014 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketObjectEchoTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollSocketObjectEchoTest extends SocketObjectEchoTest {
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.socketWithFastOpen();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright 2016 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.unix.Errors;
|
||||
import io.netty.channel.unix.Errors.NativeIoException;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketRstTest;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class EpollSocketRstTest extends SocketRstTest {
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.socketWithoutFastOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assertRstOnCloseException(IOException cause, Channel clientChannel) {
|
||||
if (!AbstractEpollChannel.class.isInstance(clientChannel)) {
|
||||
super.assertRstOnCloseException(cause, clientChannel);
|
||||
return;
|
||||
}
|
||||
|
||||
assertTrue(cause instanceof NativeIoException,
|
||||
"actual [type, message]: [" + cause.getClass() + ", " + cause.getMessage() + "]");
|
||||
assertEquals(Errors.ERRNO_ECONNRESET_NEGATIVE, ((NativeIoException) cause).expectedErr());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright 2016 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:
|
||||
*
|
||||
* https://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.ServerBootstrap;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketShutdownOutputByPeerTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollSocketShutdownOutputByPeerTest extends SocketShutdownOutputByPeerTest {
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapFactory<ServerBootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.serverSocket();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright 2016 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:
|
||||
*
|
||||
* https://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.SocketShutdownOutputBySelfTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollSocketShutdownOutputBySelfTest extends SocketShutdownOutputBySelfTest {
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapFactory<Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.clientSocket();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketSslClientRenegotiateTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollSocketSslClientRenegotiateTest extends SocketSslClientRenegotiateTest {
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.socketWithFastOpen();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright 2014 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketSslEchoTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollSocketSslEchoTest extends SocketSslEchoTest {
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.socketWithFastOpen();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright 2014 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketSslGreetingTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollSocketSslGreetingTest extends SocketSslGreetingTest {
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.socketWithFastOpen();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketSslSessionReuseTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollSocketSslSessionReuseTest extends SocketSslSessionReuseTest {
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.socketWithFastOpen();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright 2014 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketStartTlsTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollSocketStartTlsTest extends SocketStartTlsTest {
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.socketWithFastOpen();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright 2018 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.SelectStrategy;
|
||||
import io.netty.channel.SelectStrategyFactory;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation.BootstrapComboFactory;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation.BootstrapFactory;
|
||||
import io.netty.testsuite.transport.socket.SocketStringEchoTest;
|
||||
import io.netty.util.IntSupplier;
|
||||
import io.netty.util.concurrent.DefaultThreadFactory;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class EpollSocketStringEchoBusyWaitTest extends SocketStringEchoTest {
|
||||
|
||||
private static EventLoopGroup EPOLL_LOOP;
|
||||
|
||||
@BeforeAll
|
||||
public static void setup() throws Exception {
|
||||
EPOLL_LOOP = new EpollEventLoopGroup(2, new DefaultThreadFactory("testsuite-epoll-busy-wait", true),
|
||||
new SelectStrategyFactory() {
|
||||
@Override
|
||||
public SelectStrategy newSelectStrategy() {
|
||||
return new SelectStrategy() {
|
||||
@Override
|
||||
public int calculateStrategy(IntSupplier selectSupplier, boolean hasTasks) {
|
||||
return SelectStrategy.BUSY_WAIT;
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void teardown() throws Exception {
|
||||
if (EPOLL_LOOP != null) {
|
||||
EPOLL_LOOP.shutdownGracefully();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
List<BootstrapComboFactory<ServerBootstrap, Bootstrap>> list =
|
||||
new ArrayList<BootstrapComboFactory<ServerBootstrap, Bootstrap>>();
|
||||
final BootstrapFactory<ServerBootstrap> sbf = serverSocket();
|
||||
final BootstrapFactory<Bootstrap> cbf = clientSocket();
|
||||
list.add(new BootstrapComboFactory<ServerBootstrap, Bootstrap>() {
|
||||
@Override
|
||||
public ServerBootstrap newServerInstance() {
|
||||
return sbf.newInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bootstrap newClientInstance() {
|
||||
return cbf.newInstance();
|
||||
}
|
||||
});
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private static BootstrapFactory<ServerBootstrap> serverSocket() {
|
||||
return new BootstrapFactory<ServerBootstrap>() {
|
||||
@Override
|
||||
public ServerBootstrap newInstance() {
|
||||
return new ServerBootstrap().group(EPOLL_LOOP, EPOLL_LOOP).channel(EpollServerSocketChannel.class);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static BootstrapFactory<Bootstrap> clientSocket() {
|
||||
return new BootstrapFactory<Bootstrap>() {
|
||||
@Override
|
||||
public Bootstrap newInstance() {
|
||||
return new Bootstrap().group(EPOLL_LOOP).channel(EpollSocketChannel.class);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright 2014 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.socket.SocketStringEchoTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollSocketStringEchoTest extends SocketStringEchoTest {
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.socketWithFastOpen();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Copyright 2015 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:
|
||||
*
|
||||
* https://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.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.ConnectTimeoutException;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.util.CharsetUtil;
|
||||
import io.netty.util.NetUtil;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.function.Executable;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
public class EpollSocketTcpMd5Test {
|
||||
private static final byte[] SERVER_KEY = "abc".getBytes(CharsetUtil.US_ASCII);
|
||||
private static final byte[] BAD_KEY = "def".getBytes(CharsetUtil.US_ASCII);
|
||||
private static EventLoopGroup GROUP;
|
||||
private EpollServerSocketChannel server;
|
||||
|
||||
@BeforeAll
|
||||
public static void beforeClass() {
|
||||
GROUP = new EpollEventLoopGroup(1);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void afterClass() {
|
||||
GROUP.shutdownGracefully();
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
Bootstrap bootstrap = new Bootstrap();
|
||||
server = (EpollServerSocketChannel) bootstrap.group(GROUP)
|
||||
.channel(EpollServerSocketChannel.class)
|
||||
.handler(new ChannelInboundHandlerAdapter())
|
||||
.bind(new InetSocketAddress(NetUtil.LOCALHOST4, 0)).syncUninterruptibly().channel();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void teardown() {
|
||||
server.close().syncUninterruptibly();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerSocketChannelOption() throws Exception {
|
||||
server.config().setOption(EpollChannelOption.TCP_MD5SIG,
|
||||
Collections.<InetAddress, byte[]>singletonMap(NetUtil.LOCALHOST4, SERVER_KEY));
|
||||
server.config().setOption(EpollChannelOption.TCP_MD5SIG, Collections.<InetAddress, byte[]>emptyMap());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerOption() throws Exception {
|
||||
Bootstrap bootstrap = new Bootstrap();
|
||||
EpollServerSocketChannel ch = (EpollServerSocketChannel) bootstrap.group(GROUP)
|
||||
.channel(EpollServerSocketChannel.class)
|
||||
.handler(new ChannelInboundHandlerAdapter())
|
||||
.bind(new InetSocketAddress(0)).syncUninterruptibly().channel();
|
||||
|
||||
ch.config().setOption(EpollChannelOption.TCP_MD5SIG,
|
||||
Collections.<InetAddress, byte[]>singletonMap(NetUtil.LOCALHOST4, SERVER_KEY));
|
||||
ch.config().setOption(EpollChannelOption.TCP_MD5SIG, Collections.<InetAddress, byte[]>emptyMap());
|
||||
|
||||
ch.close().syncUninterruptibly();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyMismatch() throws Exception {
|
||||
server.config().setOption(EpollChannelOption.TCP_MD5SIG,
|
||||
Collections.<InetAddress, byte[]>singletonMap(NetUtil.LOCALHOST4, SERVER_KEY));
|
||||
|
||||
assertThrows(ConnectTimeoutException.class, new Executable() {
|
||||
@Override
|
||||
public void execute() throws Throwable {
|
||||
EpollSocketChannel client = (EpollSocketChannel) new Bootstrap().group(GROUP)
|
||||
.channel(EpollSocketChannel.class)
|
||||
.handler(new ChannelInboundHandlerAdapter())
|
||||
.option(EpollChannelOption.TCP_MD5SIG,
|
||||
Collections.<InetAddress, byte[]>singletonMap(NetUtil.LOCALHOST4, BAD_KEY))
|
||||
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 1000)
|
||||
.connect(server.localAddress()).syncUninterruptibly().channel();
|
||||
client.close().syncUninterruptibly();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyMatch() throws Exception {
|
||||
server.config().setOption(EpollChannelOption.TCP_MD5SIG,
|
||||
Collections.<InetAddress, byte[]>singletonMap(NetUtil.LOCALHOST4, SERVER_KEY));
|
||||
|
||||
EpollSocketChannel client = (EpollSocketChannel) new Bootstrap().group(GROUP)
|
||||
.channel(EpollSocketChannel.class)
|
||||
.handler(new ChannelInboundHandlerAdapter())
|
||||
.option(EpollChannelOption.TCP_MD5SIG,
|
||||
Collections.<InetAddress, byte[]>singletonMap(NetUtil.LOCALHOST4, SERVER_KEY))
|
||||
.connect(server.localAddress()).syncUninterruptibly().channel();
|
||||
client.close().syncUninterruptibly();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright 2016 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:
|
||||
*
|
||||
* https://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.channel.unix.DomainSocketAddress;
|
||||
import io.netty.channel.unix.PeerCredentials;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class EpollSocketTest extends SocketTest<LinuxSocket> {
|
||||
@BeforeAll
|
||||
public static void loadJNI() {
|
||||
Epoll.ensureAvailability();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTcpCork() throws Exception {
|
||||
assertFalse(socket.isTcpCork());
|
||||
socket.setTcpCork(true);
|
||||
assertTrue(socket.isTcpCork());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPeerCreds() throws IOException {
|
||||
LinuxSocket s1 = LinuxSocket.newSocketDomain();
|
||||
LinuxSocket s2 = LinuxSocket.newSocketDomain();
|
||||
|
||||
try {
|
||||
DomainSocketAddress dsa = UnixTestUtils.newDomainSocketAddress();
|
||||
s1.bind(dsa);
|
||||
s1.listen(1);
|
||||
|
||||
assertTrue(s2.connect(dsa));
|
||||
byte [] addr = new byte[64];
|
||||
s1.accept(addr);
|
||||
PeerCredentials pc = s1.getPeerCredentials();
|
||||
assertNotEquals(pc.uid(), -1);
|
||||
} finally {
|
||||
s1.close();
|
||||
s2.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LinuxSocket newSocket() {
|
||||
return LinuxSocket.newSocketStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int level() {
|
||||
// Value for SOL_SOCKET
|
||||
// See https://github.com/torvalds/linux/blob/v5.17/include/uapi/asm-generic/socket.h
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int optname() {
|
||||
// Value for SO_REUSEADDR
|
||||
// See https://github.com/torvalds/linux/blob/v5.17/include/uapi/asm-generic/socket.h
|
||||
return 2;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,264 @@
|
|||
/*
|
||||
* Copyright 2014 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFactory;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.socket.InternetProtocolFamily;
|
||||
import io.netty.channel.socket.nio.NioDatagramChannel;
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import io.netty.channel.unix.DomainSocketAddress;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation;
|
||||
import io.netty.testsuite.transport.TestsuitePermutation.BootstrapFactory;
|
||||
import io.netty.testsuite.transport.socket.SocketTestPermutation;
|
||||
import io.netty.util.concurrent.DefaultThreadFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static io.netty.channel.epoll.Native.IS_SUPPORTING_TCP_FASTOPEN_CLIENT;
|
||||
import static io.netty.channel.epoll.Native.IS_SUPPORTING_TCP_FASTOPEN_SERVER;
|
||||
|
||||
class EpollSocketTestPermutation extends SocketTestPermutation {
|
||||
|
||||
static final EpollSocketTestPermutation INSTANCE = new EpollSocketTestPermutation();
|
||||
|
||||
static final EventLoopGroup EPOLL_BOSS_GROUP =
|
||||
new EpollEventLoopGroup(BOSSES, new DefaultThreadFactory("testsuite-epoll-boss", true));
|
||||
static final EventLoopGroup EPOLL_WORKER_GROUP =
|
||||
new EpollEventLoopGroup(WORKERS, new DefaultThreadFactory("testsuite-epoll-worker", true));
|
||||
|
||||
@Override
|
||||
public List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> socket() {
|
||||
List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> list =
|
||||
combo(serverSocket(), clientSocketWithFastOpen());
|
||||
|
||||
list.remove(list.size() - 1); // Exclude NIO x NIO test
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> socketWithoutFastOpen() {
|
||||
List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> list =
|
||||
combo(serverSocket(), clientSocket());
|
||||
|
||||
list.remove(list.size() - 1); // Exclude NIO x NIO test
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BootstrapFactory<ServerBootstrap>> serverSocket() {
|
||||
List<BootstrapFactory<ServerBootstrap>> toReturn = new ArrayList<BootstrapFactory<ServerBootstrap>>();
|
||||
toReturn.add(new BootstrapFactory<ServerBootstrap>() {
|
||||
@Override
|
||||
public ServerBootstrap newInstance() {
|
||||
return new ServerBootstrap().group(EPOLL_BOSS_GROUP, EPOLL_WORKER_GROUP)
|
||||
.channel(EpollServerSocketChannel.class);
|
||||
}
|
||||
});
|
||||
if (IS_SUPPORTING_TCP_FASTOPEN_SERVER) {
|
||||
toReturn.add(new BootstrapFactory<ServerBootstrap>() {
|
||||
@Override
|
||||
public ServerBootstrap newInstance() {
|
||||
ServerBootstrap serverBootstrap = new ServerBootstrap().group(EPOLL_BOSS_GROUP, EPOLL_WORKER_GROUP)
|
||||
.channel(EpollServerSocketChannel.class);
|
||||
serverBootstrap.option(ChannelOption.TCP_FASTOPEN, 5);
|
||||
return serverBootstrap;
|
||||
}
|
||||
});
|
||||
}
|
||||
toReturn.add(new BootstrapFactory<ServerBootstrap>() {
|
||||
@Override
|
||||
public ServerBootstrap newInstance() {
|
||||
return new ServerBootstrap().group(nioBossGroup, nioWorkerGroup)
|
||||
.channel(NioServerSocketChannel.class);
|
||||
}
|
||||
});
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BootstrapFactory<Bootstrap>> clientSocket() {
|
||||
List<BootstrapFactory<Bootstrap>> toReturn = new ArrayList<BootstrapFactory<Bootstrap>>();
|
||||
|
||||
toReturn.add(new BootstrapFactory<Bootstrap>() {
|
||||
@Override
|
||||
public Bootstrap newInstance() {
|
||||
return new Bootstrap().group(EPOLL_WORKER_GROUP).channel(EpollSocketChannel.class);
|
||||
}
|
||||
});
|
||||
|
||||
toReturn.add(new BootstrapFactory<Bootstrap>() {
|
||||
@Override
|
||||
public Bootstrap newInstance() {
|
||||
return new Bootstrap().group(nioWorkerGroup).channel(NioSocketChannel.class);
|
||||
}
|
||||
});
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BootstrapFactory<Bootstrap>> clientSocketWithFastOpen() {
|
||||
List<BootstrapFactory<Bootstrap>> factories = clientSocket();
|
||||
|
||||
if (IS_SUPPORTING_TCP_FASTOPEN_CLIENT) {
|
||||
int insertIndex = factories.size() - 1; // Keep NIO fixture last.
|
||||
factories.add(insertIndex, new BootstrapFactory<Bootstrap>() {
|
||||
@Override
|
||||
public Bootstrap newInstance() {
|
||||
return new Bootstrap().group(EPOLL_WORKER_GROUP).channel(EpollSocketChannel.class)
|
||||
.option(ChannelOption.TCP_FASTOPEN_CONNECT, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return factories;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TestsuitePermutation.BootstrapComboFactory<Bootstrap, Bootstrap>> datagram(
|
||||
final InternetProtocolFamily family) {
|
||||
// Make the list of Bootstrap factories.
|
||||
List<BootstrapFactory<Bootstrap>> bfs = Arrays.asList(
|
||||
new BootstrapFactory<Bootstrap>() {
|
||||
@Override
|
||||
public Bootstrap newInstance() {
|
||||
return new Bootstrap().group(nioWorkerGroup).channelFactory(new ChannelFactory<Channel>() {
|
||||
@Override
|
||||
public Channel newChannel() {
|
||||
return new NioDatagramChannel(family);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return NioDatagramChannel.class.getSimpleName() + ".class";
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
new BootstrapFactory<Bootstrap>() {
|
||||
@Override
|
||||
public Bootstrap newInstance() {
|
||||
return new Bootstrap().group(EPOLL_WORKER_GROUP).channelFactory(new ChannelFactory<Channel>() {
|
||||
@Override
|
||||
public Channel newChannel() {
|
||||
return new EpollDatagramChannel(family);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return InternetProtocolFamily.class.getSimpleName() + ".class";
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
return combo(bfs, bfs);
|
||||
}
|
||||
|
||||
List<TestsuitePermutation.BootstrapComboFactory<Bootstrap, Bootstrap>> epollOnlyDatagram(
|
||||
final InternetProtocolFamily family) {
|
||||
return combo(Collections.singletonList(datagramBootstrapFactory(family)),
|
||||
Collections.singletonList(datagramBootstrapFactory(family)));
|
||||
}
|
||||
|
||||
private static BootstrapFactory<Bootstrap> datagramBootstrapFactory(final InternetProtocolFamily family) {
|
||||
return new BootstrapFactory<Bootstrap>() {
|
||||
@Override
|
||||
public Bootstrap newInstance() {
|
||||
return new Bootstrap().group(EPOLL_WORKER_GROUP).channelFactory(new ChannelFactory<Channel>() {
|
||||
@Override
|
||||
public Channel newChannel() {
|
||||
return new EpollDatagramChannel(family);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return InternetProtocolFamily.class.getSimpleName() + ".class";
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public List<TestsuitePermutation.BootstrapComboFactory<ServerBootstrap, Bootstrap>> domainSocket() {
|
||||
return combo(serverDomainSocket(), clientDomainSocket());
|
||||
}
|
||||
|
||||
public List<BootstrapFactory<ServerBootstrap>> serverDomainSocket() {
|
||||
return Collections.<BootstrapFactory<ServerBootstrap>>singletonList(
|
||||
new BootstrapFactory<ServerBootstrap>() {
|
||||
@Override
|
||||
public ServerBootstrap newInstance() {
|
||||
return new ServerBootstrap().group(EPOLL_BOSS_GROUP, EPOLL_WORKER_GROUP)
|
||||
.channel(EpollServerDomainSocketChannel.class);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public List<BootstrapFactory<Bootstrap>> clientDomainSocket() {
|
||||
return Collections.<BootstrapFactory<Bootstrap>>singletonList(
|
||||
new BootstrapFactory<Bootstrap>() {
|
||||
@Override
|
||||
public Bootstrap newInstance() {
|
||||
return new Bootstrap().group(EPOLL_WORKER_GROUP).channel(EpollDomainSocketChannel.class);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BootstrapFactory<Bootstrap>> datagramSocket() {
|
||||
return Collections.<BootstrapFactory<Bootstrap>>singletonList(
|
||||
new BootstrapFactory<Bootstrap>() {
|
||||
@Override
|
||||
public Bootstrap newInstance() {
|
||||
return new Bootstrap().group(EPOLL_WORKER_GROUP).channel(EpollDatagramChannel.class);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public List<TestsuitePermutation.BootstrapComboFactory<Bootstrap, Bootstrap>> domainDatagram() {
|
||||
return combo(domainDatagramSocket(), domainDatagramSocket());
|
||||
}
|
||||
|
||||
public List<BootstrapFactory<Bootstrap>> domainDatagramSocket() {
|
||||
return Collections.<BootstrapFactory<Bootstrap>>singletonList(
|
||||
new BootstrapFactory<Bootstrap>() {
|
||||
@Override
|
||||
public Bootstrap newInstance() {
|
||||
return new Bootstrap().group(EPOLL_WORKER_GROUP).channel(EpollDomainDatagramChannel.class);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public static DomainSocketAddress newDomainSocketAddress() {
|
||||
return UnixTestUtils.newDomainSocketAddress();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,313 @@
|
|||
/*
|
||||
* Copyright 2015 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:
|
||||
*
|
||||
* https://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.bootstrap.ServerBootstrap;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.channel.unix.FileDescriptor;
|
||||
import io.netty.util.NetUtil;
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.Timeout;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class EpollSpliceTest {
|
||||
|
||||
private static final int SPLICE_LEN = 32 * 1024;
|
||||
private static final Random random = new Random();
|
||||
private static final byte[] data = new byte[1048576];
|
||||
|
||||
static {
|
||||
random.nextBytes(data);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void spliceToSocket() throws Throwable {
|
||||
final EchoHandler sh = new EchoHandler();
|
||||
final EchoHandler ch = new EchoHandler();
|
||||
|
||||
EventLoopGroup group = new EpollEventLoopGroup(1);
|
||||
ServerBootstrap bs = new ServerBootstrap();
|
||||
bs.channel(EpollServerSocketChannel.class);
|
||||
bs.group(group).childHandler(sh);
|
||||
final Channel sc = bs.bind(NetUtil.LOCALHOST, 0).syncUninterruptibly().channel();
|
||||
|
||||
ServerBootstrap bs2 = new ServerBootstrap();
|
||||
bs2.channel(EpollServerSocketChannel.class);
|
||||
bs2.childOption(EpollChannelOption.EPOLL_MODE, EpollMode.LEVEL_TRIGGERED);
|
||||
bs2.group(group).childHandler(new ChannelInboundHandlerAdapter() {
|
||||
@Override
|
||||
public void channelActive(final ChannelHandlerContext ctx) throws Exception {
|
||||
ctx.channel().config().setAutoRead(false);
|
||||
Bootstrap bs = new Bootstrap();
|
||||
bs.option(EpollChannelOption.EPOLL_MODE, EpollMode.LEVEL_TRIGGERED);
|
||||
|
||||
bs.channel(EpollSocketChannel.class);
|
||||
bs.group(ctx.channel().eventLoop()).handler(new ChannelInboundHandlerAdapter() {
|
||||
@Override
|
||||
public void channelActive(ChannelHandlerContext context) throws Exception {
|
||||
final EpollSocketChannel ch = (EpollSocketChannel) ctx.channel();
|
||||
final EpollSocketChannel ch2 = (EpollSocketChannel) context.channel();
|
||||
// We are splicing two channels together, at this point we have a tcp proxy which handles all
|
||||
// the data transfer only in kernel space!
|
||||
|
||||
// Integer.MAX_VALUE will splice infinitely.
|
||||
ch.spliceTo(ch2, Integer.MAX_VALUE).addListener(new ChannelFutureListener() {
|
||||
@Override
|
||||
public void operationComplete(ChannelFuture future) throws Exception {
|
||||
if (!future.isSuccess()) {
|
||||
future.channel().close();
|
||||
}
|
||||
}
|
||||
});
|
||||
// Trigger multiple splices to see if partial splicing works as well.
|
||||
ch2.spliceTo(ch, SPLICE_LEN).addListener(new ChannelFutureListener() {
|
||||
@Override
|
||||
public void operationComplete(ChannelFuture future) throws Exception {
|
||||
if (!future.isSuccess()) {
|
||||
future.channel().close();
|
||||
} else {
|
||||
ch2.spliceTo(ch, SPLICE_LEN).addListener(this);
|
||||
}
|
||||
}
|
||||
});
|
||||
ctx.channel().config().setAutoRead(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelInactive(ChannelHandlerContext context) throws Exception {
|
||||
context.close();
|
||||
}
|
||||
});
|
||||
bs.connect(sc.localAddress()).addListener(new ChannelFutureListener() {
|
||||
@Override
|
||||
public void operationComplete(ChannelFuture future) throws Exception {
|
||||
if (!future.isSuccess()) {
|
||||
ctx.close();
|
||||
} else {
|
||||
future.channel().closeFuture().addListener(new ChannelFutureListener() {
|
||||
@Override
|
||||
public void operationComplete(ChannelFuture future) throws Exception {
|
||||
ctx.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
Channel pc = bs2.bind(NetUtil.LOCALHOST, 0).syncUninterruptibly().channel();
|
||||
|
||||
Bootstrap cb = new Bootstrap();
|
||||
cb.group(group);
|
||||
cb.channel(EpollSocketChannel.class);
|
||||
cb.handler(ch);
|
||||
Channel cc = cb.connect(pc.localAddress()).syncUninterruptibly().channel();
|
||||
|
||||
for (int i = 0; i < data.length;) {
|
||||
int length = Math.min(random.nextInt(1024 * 64), data.length - i);
|
||||
ByteBuf buf = Unpooled.wrappedBuffer(data, i, length);
|
||||
cc.writeAndFlush(buf);
|
||||
i += length;
|
||||
}
|
||||
|
||||
while (ch.counter < data.length) {
|
||||
if (sh.exception.get() != null) {
|
||||
break;
|
||||
}
|
||||
if (ch.exception.get() != null) {
|
||||
break;
|
||||
}
|
||||
|
||||
Thread.sleep(50);
|
||||
}
|
||||
|
||||
while (sh.counter < data.length) {
|
||||
if (sh.exception.get() != null) {
|
||||
break;
|
||||
}
|
||||
if (ch.exception.get() != null) {
|
||||
break;
|
||||
}
|
||||
|
||||
Thread.sleep(50);
|
||||
}
|
||||
|
||||
sh.channel.close().sync();
|
||||
ch.channel.close().sync();
|
||||
sc.close().sync();
|
||||
pc.close().sync();
|
||||
group.shutdownGracefully();
|
||||
|
||||
if (sh.exception.get() != null && !(sh.exception.get() instanceof IOException)) {
|
||||
throw sh.exception.get();
|
||||
}
|
||||
if (ch.exception.get() != null && !(ch.exception.get() instanceof IOException)) {
|
||||
throw ch.exception.get();
|
||||
}
|
||||
if (sh.exception.get() != null) {
|
||||
throw sh.exception.get();
|
||||
}
|
||||
if (ch.exception.get() != null) {
|
||||
throw ch.exception.get();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Timeout(value = 10000, unit = TimeUnit.MILLISECONDS)
|
||||
public void spliceToFile() throws Throwable {
|
||||
EventLoopGroup group = new EpollEventLoopGroup(1);
|
||||
File file = PlatformDependent.createTempFile("netty-splice", null, null);
|
||||
file.deleteOnExit();
|
||||
|
||||
SpliceHandler sh = new SpliceHandler(file);
|
||||
ServerBootstrap bs = new ServerBootstrap();
|
||||
bs.channel(EpollServerSocketChannel.class);
|
||||
bs.group(group).childHandler(sh);
|
||||
bs.childOption(EpollChannelOption.EPOLL_MODE, EpollMode.LEVEL_TRIGGERED);
|
||||
Channel sc = bs.bind(NetUtil.LOCALHOST, 0).syncUninterruptibly().channel();
|
||||
|
||||
Bootstrap cb = new Bootstrap();
|
||||
cb.group(group);
|
||||
cb.channel(EpollSocketChannel.class);
|
||||
cb.handler(new ChannelInboundHandlerAdapter());
|
||||
Channel cc = cb.connect(sc.localAddress()).syncUninterruptibly().channel();
|
||||
|
||||
for (int i = 0; i < data.length;) {
|
||||
int length = Math.min(random.nextInt(1024 * 64), data.length - i);
|
||||
ByteBuf buf = Unpooled.wrappedBuffer(data, i, length);
|
||||
cc.writeAndFlush(buf);
|
||||
i += length;
|
||||
}
|
||||
|
||||
while (sh.future2 == null || !sh.future2.isDone() || !sh.future.isDone()) {
|
||||
if (sh.exception.get() != null) {
|
||||
break;
|
||||
}
|
||||
Thread.sleep(50);
|
||||
}
|
||||
|
||||
sc.close().sync();
|
||||
cc.close().sync();
|
||||
|
||||
if (sh.exception.get() != null && !(sh.exception.get() instanceof IOException)) {
|
||||
throw sh.exception.get();
|
||||
}
|
||||
|
||||
byte[] written = new byte[data.length];
|
||||
FileInputStream in = new FileInputStream(file);
|
||||
|
||||
try {
|
||||
assertEquals(written.length, in.read(written));
|
||||
assertArrayEquals(data, written);
|
||||
} finally {
|
||||
in.close();
|
||||
group.shutdownGracefully();
|
||||
}
|
||||
}
|
||||
|
||||
private static class EchoHandler extends SimpleChannelInboundHandler<ByteBuf> {
|
||||
volatile Channel channel;
|
||||
final AtomicReference<Throwable> exception = new AtomicReference<Throwable>();
|
||||
volatile int counter;
|
||||
|
||||
@Override
|
||||
public void channelActive(ChannelHandlerContext ctx)
|
||||
throws Exception {
|
||||
channel = ctx.channel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelRead0(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
|
||||
byte[] actual = new byte[in.readableBytes()];
|
||||
in.readBytes(actual);
|
||||
|
||||
int lastIdx = counter;
|
||||
for (int i = 0; i < actual.length; i ++) {
|
||||
assertEquals(data[i + lastIdx], actual[i]);
|
||||
}
|
||||
|
||||
if (channel.parent() != null) {
|
||||
channel.write(Unpooled.wrappedBuffer(actual));
|
||||
}
|
||||
|
||||
counter += actual.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
|
||||
ctx.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx,
|
||||
Throwable cause) throws Exception {
|
||||
if (exception.compareAndSet(null, cause)) {
|
||||
cause.printStackTrace();
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class SpliceHandler extends ChannelInboundHandlerAdapter {
|
||||
private final File file;
|
||||
|
||||
volatile ChannelFuture future;
|
||||
volatile ChannelFuture future2;
|
||||
final AtomicReference<Throwable> exception = new AtomicReference<Throwable>();
|
||||
|
||||
SpliceHandler(File file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
||||
final EpollSocketChannel ch = (EpollSocketChannel) ctx.channel();
|
||||
final FileDescriptor fd = FileDescriptor.from(file);
|
||||
|
||||
// splice two halves separately to test starting offset
|
||||
future = ch.spliceTo(fd, 0, data.length / 2);
|
||||
future2 = ch.spliceTo(fd, data.length / 2, data.length / 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx,
|
||||
Throwable cause) throws Exception {
|
||||
if (exception.compareAndSet(null, cause)) {
|
||||
cause.printStackTrace();
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* 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:
|
||||
*
|
||||
* https://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.channel.unix.FileDescriptor;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.Timeout;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class EpollTest {
|
||||
|
||||
@Test
|
||||
public void testIsAvailable() {
|
||||
assertTrue(Epoll.isAvailable());
|
||||
}
|
||||
|
||||
// Testcase for https://github.com/netty/netty/issues/8444
|
||||
@Test
|
||||
@Timeout(value = 5000, unit = TimeUnit.MILLISECONDS)
|
||||
public void testEpollWaitWithTimeOutMinusOne() throws Exception {
|
||||
final EpollEventArray eventArray = new EpollEventArray(8);
|
||||
try {
|
||||
final FileDescriptor epoll = Native.newEpollCreate();
|
||||
final FileDescriptor timerFd = Native.newTimerFd();
|
||||
final FileDescriptor eventfd = Native.newEventFd();
|
||||
Native.epollCtlAdd(epoll.intValue(), timerFd.intValue(), Native.EPOLLIN);
|
||||
Native.epollCtlAdd(epoll.intValue(), eventfd.intValue(), Native.EPOLLIN);
|
||||
|
||||
final AtomicReference<Throwable> ref = new AtomicReference<Throwable>();
|
||||
Thread t = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
assertEquals(1, Native.epollWait(epoll, eventArray, false));
|
||||
// This should have been woken up because of eventfd_write.
|
||||
assertEquals(eventfd.intValue(), eventArray.fd(0));
|
||||
} catch (Throwable cause) {
|
||||
ref.set(cause);
|
||||
}
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
t.join(1000);
|
||||
assertTrue(t.isAlive());
|
||||
Native.eventFdWrite(eventfd.intValue(), 1);
|
||||
|
||||
t.join();
|
||||
assertNull(ref.get());
|
||||
epoll.close();
|
||||
timerFd.close();
|
||||
eventfd.close();
|
||||
} finally {
|
||||
eventArray.free();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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:
|
||||
*
|
||||
* https://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.WriteBeforeRegisteredTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EpollWriteBeforeRegisteredTest extends WriteBeforeRegisteredTest {
|
||||
|
||||
@Override
|
||||
protected List<TestsuitePermutation.BootstrapFactory<Bootstrap>> newFactories() {
|
||||
return EpollSocketTestPermutation.INSTANCE.clientSocketWithFastOpen();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright 2020 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:
|
||||
*
|
||||
* https://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.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.buffer.UnpooledByteBufAllocator;
|
||||
import io.netty.buffer.UnpooledDirectByteBuf;
|
||||
import io.netty.channel.unix.IovArray;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public abstract class IovArrayTest {
|
||||
|
||||
@Test
|
||||
public void testNotFailsWihtoutMemoryAddress() {
|
||||
ByteBuf buffer = new NoMemoryAddressByteBuf(128);
|
||||
IovArray array = new IovArray(buffer);
|
||||
|
||||
ByteBuf buf = Unpooled.directBuffer().writeZero(8);
|
||||
ByteBuf buf2 = new NoMemoryAddressByteBuf(8).writeZero(8);
|
||||
assertTrue(array.add(buf, 0, buf.readableBytes()));
|
||||
assertTrue(array.add(buf, 0, buf2.readableBytes()));
|
||||
assertEquals(2, array.count());
|
||||
assertEquals(16, array.size());
|
||||
assertTrue(buf.release());
|
||||
assertTrue(buf2.release());
|
||||
assertNotEquals(-1, array.memoryAddress(0));
|
||||
array.release();
|
||||
assertEquals(0, buffer.refCnt());
|
||||
}
|
||||
|
||||
private static final class NoMemoryAddressByteBuf extends UnpooledDirectByteBuf {
|
||||
|
||||
NoMemoryAddressByteBuf(int capacity) {
|
||||
super(UnpooledByteBufAllocator.DEFAULT, capacity, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMemoryAddress() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long memoryAddress() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright 2020 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:
|
||||
*
|
||||
* https://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.channel.unix.DomainSocketAddress;
|
||||
import io.netty.channel.unix.Errors.NativeIoException;
|
||||
import io.netty.channel.unix.Socket;
|
||||
import java.util.UUID;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.function.Executable;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
public class LinuxSocketTest {
|
||||
@BeforeAll
|
||||
public static void loadJNI() {
|
||||
Epoll.ensureAvailability();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBindNonIpv6SocketToInet6AddressThrows() throws Exception {
|
||||
final LinuxSocket socket = LinuxSocket.newSocketStream(false);
|
||||
try {
|
||||
assertThrows(IOException.class, new Executable() {
|
||||
@Override
|
||||
public void execute() throws Throwable {
|
||||
socket.bind(new InetSocketAddress(InetAddress.getByAddress(
|
||||
new byte[]{'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1'}),
|
||||
0));
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
socket.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConnectNonIpv6SocketToInet6AddressThrows() throws Exception {
|
||||
final LinuxSocket socket = LinuxSocket.newSocketStream(false);
|
||||
try {
|
||||
assertThrows(IOException.class,
|
||||
new Executable() {
|
||||
@Override
|
||||
public void execute() throws Throwable {
|
||||
socket.connect(new InetSocketAddress(InetAddress.getByAddress(new byte[]{
|
||||
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1'}),
|
||||
1234));
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
socket.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnixDomainSocketTooLongPathFails() throws IOException {
|
||||
// Most systems has a limit for UDS path of 108, 255 is generally too long.
|
||||
StringBuilder socketPath = new StringBuilder("/tmp/");
|
||||
while (socketPath.length() < 255) {
|
||||
socketPath.append(UUID.randomUUID());
|
||||
}
|
||||
|
||||
final DomainSocketAddress domainSocketAddress = new DomainSocketAddress(
|
||||
socketPath.toString());
|
||||
final Socket socket = Socket.newSocketDomain();
|
||||
try {
|
||||
Exception exception = Assertions.assertThrows(NativeIoException.class, new Executable() {
|
||||
@Override
|
||||
public void execute() throws Throwable {
|
||||
socket.bind(domainSocketAddress);
|
||||
}
|
||||
});
|
||||
Assertions.assertTrue(exception.getMessage().contains("too long"));
|
||||
} finally {
|
||||
socket.close();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright 2014 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:
|
||||
*
|
||||
* https://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.util.NetUtil;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import static io.netty.channel.unix.NativeInetAddress.address;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class NativeTest {
|
||||
|
||||
@Test
|
||||
public void testAddressIpv4() throws Exception {
|
||||
InetSocketAddress inetAddress = new InetSocketAddress(NetUtil.LOCALHOST4, 9999);
|
||||
byte[] bytes = new byte[8];
|
||||
ByteBuffer buffer = ByteBuffer.wrap(bytes);
|
||||
buffer.put(inetAddress.getAddress().getAddress());
|
||||
buffer.putInt(inetAddress.getPort());
|
||||
assertEquals(inetAddress, address(buffer.array(), 0, bytes.length));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddressIpv6() throws Exception {
|
||||
Inet6Address address = NetUtil.LOCALHOST6;
|
||||
InetSocketAddress inetAddress = new InetSocketAddress(address, 9999);
|
||||
byte[] bytes = new byte[24];
|
||||
ByteBuffer buffer = ByteBuffer.wrap(bytes);
|
||||
buffer.put(address.getAddress());
|
||||
buffer.putInt(address.getScopeId());
|
||||
buffer.putInt(inetAddress.getPort());
|
||||
assertEquals(inetAddress, address(buffer.array(), 0, bytes.length));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* Copyright 2015 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:
|
||||
*
|
||||
* https://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.channel.unix.Buffer;
|
||||
import io.netty.channel.unix.Socket;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.opentest4j.TestAbortedException;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public abstract class SocketTest<T extends Socket> {
|
||||
protected T socket;
|
||||
|
||||
protected abstract T newSocket();
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
socket = newSocket();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearDown() throws IOException {
|
||||
socket.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeepAlive() throws Exception {
|
||||
assertFalse(socket.isKeepAlive());
|
||||
socket.setKeepAlive(true);
|
||||
assertTrue(socket.isKeepAlive());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTcpNoDelay() throws Exception {
|
||||
assertFalse(socket.isTcpNoDelay());
|
||||
socket.setTcpNoDelay(true);
|
||||
assertTrue(socket.isTcpNoDelay());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReceivedBufferSize() throws Exception {
|
||||
int size = socket.getReceiveBufferSize();
|
||||
int newSize = 65535;
|
||||
assertTrue(size > 0);
|
||||
socket.setReceiveBufferSize(newSize);
|
||||
// Linux usually set it to double what is specified
|
||||
assertTrue(newSize <= socket.getReceiveBufferSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendBufferSize() throws Exception {
|
||||
int size = socket.getSendBufferSize();
|
||||
int newSize = 65535;
|
||||
assertTrue(size > 0);
|
||||
socket.setSendBufferSize(newSize);
|
||||
// Linux usually set it to double what is specified
|
||||
assertTrue(newSize <= socket.getSendBufferSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSoLinger() throws Exception {
|
||||
assertEquals(-1, socket.getSoLinger());
|
||||
socket.setSoLinger(10);
|
||||
assertEquals(10, socket.getSoLinger());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoubleCloseDoesNotThrow() throws IOException {
|
||||
Socket socket = Socket.newSocketStream();
|
||||
socket.close();
|
||||
socket.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTrafficClass() throws IOException {
|
||||
// IPTOS_THROUGHPUT
|
||||
final int value = 0x08;
|
||||
socket.setTrafficClass(value);
|
||||
assertEquals(value, socket.getTrafficClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntOpt() throws IOException {
|
||||
socket.setReuseAddress(false);
|
||||
socket.setIntOpt(level(), optname(), 1);
|
||||
// Anything which is != 0 is considered enabled
|
||||
assertNotEquals(0, socket.getIntOpt(level(), optname()));
|
||||
socket.setIntOpt(level(), optname(), 0);
|
||||
// This should be disabled again
|
||||
assertEquals(0, socket.getIntOpt(level(), optname()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRawOpt() throws IOException {
|
||||
ByteBuffer buffer = Buffer.allocateDirectWithNativeOrder(4);
|
||||
buffer.putInt(1).flip();
|
||||
socket.setRawOpt(level(), optname(), buffer);
|
||||
|
||||
ByteBuffer out = ByteBuffer.allocate(4);
|
||||
socket.getRawOpt(level(), optname(), out);
|
||||
assertFalse(out.hasRemaining());
|
||||
|
||||
out.flip();
|
||||
assertNotEquals(ByteBuffer.allocate(0), out);
|
||||
}
|
||||
|
||||
protected int level() {
|
||||
throw new TestAbortedException("Not supported");
|
||||
}
|
||||
|
||||
protected int optname() {
|
||||
throw new TestAbortedException("Not supported");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright 2016 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:
|
||||
*
|
||||
* https://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.channel.unix.DomainSocketAddress;
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
||||
|
||||
public final class UnixTestUtils {
|
||||
private static final Object INET_LOOPBACK_UNAVAILABLE = new Object();
|
||||
private static volatile Object inetLoopbackCache;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #newDomainSocketAddress()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static DomainSocketAddress newSocketAddress() {
|
||||
return newDomainSocketAddress();
|
||||
}
|
||||
|
||||
public static DomainSocketAddress newDomainSocketAddress() {
|
||||
try {
|
||||
File file;
|
||||
do {
|
||||
file = PlatformDependent.createTempFile("NETTY", "UDS", null);
|
||||
if (!file.delete()) {
|
||||
throw new IOException("failed to delete: " + file);
|
||||
}
|
||||
} while (file.getAbsolutePath().length() > 128);
|
||||
return new DomainSocketAddress(file);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The JDK method may produce IPv4 loopback addresses where {@link io.netty.util.NetUtil#LOCALHOST} might be an
|
||||
* IPv6 addresses.
|
||||
* This difference can stress the system in different ways that are important to test.
|
||||
*/
|
||||
public static SocketAddress newInetLoopbackSocketAddress() {
|
||||
Object loopback = inetLoopbackCache;
|
||||
|
||||
if (loopback == null) {
|
||||
inetLoopbackCache = loopback = getLoopbackAddress();
|
||||
}
|
||||
|
||||
assumeTrue(loopback != INET_LOOPBACK_UNAVAILABLE, "InetAddress.getLoopbackAddress() is not available");
|
||||
return new InetSocketAddress((InetAddress) loopback, 0);
|
||||
}
|
||||
|
||||
private static Object getLoopbackAddress() {
|
||||
try {
|
||||
Method method = InetAddress.class.getMethod("getLoopbackAddress");
|
||||
return method.invoke(null);
|
||||
} catch (Exception ignore) {
|
||||
return INET_LOOPBACK_UNAVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
private UnixTestUtils() { }
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
handlers=java.util.logging.ConsoleHandler
|
||||
.level=ALL
|
||||
java.util.logging.SimpleFormatter.format=%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%1$tL %4$-7s [%3$s] %5$s %6$s%n
|
||||
java.util.logging.ConsoleHandler.level=ALL
|
||||
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
|
||||
jdk.event.security.level=INFO
|
||||
org.junit.jupiter.engine.execution.ConditionEvaluator.level=OFF
|
3
netty-channel-sctp/build.gradle
Normal file
3
netty-channel-sctp/build.gradle
Normal file
|
@ -0,0 +1,3 @@
|
|||
dependencies {
|
||||
api project(':netty-channel')
|
||||
}
|
|
@ -0,0 +1,245 @@
|
|||
/*
|
||||
* Copyright 2011 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:
|
||||
*
|
||||
* https://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.sctp;
|
||||
|
||||
import com.sun.nio.sctp.SctpChannel;
|
||||
import com.sun.nio.sctp.SctpStandardSocketOptions;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import io.netty.channel.ChannelException;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.DefaultChannelConfig;
|
||||
import io.netty.channel.MessageSizeEstimator;
|
||||
import io.netty.channel.RecvByteBufAllocator;
|
||||
import io.netty.channel.WriteBufferWaterMark;
|
||||
import io.netty.util.internal.ObjectUtil;
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import static io.netty.channel.ChannelOption.SO_RCVBUF;
|
||||
import static io.netty.channel.ChannelOption.SO_SNDBUF;
|
||||
import static io.netty.channel.sctp.SctpChannelOption.SCTP_INIT_MAXSTREAMS;
|
||||
import static io.netty.channel.sctp.SctpChannelOption.SCTP_NODELAY;
|
||||
|
||||
/**
|
||||
* The default {@link SctpChannelConfig} implementation for SCTP.
|
||||
*/
|
||||
public class DefaultSctpChannelConfig extends DefaultChannelConfig implements SctpChannelConfig {
|
||||
|
||||
private final SctpChannel javaChannel;
|
||||
|
||||
public DefaultSctpChannelConfig(io.netty.channel.sctp.SctpChannel channel, SctpChannel javaChannel) {
|
||||
super(channel);
|
||||
this.javaChannel = ObjectUtil.checkNotNull(javaChannel, "javaChannel");
|
||||
|
||||
// Enable TCP_NODELAY by default if possible.
|
||||
if (PlatformDependent.canEnableTcpNoDelayByDefault()) {
|
||||
try {
|
||||
setSctpNoDelay(true);
|
||||
} catch (Exception e) {
|
||||
// Ignore.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ChannelOption<?>, Object> getOptions() {
|
||||
return getOptions(
|
||||
super.getOptions(),
|
||||
SO_RCVBUF, SO_SNDBUF, SCTP_NODELAY, SCTP_INIT_MAXSTREAMS);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> T getOption(ChannelOption<T> option) {
|
||||
if (option == SO_RCVBUF) {
|
||||
return (T) Integer.valueOf(getReceiveBufferSize());
|
||||
}
|
||||
if (option == SO_SNDBUF) {
|
||||
return (T) Integer.valueOf(getSendBufferSize());
|
||||
}
|
||||
if (option == SCTP_NODELAY) {
|
||||
return (T) Boolean.valueOf(isSctpNoDelay());
|
||||
}
|
||||
if (option == SCTP_INIT_MAXSTREAMS) {
|
||||
return (T) getInitMaxStreams();
|
||||
}
|
||||
return super.getOption(option);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> boolean setOption(ChannelOption<T> option, T value) {
|
||||
validate(option, value);
|
||||
|
||||
if (option == SO_RCVBUF) {
|
||||
setReceiveBufferSize((Integer) value);
|
||||
} else if (option == SO_SNDBUF) {
|
||||
setSendBufferSize((Integer) value);
|
||||
} else if (option == SCTP_NODELAY) {
|
||||
setSctpNoDelay((Boolean) value);
|
||||
} else if (option == SCTP_INIT_MAXSTREAMS) {
|
||||
setInitMaxStreams((SctpStandardSocketOptions.InitMaxStreams) value);
|
||||
} else {
|
||||
return super.setOption(option, value);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSctpNoDelay() {
|
||||
try {
|
||||
return javaChannel.getOption(SctpStandardSocketOptions.SCTP_NODELAY);
|
||||
} catch (IOException e) {
|
||||
throw new ChannelException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpChannelConfig setSctpNoDelay(boolean sctpNoDelay) {
|
||||
try {
|
||||
javaChannel.setOption(SctpStandardSocketOptions.SCTP_NODELAY, sctpNoDelay);
|
||||
} catch (IOException e) {
|
||||
throw new ChannelException(e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSendBufferSize() {
|
||||
try {
|
||||
return javaChannel.getOption(SctpStandardSocketOptions.SO_SNDBUF);
|
||||
} catch (IOException e) {
|
||||
throw new ChannelException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpChannelConfig setSendBufferSize(int sendBufferSize) {
|
||||
try {
|
||||
javaChannel.setOption(SctpStandardSocketOptions.SO_SNDBUF, sendBufferSize);
|
||||
} catch (IOException e) {
|
||||
throw new ChannelException(e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getReceiveBufferSize() {
|
||||
try {
|
||||
return javaChannel.getOption(SctpStandardSocketOptions.SO_RCVBUF);
|
||||
} catch (IOException e) {
|
||||
throw new ChannelException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpChannelConfig setReceiveBufferSize(int receiveBufferSize) {
|
||||
try {
|
||||
javaChannel.setOption(SctpStandardSocketOptions.SO_RCVBUF, receiveBufferSize);
|
||||
} catch (IOException e) {
|
||||
throw new ChannelException(e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpStandardSocketOptions.InitMaxStreams getInitMaxStreams() {
|
||||
try {
|
||||
return javaChannel.getOption(SctpStandardSocketOptions.SCTP_INIT_MAXSTREAMS);
|
||||
} catch (IOException e) {
|
||||
throw new ChannelException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpChannelConfig setInitMaxStreams(SctpStandardSocketOptions.InitMaxStreams initMaxStreams) {
|
||||
try {
|
||||
javaChannel.setOption(SctpStandardSocketOptions.SCTP_INIT_MAXSTREAMS, initMaxStreams);
|
||||
} catch (IOException e) {
|
||||
throw new ChannelException(e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpChannelConfig setConnectTimeoutMillis(int connectTimeoutMillis) {
|
||||
super.setConnectTimeoutMillis(connectTimeoutMillis);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public SctpChannelConfig setMaxMessagesPerRead(int maxMessagesPerRead) {
|
||||
super.setMaxMessagesPerRead(maxMessagesPerRead);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpChannelConfig setWriteSpinCount(int writeSpinCount) {
|
||||
super.setWriteSpinCount(writeSpinCount);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpChannelConfig setAllocator(ByteBufAllocator allocator) {
|
||||
super.setAllocator(allocator);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpChannelConfig setRecvByteBufAllocator(RecvByteBufAllocator allocator) {
|
||||
super.setRecvByteBufAllocator(allocator);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpChannelConfig setAutoRead(boolean autoRead) {
|
||||
super.setAutoRead(autoRead);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpChannelConfig setAutoClose(boolean autoClose) {
|
||||
super.setAutoClose(autoClose);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpChannelConfig setWriteBufferHighWaterMark(int writeBufferHighWaterMark) {
|
||||
super.setWriteBufferHighWaterMark(writeBufferHighWaterMark);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpChannelConfig setWriteBufferLowWaterMark(int writeBufferLowWaterMark) {
|
||||
super.setWriteBufferLowWaterMark(writeBufferLowWaterMark);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpChannelConfig setWriteBufferWaterMark(WriteBufferWaterMark writeBufferWaterMark) {
|
||||
super.setWriteBufferWaterMark(writeBufferWaterMark);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpChannelConfig setMessageSizeEstimator(MessageSizeEstimator estimator) {
|
||||
super.setMessageSizeEstimator(estimator);
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,227 @@
|
|||
/*
|
||||
* Copyright 2011 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:
|
||||
*
|
||||
* https://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.sctp;
|
||||
|
||||
import static io.netty.util.internal.ObjectUtil.checkPositiveOrZero;
|
||||
|
||||
import com.sun.nio.sctp.SctpServerChannel;
|
||||
import com.sun.nio.sctp.SctpStandardSocketOptions;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import io.netty.channel.ChannelException;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.DefaultChannelConfig;
|
||||
import io.netty.channel.MessageSizeEstimator;
|
||||
import io.netty.channel.RecvByteBufAllocator;
|
||||
import io.netty.channel.ServerChannelRecvByteBufAllocator;
|
||||
import io.netty.channel.WriteBufferWaterMark;
|
||||
import io.netty.util.NetUtil;
|
||||
import io.netty.util.internal.ObjectUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The default {@link SctpServerChannelConfig} implementation for SCTP.
|
||||
*/
|
||||
public class DefaultSctpServerChannelConfig extends DefaultChannelConfig implements SctpServerChannelConfig {
|
||||
|
||||
private final SctpServerChannel javaChannel;
|
||||
private volatile int backlog = NetUtil.SOMAXCONN;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*/
|
||||
public DefaultSctpServerChannelConfig(
|
||||
io.netty.channel.sctp.SctpServerChannel channel, SctpServerChannel javaChannel) {
|
||||
super(channel, new ServerChannelRecvByteBufAllocator());
|
||||
this.javaChannel = ObjectUtil.checkNotNull(javaChannel, "javaChannel");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ChannelOption<?>, Object> getOptions() {
|
||||
return getOptions(
|
||||
super.getOptions(),
|
||||
ChannelOption.SO_RCVBUF, ChannelOption.SO_SNDBUF, SctpChannelOption.SCTP_INIT_MAXSTREAMS);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> T getOption(ChannelOption<T> option) {
|
||||
if (option == ChannelOption.SO_RCVBUF) {
|
||||
return (T) Integer.valueOf(getReceiveBufferSize());
|
||||
}
|
||||
if (option == ChannelOption.SO_SNDBUF) {
|
||||
return (T) Integer.valueOf(getSendBufferSize());
|
||||
}
|
||||
if (option == SctpChannelOption.SCTP_INIT_MAXSTREAMS) {
|
||||
return (T) getInitMaxStreams();
|
||||
}
|
||||
return super.getOption(option);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> boolean setOption(ChannelOption<T> option, T value) {
|
||||
validate(option, value);
|
||||
|
||||
if (option == ChannelOption.SO_RCVBUF) {
|
||||
setReceiveBufferSize((Integer) value);
|
||||
} else if (option == ChannelOption.SO_SNDBUF) {
|
||||
setSendBufferSize((Integer) value);
|
||||
} else if (option == SctpChannelOption.SCTP_INIT_MAXSTREAMS) {
|
||||
setInitMaxStreams((SctpStandardSocketOptions.InitMaxStreams) value);
|
||||
} else {
|
||||
return super.setOption(option, value);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSendBufferSize() {
|
||||
try {
|
||||
return javaChannel.getOption(SctpStandardSocketOptions.SO_SNDBUF);
|
||||
} catch (IOException e) {
|
||||
throw new ChannelException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpServerChannelConfig setSendBufferSize(int sendBufferSize) {
|
||||
try {
|
||||
javaChannel.setOption(SctpStandardSocketOptions.SO_SNDBUF, sendBufferSize);
|
||||
} catch (IOException e) {
|
||||
throw new ChannelException(e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getReceiveBufferSize() {
|
||||
try {
|
||||
return javaChannel.getOption(SctpStandardSocketOptions.SO_RCVBUF);
|
||||
} catch (IOException e) {
|
||||
throw new ChannelException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpServerChannelConfig setReceiveBufferSize(int receiveBufferSize) {
|
||||
try {
|
||||
javaChannel.setOption(SctpStandardSocketOptions.SO_RCVBUF, receiveBufferSize);
|
||||
} catch (IOException e) {
|
||||
throw new ChannelException(e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpStandardSocketOptions.InitMaxStreams getInitMaxStreams() {
|
||||
try {
|
||||
return javaChannel.getOption(SctpStandardSocketOptions.SCTP_INIT_MAXSTREAMS);
|
||||
} catch (IOException e) {
|
||||
throw new ChannelException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpServerChannelConfig setInitMaxStreams(SctpStandardSocketOptions.InitMaxStreams initMaxStreams) {
|
||||
try {
|
||||
javaChannel.setOption(SctpStandardSocketOptions.SCTP_INIT_MAXSTREAMS, initMaxStreams);
|
||||
} catch (IOException e) {
|
||||
throw new ChannelException(e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBacklog() {
|
||||
return backlog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpServerChannelConfig setBacklog(int backlog) {
|
||||
checkPositiveOrZero(backlog, "backlog");
|
||||
this.backlog = backlog;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public SctpServerChannelConfig setMaxMessagesPerRead(int maxMessagesPerRead) {
|
||||
super.setMaxMessagesPerRead(maxMessagesPerRead);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpServerChannelConfig setWriteSpinCount(int writeSpinCount) {
|
||||
super.setWriteSpinCount(writeSpinCount);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpServerChannelConfig setConnectTimeoutMillis(int connectTimeoutMillis) {
|
||||
super.setConnectTimeoutMillis(connectTimeoutMillis);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpServerChannelConfig setAllocator(ByteBufAllocator allocator) {
|
||||
super.setAllocator(allocator);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpServerChannelConfig setRecvByteBufAllocator(RecvByteBufAllocator allocator) {
|
||||
super.setRecvByteBufAllocator(allocator);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpServerChannelConfig setAutoRead(boolean autoRead) {
|
||||
super.setAutoRead(autoRead);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpServerChannelConfig setAutoClose(boolean autoClose) {
|
||||
super.setAutoClose(autoClose);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpServerChannelConfig setWriteBufferLowWaterMark(int writeBufferLowWaterMark) {
|
||||
super.setWriteBufferLowWaterMark(writeBufferLowWaterMark);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpServerChannelConfig setWriteBufferHighWaterMark(int writeBufferHighWaterMark) {
|
||||
super.setWriteBufferHighWaterMark(writeBufferHighWaterMark);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpServerChannelConfig setWriteBufferWaterMark(WriteBufferWaterMark writeBufferWaterMark) {
|
||||
super.setWriteBufferWaterMark(writeBufferWaterMark);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpServerChannelConfig setMessageSizeEstimator(MessageSizeEstimator estimator) {
|
||||
super.setMessageSizeEstimator(estimator);
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Copyright 2011 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:
|
||||
*
|
||||
* https://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.sctp;
|
||||
|
||||
import com.sun.nio.sctp.Association;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A SCTP/IP {@link Channel} interface for single SCTP association.
|
||||
*
|
||||
* <p>
|
||||
* The SctpChannel is a message-oriented, connected transport which supports multi-streaming and multi-homing.
|
||||
* </p>
|
||||
*/
|
||||
public interface SctpChannel extends Channel {
|
||||
@Override
|
||||
SctpServerChannel parent();
|
||||
|
||||
/**
|
||||
* Returns the underlying SCTP association.
|
||||
*/
|
||||
Association association();
|
||||
|
||||
/**
|
||||
* Return the (primary) local address of the SCTP channel.
|
||||
*
|
||||
* Please note that, this return the first local address in the underlying SCTP Channel's
|
||||
* local address iterator to support Netty Channel API. In other words, its the application's
|
||||
* responsibility to keep track of it's local primary address.
|
||||
*
|
||||
* (To set a local address as primary, the application can request by calling local SCTP stack,
|
||||
* with SctpStandardSocketOption.SCTP_PRIMARY_ADDR option).
|
||||
*/
|
||||
@Override
|
||||
InetSocketAddress localAddress();
|
||||
|
||||
/**
|
||||
* Return all local addresses of the SCTP channel.
|
||||
* Please note that, it will return more than one address if this channel is using multi-homing
|
||||
*/
|
||||
Set<InetSocketAddress> allLocalAddresses();
|
||||
|
||||
/**
|
||||
* Returns the {@link SctpChannelConfig} configuration of the channel.
|
||||
*/
|
||||
@Override
|
||||
SctpChannelConfig config();
|
||||
|
||||
/**
|
||||
* Return the (primary) remote address of the SCTP channel.
|
||||
*
|
||||
* Please note that, this return the first remote address in the underlying SCTP Channel's
|
||||
* remote address iterator to support Netty Channel API. In other words, its the application's
|
||||
* responsibility to keep track of it's peer's primary address.
|
||||
*
|
||||
* (The application can request it's remote peer to set a specific address as primary by
|
||||
* calling the local SCTP stack with SctpStandardSocketOption.SCTP_SET_PEER_PRIMARY_ADDR option)
|
||||
*/
|
||||
@Override
|
||||
InetSocketAddress remoteAddress();
|
||||
|
||||
/**
|
||||
* Return all remote addresses of the SCTP server channel.
|
||||
* Please note that, it will return more than one address if the remote is using multi-homing.
|
||||
*/
|
||||
Set<InetSocketAddress> allRemoteAddresses();
|
||||
|
||||
/**
|
||||
* Bind a address to the already bound channel to enable multi-homing.
|
||||
* The Channel bust be bound and yet to be connected.
|
||||
*/
|
||||
ChannelFuture bindAddress(InetAddress localAddress);
|
||||
|
||||
/**
|
||||
* Bind a address to the already bound channel to enable multi-homing.
|
||||
* The Channel bust be bound and yet to be connected.
|
||||
*
|
||||
* Will notify the given {@link ChannelPromise} and return a {@link ChannelFuture}
|
||||
*/
|
||||
ChannelFuture bindAddress(InetAddress localAddress, ChannelPromise promise);
|
||||
|
||||
/**
|
||||
* Unbind the address from channel's multi-homing address list.
|
||||
* The address should be added already in multi-homing address list.
|
||||
*/
|
||||
ChannelFuture unbindAddress(InetAddress localAddress);
|
||||
|
||||
/**
|
||||
* Unbind the address from channel's multi-homing address list.
|
||||
* The address should be added already in multi-homing address list.
|
||||
*
|
||||
* Will notify the given {@link ChannelPromise} and return a {@link ChannelFuture}
|
||||
*/
|
||||
ChannelFuture unbindAddress(InetAddress localAddress, ChannelPromise promise);
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright 2011 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:
|
||||
*
|
||||
* https://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.sctp;
|
||||
|
||||
import com.sun.nio.sctp.SctpStandardSocketOptions.InitMaxStreams;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import io.netty.channel.ChannelConfig;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.MessageSizeEstimator;
|
||||
import io.netty.channel.RecvByteBufAllocator;
|
||||
import io.netty.channel.WriteBufferWaterMark;
|
||||
|
||||
/**
|
||||
* A {@link ChannelConfig} for a {@link SctpChannel}.
|
||||
* <p/>
|
||||
* <h3>Available options</h3>
|
||||
* <p/>
|
||||
* In addition to the options provided by {@link ChannelConfig},
|
||||
* {@link SctpChannelConfig} allows the following options in the option map:
|
||||
* <p/>
|
||||
* <table border="1" cellspacing="0" cellpadding="6">
|
||||
* <tr>
|
||||
* <th>Name</th><th>Associated setter method</th>
|
||||
* </tr><tr>
|
||||
* <td>{@link ChannelOption#SO_RCVBUF}</td><td>{@link #setReceiveBufferSize(int)}</td>
|
||||
* </tr><tr>
|
||||
* <td>{@link ChannelOption#SO_SNDBUF}</td><td>{@link #setSendBufferSize(int)}</td>
|
||||
* </tr><tr>
|
||||
* <td>{@link SctpChannelOption#SCTP_NODELAY}</td><td>{@link #setSctpNoDelay(boolean)}}</td>
|
||||
* </tr><tr>
|
||||
* <td>{@link SctpChannelOption#SCTP_INIT_MAXSTREAMS}</td><td>{@link #setInitMaxStreams(InitMaxStreams)}</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
public interface SctpChannelConfig extends ChannelConfig {
|
||||
|
||||
/**
|
||||
* Gets the <a href="https://openjdk.java.net/projects/sctp/javadoc/com/sun/nio/sctp/SctpStandardSocketOption.html">
|
||||
* {@code SCTP_NODELAY}</a> option. Please note that the default value of this option is {@code true} unlike the
|
||||
* operating system default ({@code false}). However, for some buggy platforms, such as Android, that shows erratic
|
||||
* behavior with Nagle's algorithm disabled, the default value remains to be {@code false}.
|
||||
*/
|
||||
boolean isSctpNoDelay();
|
||||
|
||||
/**
|
||||
* Sets the <a href="https://openjdk.java.net/projects/sctp/javadoc/com/sun/nio/sctp/SctpStandardSocketOption.html">
|
||||
* {@code SCTP_NODELAY}</a> option. Please note that the default value of this option is {@code true} unlike the
|
||||
* operating system default ({@code false}). However, for some buggy platforms, such as Android, that shows erratic
|
||||
* behavior with Nagle's algorithm disabled, the default value remains to be {@code false}.
|
||||
*/
|
||||
SctpChannelConfig setSctpNoDelay(boolean sctpNoDelay);
|
||||
|
||||
/**
|
||||
* Gets the <a href="https://openjdk.java.net/projects/sctp/javadoc/com/sun/nio/sctp/SctpStandardSocketOption.html">
|
||||
* {@code SO_SNDBUF}</a> option.
|
||||
*/
|
||||
int getSendBufferSize();
|
||||
|
||||
/**
|
||||
* Sets the <a href="https://openjdk.java.net/projects/sctp/javadoc/com/sun/nio/sctp/SctpStandardSocketOption.html">
|
||||
* {@code SO_SNDBUF}</a> option.
|
||||
*/
|
||||
SctpChannelConfig setSendBufferSize(int sendBufferSize);
|
||||
|
||||
/**
|
||||
* Gets the <a href="https://openjdk.java.net/projects/sctp/javadoc/com/sun/nio/sctp/SctpStandardSocketOption.html">
|
||||
* {@code SO_RCVBUF}</a> option.
|
||||
*/
|
||||
int getReceiveBufferSize();
|
||||
|
||||
/**
|
||||
* Gets the <a href="https://openjdk.java.net/projects/sctp/javadoc/com/sun/nio/sctp/SctpStandardSocketOption.html">
|
||||
* {@code SO_RCVBUF}</a> option.
|
||||
*/
|
||||
SctpChannelConfig setReceiveBufferSize(int receiveBufferSize);
|
||||
|
||||
/**
|
||||
* Gets the <a href="https://openjdk.java.net/projects/sctp/javadoc/com/sun/nio/sctp/SctpStandardSocketOption.html">
|
||||
* {@code SCTP_INIT_MAXSTREAMS}</a> option.
|
||||
*/
|
||||
InitMaxStreams getInitMaxStreams();
|
||||
|
||||
/**
|
||||
* Gets the <a href="https://openjdk.java.net/projects/sctp/javadoc/com/sun/nio/sctp/SctpStandardSocketOption.html">
|
||||
* {@code SCTP_INIT_MAXSTREAMS}</a> option.
|
||||
*/
|
||||
SctpChannelConfig setInitMaxStreams(InitMaxStreams initMaxStreams);
|
||||
|
||||
@Override
|
||||
SctpChannelConfig setConnectTimeoutMillis(int connectTimeoutMillis);
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
SctpChannelConfig setMaxMessagesPerRead(int maxMessagesPerRead);
|
||||
|
||||
@Override
|
||||
SctpChannelConfig setWriteSpinCount(int writeSpinCount);
|
||||
|
||||
@Override
|
||||
SctpChannelConfig setAllocator(ByteBufAllocator allocator);
|
||||
|
||||
@Override
|
||||
SctpChannelConfig setRecvByteBufAllocator(RecvByteBufAllocator allocator);
|
||||
|
||||
@Override
|
||||
SctpChannelConfig setAutoRead(boolean autoRead);
|
||||
|
||||
@Override
|
||||
SctpChannelConfig setAutoClose(boolean autoClose);
|
||||
|
||||
@Override
|
||||
SctpChannelConfig setWriteBufferHighWaterMark(int writeBufferHighWaterMark);
|
||||
|
||||
@Override
|
||||
SctpChannelConfig setWriteBufferLowWaterMark(int writeBufferLowWaterMark);
|
||||
|
||||
@Override
|
||||
SctpChannelConfig setWriteBufferWaterMark(WriteBufferWaterMark writeBufferWaterMark);
|
||||
|
||||
@Override
|
||||
SctpChannelConfig setMessageSizeEstimator(MessageSizeEstimator estimator);
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright 2013 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:
|
||||
*
|
||||
* https://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.sctp;
|
||||
|
||||
import com.sun.nio.sctp.SctpStandardSocketOptions.InitMaxStreams;
|
||||
import io.netty.channel.ChannelOption;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
|
||||
/**
|
||||
* Option for configuring the SCTP transport
|
||||
*/
|
||||
public final class SctpChannelOption<T> extends ChannelOption<T> {
|
||||
|
||||
public static final ChannelOption<Boolean> SCTP_DISABLE_FRAGMENTS =
|
||||
valueOf(SctpChannelOption.class, "SCTP_DISABLE_FRAGMENTS");
|
||||
public static final ChannelOption<Boolean> SCTP_EXPLICIT_COMPLETE =
|
||||
valueOf(SctpChannelOption.class, "SCTP_EXPLICIT_COMPLETE");
|
||||
public static final ChannelOption<Integer> SCTP_FRAGMENT_INTERLEAVE =
|
||||
valueOf(SctpChannelOption.class, "SCTP_FRAGMENT_INTERLEAVE");
|
||||
public static final ChannelOption<InitMaxStreams> SCTP_INIT_MAXSTREAMS =
|
||||
valueOf(SctpChannelOption.class, "SCTP_INIT_MAXSTREAMS");
|
||||
|
||||
public static final ChannelOption<Boolean> SCTP_NODELAY =
|
||||
valueOf(SctpChannelOption.class, "SCTP_NODELAY");
|
||||
public static final ChannelOption<SocketAddress> SCTP_PRIMARY_ADDR =
|
||||
valueOf(SctpChannelOption.class, "SCTP_PRIMARY_ADDR");
|
||||
public static final ChannelOption<SocketAddress> SCTP_SET_PEER_PRIMARY_ADDR =
|
||||
valueOf(SctpChannelOption.class, "SCTP_SET_PEER_PRIMARY_ADDR");
|
||||
|
||||
@SuppressWarnings({ "unused", "deprecation" })
|
||||
private SctpChannelOption() {
|
||||
super(null);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
* Copyright 2011 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:
|
||||
*
|
||||
* https://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.sctp;
|
||||
|
||||
import com.sun.nio.sctp.MessageInfo;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.DefaultByteBufHolder;
|
||||
import io.netty.util.internal.ObjectUtil;
|
||||
|
||||
/**
|
||||
* Representation of SCTP Data Chunk
|
||||
*/
|
||||
public final class SctpMessage extends DefaultByteBufHolder {
|
||||
private final int streamIdentifier;
|
||||
private final int protocolIdentifier;
|
||||
private final boolean unordered;
|
||||
|
||||
private final MessageInfo msgInfo;
|
||||
|
||||
/**
|
||||
* Essential data that is being carried within SCTP Data Chunk
|
||||
* @param protocolIdentifier of payload
|
||||
* @param streamIdentifier that you want to send the payload
|
||||
* @param payloadBuffer channel buffer
|
||||
*/
|
||||
public SctpMessage(int protocolIdentifier, int streamIdentifier, ByteBuf payloadBuffer) {
|
||||
this(protocolIdentifier, streamIdentifier, false, payloadBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Essential data that is being carried within SCTP Data Chunk
|
||||
* @param protocolIdentifier of payload
|
||||
* @param streamIdentifier that you want to send the payload
|
||||
* @param unordered if {@literal true}, the SCTP Data Chunk will be sent with the U (unordered) flag set.
|
||||
* @param payloadBuffer channel buffer
|
||||
*/
|
||||
public SctpMessage(int protocolIdentifier, int streamIdentifier, boolean unordered, ByteBuf payloadBuffer) {
|
||||
super(payloadBuffer);
|
||||
this.protocolIdentifier = protocolIdentifier;
|
||||
this.streamIdentifier = streamIdentifier;
|
||||
this.unordered = unordered;
|
||||
msgInfo = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Essential data that is being carried within SCTP Data Chunk
|
||||
* @param msgInfo the {@link MessageInfo}
|
||||
* @param payloadBuffer channel buffer
|
||||
*/
|
||||
public SctpMessage(MessageInfo msgInfo, ByteBuf payloadBuffer) {
|
||||
super(payloadBuffer);
|
||||
this.msgInfo = ObjectUtil.checkNotNull(msgInfo, "msgInfo");
|
||||
this.streamIdentifier = msgInfo.streamNumber();
|
||||
this.protocolIdentifier = msgInfo.payloadProtocolID();
|
||||
this.unordered = msgInfo.isUnordered();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the stream-identifier
|
||||
*/
|
||||
public int streamIdentifier() {
|
||||
return streamIdentifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the protocol-identifier
|
||||
*/
|
||||
public int protocolIdentifier() {
|
||||
return protocolIdentifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the unordered flag
|
||||
*/
|
||||
public boolean isUnordered() {
|
||||
return unordered;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link MessageInfo} for inbound messages or {@code null} for
|
||||
* outbound messages.
|
||||
*/
|
||||
public MessageInfo messageInfo() {
|
||||
return msgInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if this message is complete.
|
||||
*/
|
||||
public boolean isComplete() {
|
||||
if (msgInfo != null) {
|
||||
return msgInfo.isComplete();
|
||||
} else {
|
||||
//all outbound sctp messages are complete
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SctpMessage sctpFrame = (SctpMessage) o;
|
||||
|
||||
if (protocolIdentifier != sctpFrame.protocolIdentifier) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (streamIdentifier != sctpFrame.streamIdentifier) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (unordered != sctpFrame.unordered) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return content().equals(sctpFrame.content());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = streamIdentifier;
|
||||
result = 31 * result + protocolIdentifier;
|
||||
// values 1231 and 1237 are referenced in the javadocs of Boolean#hashCode()
|
||||
result = 31 * result + (unordered ? 1231 : 1237);
|
||||
result = 31 * result + content().hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpMessage copy() {
|
||||
return (SctpMessage) super.copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpMessage duplicate() {
|
||||
return (SctpMessage) super.duplicate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpMessage retainedDuplicate() {
|
||||
return (SctpMessage) super.retainedDuplicate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpMessage replace(ByteBuf content) {
|
||||
if (msgInfo == null) {
|
||||
return new SctpMessage(protocolIdentifier, streamIdentifier, unordered, content);
|
||||
} else {
|
||||
return new SctpMessage(msgInfo, content);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpMessage retain() {
|
||||
super.retain();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpMessage retain(int increment) {
|
||||
super.retain(increment);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpMessage touch() {
|
||||
super.touch();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpMessage touch(Object hint) {
|
||||
super.touch(hint);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SctpFrame{" +
|
||||
"streamIdentifier=" + streamIdentifier + ", protocolIdentifier=" + protocolIdentifier +
|
||||
", unordered=" + unordered +
|
||||
", data=" + contentToString() + '}';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright 2011 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:
|
||||
*
|
||||
* https://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.sctp;
|
||||
|
||||
import com.sun.nio.sctp.AbstractNotificationHandler;
|
||||
import com.sun.nio.sctp.AssociationChangeNotification;
|
||||
import com.sun.nio.sctp.HandlerResult;
|
||||
import com.sun.nio.sctp.Notification;
|
||||
import com.sun.nio.sctp.PeerAddressChangeNotification;
|
||||
import com.sun.nio.sctp.SendFailedNotification;
|
||||
import com.sun.nio.sctp.ShutdownNotification;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.util.internal.ObjectUtil;
|
||||
|
||||
|
||||
/**
|
||||
* {@link AbstractNotificationHandler} implementation which will handle all {@link Notification}s by trigger a
|
||||
* {@link Notification} user event in the {@link ChannelPipeline} of a {@link SctpChannel}.
|
||||
*/
|
||||
public final class SctpNotificationHandler extends AbstractNotificationHandler<Object> {
|
||||
|
||||
private final SctpChannel sctpChannel;
|
||||
|
||||
public SctpNotificationHandler(SctpChannel sctpChannel) {
|
||||
this.sctpChannel = ObjectUtil.checkNotNull(sctpChannel, "sctpChannel");
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerResult handleNotification(AssociationChangeNotification notification, Object o) {
|
||||
fireEvent(notification);
|
||||
return HandlerResult.CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerResult handleNotification(PeerAddressChangeNotification notification, Object o) {
|
||||
fireEvent(notification);
|
||||
return HandlerResult.CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerResult handleNotification(SendFailedNotification notification, Object o) {
|
||||
fireEvent(notification);
|
||||
return HandlerResult.CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerResult handleNotification(ShutdownNotification notification, Object o) {
|
||||
fireEvent(notification);
|
||||
sctpChannel.close();
|
||||
return HandlerResult.RETURN;
|
||||
}
|
||||
|
||||
private void fireEvent(Notification notification) {
|
||||
sctpChannel.pipeline().fireUserEventTriggered(notification);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright 2011 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:
|
||||
*
|
||||
* https://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.sctp;
|
||||
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import io.netty.channel.ServerChannel;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.InetAddress;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A SCTP/IP {@link ServerChannel} which accepts incoming SCTP/IP associations.
|
||||
*
|
||||
* <p>
|
||||
* Multi-homing address binding/unbinding can done through bindAddress/unbindAddress methods.
|
||||
* </p>
|
||||
*/
|
||||
public interface SctpServerChannel extends ServerChannel {
|
||||
|
||||
/**
|
||||
* Returns the {@link SctpServerChannelConfig} configuration of the channel.
|
||||
*/
|
||||
@Override
|
||||
SctpServerChannelConfig config();
|
||||
|
||||
/**
|
||||
* Return the (primary) local address of the SCTP server channel.
|
||||
*
|
||||
* Please note that, this return the first local address in the underlying SCTP ServerChannel's
|
||||
* local address iterator to support Netty Channel API. In other words, its the application's
|
||||
* responsibility to keep track of it's local primary address.
|
||||
*
|
||||
* (To set a local address as primary, the application can request by calling local SCTP stack,
|
||||
* with SctpStandardSocketOption.SCTP_PRIMARY_ADDR option).
|
||||
*/
|
||||
@Override
|
||||
InetSocketAddress localAddress();
|
||||
|
||||
/**
|
||||
* Return all local addresses of the SCTP server channel.
|
||||
* Please note that, it will return more than one address if this channel is using multi-homing
|
||||
*/
|
||||
Set<InetSocketAddress> allLocalAddresses();
|
||||
|
||||
/**
|
||||
* Bind a address to the already bound channel to enable multi-homing.
|
||||
* The Channel must be bound and yet to be connected.
|
||||
*/
|
||||
ChannelFuture bindAddress(InetAddress localAddress);
|
||||
|
||||
/**
|
||||
* Bind a address to the already bound channel to enable multi-homing.
|
||||
* The Channel must be bound and yet to be connected.
|
||||
*
|
||||
* Will notify the given {@link ChannelPromise} and return a {@link ChannelFuture}
|
||||
*/
|
||||
ChannelFuture bindAddress(InetAddress localAddress, ChannelPromise promise);
|
||||
|
||||
/**
|
||||
* Unbind the address from channel's multi-homing address list.
|
||||
* The address should be added already in multi-homing address list.
|
||||
*/
|
||||
ChannelFuture unbindAddress(InetAddress localAddress);
|
||||
|
||||
/**
|
||||
* Unbind the address from channel's multi-homing address list.
|
||||
* The address should be added already in multi-homing address list.
|
||||
*
|
||||
* Will notify the given {@link ChannelPromise} and return a {@link ChannelFuture}
|
||||
*/
|
||||
ChannelFuture unbindAddress(InetAddress localAddress, ChannelPromise promise);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue