下面列出了io.netty.channel.ChannelFactory#io.netty.channel.socket.InternetProtocolFamily 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Compute a {@link ResolvedAddressTypes} from some {@link InternetProtocolFamily}s.
* An empty input will return the default value, based on "java.net" System properties.
* Valid inputs are (), (IPv4), (IPv6), (Ipv4, IPv6) and (IPv6, IPv4).
* @param internetProtocolFamilies a valid sequence of {@link InternetProtocolFamily}s
* @return a {@link ResolvedAddressTypes}
*/
public static ResolvedAddressTypes computeResolvedAddressTypes(InternetProtocolFamily... internetProtocolFamilies) {
if (internetProtocolFamilies == null || internetProtocolFamilies.length == 0) {
return DnsNameResolver.DEFAULT_RESOLVE_ADDRESS_TYPES;
}
if (internetProtocolFamilies.length > 2) {
throw new IllegalArgumentException("No more than 2 InternetProtocolFamilies");
}
switch(internetProtocolFamilies[0]) {
case IPv4:
return (internetProtocolFamilies.length >= 2
&& internetProtocolFamilies[1] == InternetProtocolFamily.IPv6) ?
ResolvedAddressTypes.IPV4_PREFERRED: ResolvedAddressTypes.IPV4_ONLY;
case IPv6:
return (internetProtocolFamilies.length >= 2
&& internetProtocolFamilies[1] == InternetProtocolFamily.IPv4) ?
ResolvedAddressTypes.IPV6_PREFERRED: ResolvedAddressTypes.IPV6_ONLY;
default:
throw new IllegalArgumentException(
"Couldn't resolve ResolvedAddressTypes from InternetProtocolFamily array");
}
}
private CompletableFuture<Void> bootstrapServer() {
Bootstrap serverBootstrap = new Bootstrap()
.group(group)
.channelFactory(() -> new NioDatagramChannel(InternetProtocolFamily.IPv4))
.handler(new SimpleChannelInboundHandler<Object>() {
@Override
public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
// Nothing will be sent.
}
})
.option(ChannelOption.IP_MULTICAST_IF, iface)
.option(ChannelOption.SO_REUSEADDR, true);
CompletableFuture<Void> future = new CompletableFuture<>();
serverBootstrap.bind(localAddress).addListener((ChannelFutureListener) f -> {
if (f.isSuccess()) {
serverChannel = f.channel();
future.complete(null);
} else {
future.completeExceptionally(f.cause());
}
});
return future;
}
public List<BootstrapComboFactory<Bootstrap, Bootstrap>> datagram() {
// 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(InternetProtocolFamily.IPv4);
}
@Override
public String toString() {
return NioDatagramChannel.class.getSimpleName() + ".class";
}
});
}
},
new BootstrapFactory<Bootstrap>() {
@Override
public Bootstrap newInstance() {
return new Bootstrap().group(oioWorkerGroup).channel(OioDatagramChannel.class)
.option(ChannelOption.SO_TIMEOUT, OIO_SO_TIMEOUT);
}
}
);
// Populare the combinations.
return combo(bfs, bfs);
}
private boolean doResolveCached(String hostname,
DnsRecord[] additionals,
Promise<InetAddress> promise,
DnsCache resolveCache) {
final List<? extends DnsCacheEntry> cachedEntries = resolveCache.get(hostname, additionals);
if (cachedEntries == null || cachedEntries.isEmpty()) {
return false;
}
Throwable cause = cachedEntries.get(0).cause();
if (cause == null) {
final int numEntries = cachedEntries.size();
// Find the first entry with the preferred address type.
for (InternetProtocolFamily f : resolvedInternetProtocolFamilies) {
for (int i = 0; i < numEntries; i++) {
final DnsCacheEntry e = cachedEntries.get(i);
if (f.addressType().isInstance(e.address())) {
trySuccess(promise, e.address());
return true;
}
}
}
return false;
} else {
tryFailure(promise, cause);
return true;
}
}
private boolean doResolveAllCached(String hostname,
DnsRecord[] additionals,
Promise<List<InetAddress>> promise,
DnsCache resolveCache) {
final List<? extends DnsCacheEntry> cachedEntries = resolveCache.get(hostname, additionals);
if (cachedEntries == null || cachedEntries.isEmpty()) {
return false;
}
Throwable cause = cachedEntries.get(0).cause();
if (cause == null) {
List<InetAddress> result = null;
final int numEntries = cachedEntries.size();
for (InternetProtocolFamily f : resolvedInternetProtocolFamilies) {
for (int i = 0; i < numEntries; i++) {
final DnsCacheEntry e = cachedEntries.get(i);
if (f.addressType().isInstance(e.address())) {
if (result == null) {
result = new ArrayList<InetAddress>(numEntries);
}
result.add(e.address());
}
}
}
if (result != null) {
trySuccess(promise, result);
return true;
}
return false;
} else {
tryFailure(promise, cause);
return true;
}
}
/**
* Convert the {@link InternetProtocolFamily}. This MUST only be called on jdk version >= 7.
*/
public static ProtocolFamily convert(InternetProtocolFamily family) {
switch (family) {
case IPv4:
return StandardProtocolFamily.INET;
case IPv6:
return StandardProtocolFamily.INET6;
default:
throw new IllegalArgumentException();
}
}
private static DatagramChannel newSocket(SelectorProvider provider, InternetProtocolFamily ipFamily) {
if (ipFamily == null) {
return newSocket(provider);
}
checkJavaVersion();
try {
return provider.openDatagramChannel(ProtocolFamilyConverter.convert(ipFamily));
} catch (IOException e) {
throw new ChannelException("Failed to open a socket.", e);
}
}
@Override
public List<TestsuitePermutation.BootstrapComboFactory<Bootstrap, Bootstrap>> datagram() {
// Make the list of Bootstrap factories.
@SuppressWarnings("unchecked")
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(InternetProtocolFamily.IPv4);
}
@Override
public String toString() {
return NioDatagramChannel.class.getSimpleName() + ".class";
}
});
}
},
new BootstrapFactory<Bootstrap>() {
@Override
public Bootstrap newInstance() {
return new Bootstrap().group(KQUEUE_WORKER_GROUP).channel(KQueueDatagramChannel.class);
}
}
);
return combo(bfs, bfs);
}
@Override
public List<TestsuitePermutation.BootstrapComboFactory<Bootstrap, Bootstrap>> datagram() {
// Make the list of Bootstrap factories.
@SuppressWarnings("unchecked")
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(InternetProtocolFamily.IPv4);
}
@Override
public String toString() {
return NioDatagramChannel.class.getSimpleName() + ".class";
}
});
}
},
new BootstrapFactory<Bootstrap>() {
@Override
public Bootstrap newInstance() {
return new Bootstrap().group(EPOLL_WORKER_GROUP).channel(EpollDatagramChannel.class);
}
}
);
return combo(bfs, bfs);
}
/**
* Run IO loops on a supplied {@link EventLoopGroup} from the {@link LoopResources} container.
*
* @param loopResources a new loop resources
* @param family a specific {@link InternetProtocolFamily} to run with
* @return a new {@link UdpServer} reference
*/
public final UdpServer runOn(LoopResources loopResources, InternetProtocolFamily family) {
Objects.requireNonNull(loopResources, "loopResources");
Objects.requireNonNull(family, "family");
UdpServer dup = super.runOn(loopResources, false);
dup.configuration().family = family;
return dup;
}
/**
* Run IO loops on a supplied {@link EventLoopGroup} from the {@link LoopResources} container.
*
* @param loopResources a new loop resources
* @param family a specific {@link InternetProtocolFamily} to run with
* @return a new {@link UdpClient} reference
*/
public final UdpClient runOn(LoopResources loopResources, InternetProtocolFamily family) {
Objects.requireNonNull(loopResources, "loopResources");
Objects.requireNonNull(family, "family");
UdpClient dup = super.runOn(loopResources, false);
dup.configuration().family = family;
return dup;
}
public List<BootstrapComboFactory<Bootstrap, Bootstrap>> datagram() {
// 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(InternetProtocolFamily.IPv4);
}
@Override
public String toString() {
return NioDatagramChannel.class.getSimpleName() + ".class";
}
});
}
},
new BootstrapFactory<Bootstrap>() {
@Override
public Bootstrap newInstance() {
return new Bootstrap().group(oioWorkerGroup).channel(OioDatagramChannel.class);
}
}
);
// Populare the combinations.
return combo(bfs, bfs);
}
/**
* Convert the {@link InternetProtocolFamily}. This MUST only be called on jdk version >= 7.
*/
public static ProtocolFamily convert(InternetProtocolFamily family) {
switch (family) {
case IPv4:
return StandardProtocolFamily.INET;
case IPv6:
return StandardProtocolFamily.INET6;
default:
throw new IllegalArgumentException();
}
}
private static DatagramChannel newSocket(SelectorProvider provider, InternetProtocolFamily ipFamily) {
if (ipFamily == null) {
return newSocket(provider);
}
checkJavaVersion();
try {
return provider.openDatagramChannel(ProtocolFamilyConverter.convert(ipFamily));
} catch (IOException e) {
throw new ChannelException("Failed to open a socket.", e);
}
}
@Override
public List<TestsuitePermutation.BootstrapComboFactory<Bootstrap, Bootstrap>> datagram() {
// 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(InternetProtocolFamily.IPv4);
}
@Override
public String toString() {
return NioDatagramChannel.class.getSimpleName() + ".class";
}
});
}
},
new BootstrapFactory<Bootstrap>() {
@Override
public Bootstrap newInstance() {
return new Bootstrap().group(EPOLL_WORKER_GROUP).channel(EpollDatagramChannel.class);
}
}
);
return combo(bfs, bfs);
}
private void encodeOptEcsRecord(DnsOptEcsRecord record, ByteBuf out) throws Exception {
encodeRecord0(record, out);
int sourcePrefixLength = record.sourcePrefixLength();
int scopePrefixLength = record.scopePrefixLength();
int lowOrderBitsToPreserve = sourcePrefixLength & PREFIX_MASK;
byte[] bytes = record.address();
int addressBits = bytes.length << 3;
if (addressBits < sourcePrefixLength || sourcePrefixLength < 0) {
throw new IllegalArgumentException(sourcePrefixLength + ": " +
sourcePrefixLength + " (expected: 0 >= " + addressBits + ')');
}
// See http://www.iana.org/assignments/address-family-numbers/address-family-numbers.xhtml
final short addressNumber = (short) (bytes.length == 4 ?
InternetProtocolFamily.IPv4.addressNumber() : InternetProtocolFamily.IPv6.addressNumber());
int payloadLength = calculateEcsAddressLength(sourcePrefixLength, lowOrderBitsToPreserve);
int fullPayloadLength = 2 + // OPTION-CODE
2 + // OPTION-LENGTH
2 + // FAMILY
1 + // SOURCE PREFIX-LENGTH
1 + // SCOPE PREFIX-LENGTH
payloadLength; // ADDRESS...
out.writeShort(fullPayloadLength);
out.writeShort(8); // This is the defined type for ECS.
out.writeShort(fullPayloadLength - 4); // Not include OPTION-CODE and OPTION-LENGTH
out.writeShort(addressNumber);
out.writeByte(sourcePrefixLength);
out.writeByte(scopePrefixLength); // Must be 0 in queries.
if (lowOrderBitsToPreserve > 0) {
int bytesLength = payloadLength - 1;
out.writeBytes(bytes, 0, bytesLength);
// Pad the leftover of the last byte with zeros.
out.writeByte(padWithZeros(bytes[bytesLength], lowOrderBitsToPreserve));
} else {
// The sourcePrefixLength align with Byte so just copy in the bytes directly.
out.writeBytes(bytes, 0, payloadLength);
}
}
private static void testIp(InetAddress address, int prefix) throws Exception {
int lowOrderBitsToPreserve = prefix % Byte.SIZE;
ByteBuf addressPart = Unpooled.wrappedBuffer(address.getAddress(), 0,
DefaultDnsRecordEncoder.calculateEcsAddressLength(prefix, lowOrderBitsToPreserve));
if (lowOrderBitsToPreserve > 0) {
// Pad the leftover of the last byte with zeros.
int idx = addressPart.writerIndex() - 1;
byte lastByte = addressPart.getByte(idx);
int paddingMask = ~((1 << (8 - lowOrderBitsToPreserve)) - 1);
addressPart.setByte(idx, lastByte & paddingMask);
}
int payloadSize = nextInt(Short.MAX_VALUE);
int extendedRcode = nextInt(Byte.MAX_VALUE * 2); // Unsigned
int version = nextInt(Byte.MAX_VALUE * 2); // Unsigned
DefaultDnsRecordEncoder encoder = new DefaultDnsRecordEncoder();
ByteBuf out = Unpooled.buffer();
try {
DnsOptEcsRecord record = new DefaultDnsOptEcsRecord(
payloadSize, extendedRcode, version, prefix, address.getAddress());
encoder.encodeRecord(record, out);
assertEquals(0, out.readByte()); // Name
assertEquals(DnsRecordType.OPT.intValue(), out.readUnsignedShort()); // Opt
assertEquals(payloadSize, out.readUnsignedShort()); // payload
assertEquals(record.timeToLive(), out.getUnsignedInt(out.readerIndex()));
// Read unpacked TTL.
assertEquals(extendedRcode, out.readUnsignedByte());
assertEquals(version, out.readUnsignedByte());
assertEquals(extendedRcode, record.extendedRcode());
assertEquals(version, record.version());
assertEquals(0, record.flags());
assertEquals(0, out.readShort());
int payloadLength = out.readUnsignedShort();
assertEquals(payloadLength, out.readableBytes());
assertEquals(8, out.readShort()); // As defined by RFC.
int rdataLength = out.readUnsignedShort();
assertEquals(rdataLength, out.readableBytes());
assertEquals((short) InternetProtocolFamily.of(address).addressNumber(), out.readShort());
assertEquals(prefix, out.readUnsignedByte());
assertEquals(0, out.readUnsignedByte()); // This must be 0 for requests.
assertEquals(addressPart, out);
} finally {
addressPart.release();
out.release();
}
}
InternetProtocolFamily[] resolvedInternetProtocolFamiliesUnsafe() {
return resolvedInternetProtocolFamilies;
}
final InternetProtocolFamily preferredAddressType() {
return preferredAddressType;
}
private static Map<String, InetAddress> testResolve0(DnsNameResolver resolver, Set<String> excludedDomains,
DnsRecordType cancelledType)
throws InterruptedException {
assertThat(resolver.isRecursionDesired(), is(true));
final Map<String, InetAddress> results = new HashMap<String, InetAddress>();
final Map<String, Future<InetAddress>> futures =
new LinkedHashMap<String, Future<InetAddress>>();
for (String name : DOMAINS) {
if (excludedDomains.contains(name)) {
continue;
}
resolve(resolver, futures, name);
}
for (Entry<String, Future<InetAddress>> e : futures.entrySet()) {
String unresolved = e.getKey();
InetAddress resolved = e.getValue().sync().getNow();
logger.info("{}: {}", unresolved, resolved.getHostAddress());
assertThat(resolved.getHostName(), is(unresolved));
boolean typeMatches = false;
for (InternetProtocolFamily f: resolver.resolvedInternetProtocolFamiliesUnsafe()) {
Class<?> resolvedType = resolved.getClass();
if (f.addressType().isAssignableFrom(resolvedType)) {
typeMatches = true;
}
}
assertThat(typeMatches, is(true));
results.put(resolved.getHostName(), resolved);
}
assertQueryObserver(resolver, cancelledType);
return results;
}
@Override
public Channel newChannel() {
return new NioDatagramChannel(InternetProtocolFamily.IPv4);
}
@Override
public void connect() throws Exception {
try {
channelLock.writeLock().lock();
LinkedHashMap<String, ChannelHandler> handlers = getChannelHandlers();
String interfaceIp = getSettings().getInterfaceIp();
String mcastIp = getSettings().getMulticastIp();
int mcastPort = getSettings().getMulticastPort();
this.localNetworkInterface = NetworkInterface.getByInetAddress(Inet4Address.getByName(interfaceIp));
if (this.localNetworkInterface == null) {
throw new ServiceException("Failed to resolve network interface via IP: " + interfaceIp);
}
this.multicastGroup = new InetSocketAddress(InetAddress.getByName(mcastIp), mcastPort);
Bootstrap cb = new Bootstrap();
// Fixme: use ITaskExecutor ?
cb.group(nioEventLoopGroup);
cb.channelFactory(new ChannelFactory<Channel>() {
@Override
public Channel newChannel() {
// Force IPv4
return new NioDatagramChannel(InternetProtocolFamily.IPv4);
}
});
cb.option(ChannelOption.SO_REUSEADDR, true);
cb.option(ChannelOption.IP_MULTICAST_IF, localNetworkInterface);
cb.option(ChannelOption.IP_MULTICAST_TTL, getSettings().getTtl());
cb.localAddress(new InetSocketAddress(InetAddress.getByName(mcastIp), mcastPort));
// we can configure java -Dio.netty.allocator.numDirectArenas=... -Dio.netty.allocator.numHeapArenas=...
cb.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
cb.handler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
handlers.forEach((key, value) -> ch.pipeline().addLast(key, value));
// add exception handler for inbound messages
// outbound exceptions will be routed here by ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE
ch.pipeline().addLast(new ExceptionInboundHandler(nettySession::onExceptionCaught));
}
});
Channel localChannel = cb.bind().addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture bindFuture) throws Exception {
if (!bindFuture.isSuccess()) {
return;
}
DatagramChannel channel = (DatagramChannel) bindFuture.channel();
// TODO: heartbeat loss detection
ChannelFuture future;
String sourceIP = getSettings().getSourceIp();
if (sourceIP == null) {
future = channel.joinGroup(multicastGroup, localNetworkInterface);
} else {
future = channel.joinGroup(multicastGroup.getAddress(), localNetworkInterface, InetAddress.getByName(sourceIP));
}
future.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE).addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
}
}).addListener(ChannelFutureListener.CLOSE_ON_FAILURE).syncUninterruptibly().channel();
localChannel.closeFuture().addListener((ChannelFutureListener) future -> changeStatus(ServiceStatus.DISPOSED, "Connection closed", null));
setChannel(localChannel);
} finally {
channelLock.writeLock().unlock();
}
}
private CompletableFuture<Void> bootstrapClient() {
Bootstrap clientBootstrap = new Bootstrap()
.group(group)
.channelFactory(() -> new NioDatagramChannel(InternetProtocolFamily.IPv4))
.handler(new SimpleChannelInboundHandler<DatagramPacket>() {
@Override
protected void channelRead0(ChannelHandlerContext context, DatagramPacket packet) throws Exception {
byte[] payload = new byte[packet.content().readInt()];
packet.content().readBytes(payload);
Message message = SERIALIZER.decode(payload);
Set<Consumer<byte[]>> listeners = NettyBroadcastService.this.listeners.get(message.subject());
if (listeners != null) {
for (Consumer<byte[]> listener : listeners) {
listener.accept(message.payload());
}
}
}
})
.option(ChannelOption.IP_MULTICAST_IF, iface)
.option(ChannelOption.SO_REUSEADDR, true)
.localAddress(localAddress.getPort());
CompletableFuture<Void> future = new CompletableFuture<>();
clientBootstrap.bind().addListener((ChannelFutureListener) f -> {
if (f.isSuccess()) {
clientChannel = (DatagramChannel) f.channel();
log.info("{} joining multicast group {} on port {}", localAddress.getHostName(), groupAddress.getHostName(), groupAddress.getPort());
clientChannel.joinGroup(groupAddress, iface).addListener(f2 -> {
if (f2.isSuccess()) {
log.info("{} successfully joined multicast group {} on port {}", localAddress.getHostName(), groupAddress.getHostName(), groupAddress.getPort());
future.complete(null);
} else {
log.info("{} failed to join group {} on port {}", localAddress.getHostName(), groupAddress.getHostName(), groupAddress.getPort());
future.completeExceptionally(f2.cause());
}
});
} else {
future.completeExceptionally(f.cause());
}
});
return future;
}
/**
* Creates a new instance.
*
* @param maxPayloadSize the suggested max payload size in bytes
* @param protocolFamily the {@link InternetProtocolFamily} to use. This should be the same as the one used to
* send the query.
*/
public DefaultDnsOptEcsRecord(int maxPayloadSize, InternetProtocolFamily protocolFamily) {
this(maxPayloadSize, 0, 0, 0, protocolFamily.localhost().getAddress());
}
/**
* Create a new instance using the given {@link InternetProtocolFamily}. If {@code null} is used it will depend
* on the Operation Systems default which will be chosen.
*/
public NioDatagramChannel(InternetProtocolFamily ipFamily) {
this(newSocket(DEFAULT_SELECTOR_PROVIDER, ipFamily));
}
/**
* Create a new instance using the given {@link SelectorProvider} and {@link InternetProtocolFamily}.
* If {@link InternetProtocolFamily} is {@code null} it will depend on the Operation Systems default
* which will be chosen.
*/
public NioDatagramChannel(SelectorProvider provider, InternetProtocolFamily ipFamily) {
this(newSocket(provider, ipFamily));
}
/**
* Return the configured {@link InternetProtocolFamily} to run with or null
*
* @return the configured {@link InternetProtocolFamily} to run with or null
*/
@Nullable
public final InternetProtocolFamily family() {
return family;
}
/**
* Return the configured {@link InternetProtocolFamily} to run with or null
*
* @return the configured {@link InternetProtocolFamily} to run with or null
*/
@Nullable
public final InternetProtocolFamily family() {
return family;
}
/**
* Create a new instance using the given {@link InternetProtocolFamily}. If {@code null} is used it will depend
* on the Operation Systems default which will be chosen.
*/
public NioDatagramChannel(InternetProtocolFamily ipFamily) {
this(newSocket(DEFAULT_SELECTOR_PROVIDER, ipFamily));
}
/**
* Create a new instance using the given {@link SelectorProvider} and {@link InternetProtocolFamily}.
* If {@link InternetProtocolFamily} is {@code null} it will depend on the Operation Systems default
* which will be chosen.
*/
public NioDatagramChannel(SelectorProvider provider, InternetProtocolFamily ipFamily) {
this(newSocket(provider, ipFamily));
}