DnsQueryContext get(InetSocketAddress nameServerAddr, int id) { final IntObjectMap<DnsQueryContext> contexts = getContextMap(nameServerAddr); final DnsQueryContext qCtx; if (contexts != null) { synchronized (contexts) { qCtx = contexts.get(id); } } else { qCtx = null; } return qCtx; }
int add(DnsQueryContext qCtx) { final IntObjectMap<DnsQueryContext> contexts = getOrCreateContextMap(qCtx.nameServerAddr()); int id = PlatformDependent.threadLocalRandom().nextInt(65536 - 1) + 1; final int maxTries = 65535 << 1; int tries = 0; synchronized (contexts) { for (;;) { if (!contexts.containsKey(id)) { contexts.put(id, qCtx); return id; } id = id + 1 & 0xFFFF; if (++tries >= maxTries) { throw new IllegalStateException("query ID space exhausted: " + qCtx.question()); } } } }
@Override public void operationComplete(Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> future) { // Cancel the timeout task. final ScheduledFuture<?> timeoutFuture = this.timeoutFuture; if (timeoutFuture != null) { this.timeoutFuture = null; timeoutFuture.cancel(false); } // Remove the id from the manager as soon as the query completes. This may be because of success, failure or // cancellation parent.queryContextManager.remove(nameServerAddr, id); } }
private IntObjectMap<DnsQueryContext> getOrCreateContextMap(InetSocketAddress nameServerAddr) { synchronized (map) { final IntObjectMap<DnsQueryContext> contexts = map.get(nameServerAddr); if (contexts != null) { return contexts; } final IntObjectMap<DnsQueryContext> newContexts = new IntObjectHashMap<DnsQueryContext>(); final InetAddress a = nameServerAddr.getAddress(); final int port = nameServerAddr.getPort(); map.put(nameServerAddr, newContexts); if (a instanceof Inet4Address) { // Also add the mapping for the IPv4-compatible IPv6 address. final Inet4Address a4 = (Inet4Address) a; if (a4.isLoopbackAddress()) { map.put(new InetSocketAddress(NetUtil.LOCALHOST6, port), newContexts); } else { map.put(new InetSocketAddress(toCompactAddress(a4), port), newContexts); } } else if (a instanceof Inet6Address) { // Also add the mapping for the IPv4 address if this IPv6 address is compatible. final Inet6Address a6 = (Inet6Address) a; if (a6.isLoopbackAddress()) { map.put(new InetSocketAddress(NetUtil.LOCALHOST4, port), newContexts); } else if (a6.isIPv4CompatibleAddress()) { map.put(new InetSocketAddress(toIPv4Address(a6), port), newContexts); } } return newContexts; } }
@Override public void channelRead(ChannelHandlerContext ctx, Object msg) { try { final DatagramDnsResponse res = (DatagramDnsResponse) msg; final int queryId = res.id(); if (logger.isDebugEnabled()) { logger.debug("{} RECEIVED: [{}: {}], {}", ch, queryId, res.sender(), res); } final DnsQueryContext qCtx = queryContextManager.get(res.sender(), queryId); if (qCtx == null) { logger.warn("{} Received a DNS response with an unknown ID: {}", ch, queryId); return; } qCtx.finish(res); } finally { ReferenceCountUtil.safeRelease(msg); } }
DnsQueryContext(DnsNameResolver parent, InetSocketAddress nameServerAddr, DnsQuestion question, DnsRecord[] additionals, Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>> promise) { this.parent = checkNotNull(parent, "parent"); this.nameServerAddr = checkNotNull(nameServerAddr, "nameServerAddr"); this.question = checkNotNull(question, "question"); this.additionals = checkNotNull(additionals, "additionals"); this.promise = checkNotNull(promise, "promise"); recursionDesired = parent.isRecursionDesired(); id = parent.queryContextManager.add(this); // Ensure we remove the id from the QueryContextManager once the query completes. promise.addListener(this); if (parent.isOptResourceEnabled()) { optResource = new AbstractDnsOptPseudoRrRecord(parent.maxPayloadSize(), 0, 0) { // We may want to remove this in the future and let the user just specify the opt record in the query. }; } else { optResource = null; } }
private IntObjectMap<DnsQueryContext> getOrCreateContextMap(InetSocketAddress nameServerAddr) { synchronized (map) { final IntObjectMap<DnsQueryContext> contexts = map.get(nameServerAddr); if (contexts != null) { return contexts; } final IntObjectMap<DnsQueryContext> newContexts = new IntObjectHashMap<DnsQueryContext>(); final InetAddress a = nameServerAddr.getAddress(); final int port = nameServerAddr.getPort(); map.put(nameServerAddr, newContexts); if (a instanceof Inet4Address) { // Also add the mapping for the IPv4-compatible IPv6 address. final Inet4Address a4 = (Inet4Address) a; if (a4.isLoopbackAddress()) { map.put(new InetSocketAddress(NetUtil.LOCALHOST6, port), newContexts); } else { map.put(new InetSocketAddress(toCompatAddress(a4), port), newContexts); } } else if (a instanceof Inet6Address) { // Also add the mapping for the IPv4 address if this IPv6 address is compatible. final Inet6Address a6 = (Inet6Address) a; if (a6.isLoopbackAddress()) { map.put(new InetSocketAddress(NetUtil.LOCALHOST4, port), newContexts); } else if (a6.isIPv4CompatibleAddress()) { map.put(new InetSocketAddress(toIPv4Address(a6), port), newContexts); } } return newContexts; } }
final DnsQueryContextManager queryContextManager = new DnsQueryContextManager();
private IntObjectMap<DnsQueryContext> getOrCreateContextMap(InetSocketAddress nameServerAddr) { synchronized (map) { final IntObjectMap<DnsQueryContext> contexts = map.get(nameServerAddr); if (contexts != null) { return contexts; } final IntObjectMap<DnsQueryContext> newContexts = new IntObjectHashMap<DnsQueryContext>(); final InetAddress a = nameServerAddr.getAddress(); final int port = nameServerAddr.getPort(); map.put(nameServerAddr, newContexts); if (a instanceof Inet4Address) { // Also add the mapping for the IPv4-compatible IPv6 address. final Inet4Address a4 = (Inet4Address) a; if (a4.isLoopbackAddress()) { map.put(new InetSocketAddress(NetUtil.LOCALHOST6, port), newContexts); } else { map.put(new InetSocketAddress(toCompactAddress(a4), port), newContexts); } } else if (a instanceof Inet6Address) { // Also add the mapping for the IPv4 address if this IPv6 address is compatible. final Inet6Address a6 = (Inet6Address) a; if (a6.isLoopbackAddress()) { map.put(new InetSocketAddress(NetUtil.LOCALHOST4, port), newContexts); } else if (a6.isIPv4CompatibleAddress()) { map.put(new InetSocketAddress(toIPv4Address(a6), port), newContexts); } } return newContexts; } }
@Override public void channelRead(ChannelHandlerContext ctx, Object msg) { try { final DatagramDnsResponse res = (DatagramDnsResponse) msg; final int queryId = res.id(); if (logger.isDebugEnabled()) { logger.debug("{} RECEIVED: [{}: {}], {}", ch, queryId, res.sender(), res); } final DnsQueryContext qCtx = queryContextManager.get(res.sender(), queryId); if (qCtx == null) { logger.warn("{} Received a DNS response with an unknown ID: {}", ch, queryId); return; } qCtx.finish(res); } finally { ReferenceCountUtil.safeRelease(msg); } }
DnsQueryContext(DnsNameResolver parent, InetSocketAddress nameServerAddr, DnsQuestion question, DnsRecord[] additionals, Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>> promise) { this.parent = checkNotNull(parent, "parent"); this.nameServerAddr = checkNotNull(nameServerAddr, "nameServerAddr"); this.question = checkNotNull(question, "question"); this.additionals = checkNotNull(additionals, "additionals"); this.promise = checkNotNull(promise, "promise"); recursionDesired = parent.isRecursionDesired(); id = parent.queryContextManager.add(this); // Ensure we remove the id from the QueryContextManager once the query completes. promise.addListener(this); if (parent.isOptResourceEnabled()) { optResource = new AbstractDnsOptPseudoRrRecord(parent.maxPayloadSize(), 0, 0) { // We may want to remove this in the future and let the user just specify the opt record in the query. }; } else { optResource = null; } }
final DnsQueryContextManager queryContextManager = new DnsQueryContextManager();
private IntObjectMap<DnsQueryContext> getOrCreateContextMap(InetSocketAddress nameServerAddr) { synchronized (map) { final IntObjectMap<DnsQueryContext> contexts = map.get(nameServerAddr); if (contexts != null) { return contexts; } final IntObjectMap<DnsQueryContext> newContexts = new IntObjectHashMap<DnsQueryContext>(); final InetAddress a = nameServerAddr.getAddress(); final int port = nameServerAddr.getPort(); map.put(nameServerAddr, newContexts); if (a instanceof Inet4Address) { // Also add the mapping for the IPv4-compatible IPv6 address. final Inet4Address a4 = (Inet4Address) a; if (a4.isLoopbackAddress()) { map.put(new InetSocketAddress(NetUtil.LOCALHOST6, port), newContexts); } else { map.put(new InetSocketAddress(toCompactAddress(a4), port), newContexts); } } else if (a instanceof Inet6Address) { // Also add the mapping for the IPv4 address if this IPv6 address is compatible. final Inet6Address a6 = (Inet6Address) a; if (a6.isLoopbackAddress()) { map.put(new InetSocketAddress(NetUtil.LOCALHOST4, port), newContexts); } else if (a6.isIPv4CompatibleAddress()) { map.put(new InetSocketAddress(toIPv4Address(a6), port), newContexts); } } return newContexts; } }
DnsQueryContext remove(InetSocketAddress nameServerAddr, int id) { final IntObjectMap<DnsQueryContext> contexts = getContextMap(nameServerAddr); if (contexts == null) { return null; } synchronized (contexts) { return contexts.remove(id); } }
@Override public void operationComplete(Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> future) { // Cancel the timeout task. final ScheduledFuture<?> timeoutFuture = this.timeoutFuture; if (timeoutFuture != null) { this.timeoutFuture = null; timeoutFuture.cancel(false); } // Remove the id from the manager as soon as the query completes. This may be because of success, failure or // cancellation parent.queryContextManager.remove(nameServerAddr, id); } }
int add(DnsQueryContext qCtx) { final IntObjectMap<DnsQueryContext> contexts = getOrCreateContextMap(qCtx.nameServerAddr()); int id = PlatformDependent.threadLocalRandom().nextInt(65536 - 1) + 1; final int maxTries = 65535 << 1; int tries = 0; synchronized (contexts) { for (;;) { if (!contexts.containsKey(id)) { contexts.put(id, qCtx); return id; } id = id + 1 & 0xFFFF; if (++tries >= maxTries) { throw new IllegalStateException("query ID space exhausted: " + qCtx.question()); } } } }
@Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { try { final DatagramDnsResponse res = (DatagramDnsResponse) msg; final int queryId = res.id(); if (logger.isDebugEnabled()) { logger.debug("{} RECEIVED: [{}: {}], {}", ch, queryId, res.sender(), res); } final DnsQueryContext qCtx = queryContextManager.get(res.sender(), queryId); if (qCtx == null) { logger.warn("{} Received a DNS response with an unknown ID: {}", ch, queryId); return; } qCtx.finish(res); } finally { ReferenceCountUtil.safeRelease(msg); } }
DnsQueryContext(DnsNameResolver parent, InetSocketAddress nameServerAddr, DnsQuestion question, DnsRecord[] additionals, Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>> promise) { this.parent = checkNotNull(parent, "parent"); this.nameServerAddr = checkNotNull(nameServerAddr, "nameServerAddr"); this.question = checkNotNull(question, "question"); this.additionals = checkNotNull(additionals, "additionals"); this.promise = checkNotNull(promise, "promise"); recursionDesired = parent.isRecursionDesired(); id = parent.queryContextManager.add(this); if (parent.isOptResourceEnabled()) { optResource = new AbstractDnsOptPseudoRrRecord(parent.maxPayloadSize(), 0, 0) { // We may want to remove this in the future and let the user just specify the opt record in the query. }; } else { optResource = null; } }
final DnsQueryContextManager queryContextManager = new DnsQueryContextManager();
private IntObjectMap<DnsQueryContext> getOrCreateContextMap(InetSocketAddress nameServerAddr) { synchronized (map) { final IntObjectMap<DnsQueryContext> contexts = map.get(nameServerAddr); if (contexts != null) { return contexts; } final IntObjectMap<DnsQueryContext> newContexts = new IntObjectHashMap<DnsQueryContext>(); final InetAddress a = nameServerAddr.getAddress(); final int port = nameServerAddr.getPort(); map.put(nameServerAddr, newContexts); if (a instanceof Inet4Address) { // Also add the mapping for the IPv4-compatible IPv6 address. final Inet4Address a4 = (Inet4Address) a; if (a4.isLoopbackAddress()) { map.put(new InetSocketAddress(NetUtil.LOCALHOST6, port), newContexts); } else { map.put(new InetSocketAddress(toCompactAddress(a4), port), newContexts); } } else if (a instanceof Inet6Address) { // Also add the mapping for the IPv4 address if this IPv6 address is compatible. final Inet6Address a6 = (Inet6Address) a; if (a6.isLoopbackAddress()) { map.put(new InetSocketAddress(NetUtil.LOCALHOST4, port), newContexts); } else if (a6.isIPv4CompatibleAddress()) { map.put(new InetSocketAddress(toIPv4Address(a6), port), newContexts); } } return newContexts; } }