11package com .alibaba .dcm .internal ;
22
3+ import com .alibaba .dcm .DnsCache ;
34import com .alibaba .dcm .DnsCacheEntry ;
45
56import java .lang .reflect .Constructor ;
1415import java .util .Map ;
1516import java .util .regex .Pattern ;
1617
18+ import javax .annotation .Nullable ;
1719import javax .annotation .concurrent .GuardedBy ;
1820
1921/**
@@ -41,10 +43,11 @@ public static void setInetAddressCache(String host, String[] ips, long expiratio
4143 IllegalAccessException , InstantiationException , InvocationTargetException ,
4244 ClassNotFoundException , NoSuchFieldException {
4345 host = host .toLowerCase ();
44- Object entry = createCacheEntry (host , ips , expiration );
46+ Object entry = newCacheEntry (host , ips , expiration );
4547
4648 synchronized (getAddressCacheFieldOfInetAddress ()) {
47- getCacheFiledOfInetAddress$CacheEntry ().put (host , entry );
49+ getCacheFiledOfAddressCacheFiledOfInetAddress ().put (host , entry );
50+ getCacheFiledOfNegativeCacheFiledOfInetAddress ().remove (host );
4851 }
4952 }
5053
@@ -53,11 +56,12 @@ public static void removeInetAddressCache(String host)
5356 host = host .toLowerCase ();
5457
5558 synchronized (getAddressCacheFieldOfInetAddress ()) {
56- getCacheFiledOfInetAddress$CacheEntry ().remove (host );
59+ getCacheFiledOfAddressCacheFiledOfInetAddress ().remove (host );
60+ getCacheFiledOfNegativeCacheFiledOfInetAddress ().remove (host );
5761 }
5862 }
5963
60- static Object createCacheEntry (String host , String [] ips , long expiration )
64+ static Object newCacheEntry (String host , String [] ips , long expiration )
6165 throws UnknownHostException , ClassNotFoundException , NoSuchMethodException ,
6266 IllegalAccessException , InvocationTargetException , InstantiationException {
6367 String className = "java.net.InetAddress$CacheEntry" ;
@@ -80,35 +84,71 @@ static Object createCacheEntry(String host, String[] ips, long expiration)
8084 /**
8185 * @return {@link InetAddress.Cache#cache} in {@link InetAddress#addressCache}
8286 */
83- @ SuppressWarnings ("unchecked" )
8487 @ GuardedBy ("getAddressCacheFieldOfInetAddress()" )
85- static Map <String , Object > getCacheFiledOfInetAddress$CacheEntry ()
88+ static Map <String , Object > getCacheFiledOfAddressCacheFiledOfInetAddress ()
89+ throws NoSuchFieldException , IllegalAccessException {
90+ return getCacheFiledOfInetAddress$Cache0 (getAddressCacheFieldOfInetAddress ());
91+ }
92+
93+ /**
94+ * @return {@link InetAddress.Cache#cache} in {@link InetAddress#negativeCache}
95+ */
96+ @ GuardedBy ("getAddressCacheFieldOfInetAddress()" )
97+ static Map <String , Object > getCacheFiledOfNegativeCacheFiledOfInetAddress ()
98+ throws NoSuchFieldException , IllegalAccessException {
99+ return getCacheFiledOfInetAddress$Cache0 (getNegativeCacheFieldOfInetAddress ());
100+ }
101+
102+ @ SuppressWarnings ("unchecked" )
103+ static Map <String , Object > getCacheFiledOfInetAddress$Cache0 (Object inetAddressCache )
86104 throws NoSuchFieldException , IllegalAccessException {
87- final Object inetAddressCache = getAddressCacheFieldOfInetAddress ();
88105 Class clazz = inetAddressCache .getClass ();
89106
90107 final Field cacheMapField = clazz .getDeclaredField ("cache" );
91108 cacheMapField .setAccessible (true );
92109 return (Map <String , Object >) cacheMapField .get (inetAddressCache );
93110 }
94111
95- static volatile Object ADDRESS_CACHE = null ;
96-
97112 /**
98113 * @return {@link InetAddress#addressCache}
99114 */
100115 static Object getAddressCacheFieldOfInetAddress ()
101116 throws NoSuchFieldException , IllegalAccessException {
102- if (ADDRESS_CACHE == null ) {
117+ return getAddressCacheFieldsOfInetAddress0 ()[0 ];
118+ }
119+
120+ /**
121+ * @return {@link InetAddress#negativeCache}
122+ */
123+ static Object getNegativeCacheFieldOfInetAddress ()
124+ throws NoSuchFieldException , IllegalAccessException {
125+ return getAddressCacheFieldsOfInetAddress0 ()[1 ];
126+ }
127+
128+ static volatile Object [] ADDRESS_CACHE_AND_NEGATIVE_CACHE = null ;
129+
130+ /**
131+ * @return {@link InetAddress#addressCache} and {@link InetAddress#negativeCache}
132+ */
133+ static Object [] getAddressCacheFieldsOfInetAddress0 ()
134+ throws NoSuchFieldException , IllegalAccessException {
135+ if (ADDRESS_CACHE_AND_NEGATIVE_CACHE == null ) {
103136 synchronized (InetAddressCacheUtil .class ) {
104- if (ADDRESS_CACHE == null ) { // double check
137+ if (ADDRESS_CACHE_AND_NEGATIVE_CACHE == null ) { // double check
105138 final Field cacheField = InetAddress .class .getDeclaredField ("addressCache" );
106139 cacheField .setAccessible (true );
107- ADDRESS_CACHE = cacheField .get (InetAddress .class );
140+
141+ final Field negativeCacheField = InetAddress .class .getDeclaredField ("negativeCache" );
142+ negativeCacheField .setAccessible (true );
143+
144+ ADDRESS_CACHE_AND_NEGATIVE_CACHE = new Object []{
145+ cacheField .get (InetAddress .class ),
146+ negativeCacheField .get (InetAddress .class )
147+ };
108148 }
109149 }
110150 }
111- return ADDRESS_CACHE ;
151+ return ADDRESS_CACHE_AND_NEGATIVE_CACHE ;
112152 }
113153
114154 static InetAddress [] toInetAddressArray (String host , String [] ips ) throws UnknownHostException {
@@ -136,31 +176,39 @@ static byte[] ip2ByteArray(String ip) {
136176 return address ;
137177 }
138178
179+ @ Nullable
139180 public static DnsCacheEntry getInetAddressCache (String host )
140181 throws NoSuchFieldException , IllegalAccessException {
141182 host = host .toLowerCase ();
142183
143184 Object cacheEntry ;
144185 synchronized (getAddressCacheFieldOfInetAddress ()) {
145- cacheEntry = getCacheFiledOfInetAddress$CacheEntry ().get (host );
186+ cacheEntry = getCacheFiledOfAddressCacheFiledOfInetAddress ().get (host );
146187 }
147188 return inetAddress$CacheEntry2DnsCacheEntry (host , cacheEntry );
148189 }
149190
150- public static List < DnsCacheEntry > listInetAddressCache ()
191+ public static DnsCache listInetAddressCache ()
151192 throws NoSuchFieldException , IllegalAccessException {
152- List <DnsCacheEntry > list = new ArrayList <DnsCacheEntry >();
153193
154194 final Map <String , Object > cache ;
195+ final Map <String , Object > negativeCache ;
155196 synchronized (getAddressCacheFieldOfInetAddress ()) {
156- cache = new HashMap <String , Object >(getCacheFiledOfInetAddress$CacheEntry ());
197+ cache = new HashMap <String , Object >(getCacheFiledOfAddressCacheFiledOfInetAddress ());
198+ negativeCache = new HashMap <String , Object >(getCacheFiledOfNegativeCacheFiledOfInetAddress ());
157199 }
158200
201+ List <DnsCacheEntry > retCache = new ArrayList <DnsCacheEntry >();
159202 for (Map .Entry <String , Object > entry : cache .entrySet ()) {
160203 final String host = entry .getKey ();
161- list .add (inetAddress$CacheEntry2DnsCacheEntry (host , entry .getValue ()));
204+ retCache .add (inetAddress$CacheEntry2DnsCacheEntry (host , entry .getValue ()));
205+ }
206+ List <DnsCacheEntry > retNegativeCache = new ArrayList <DnsCacheEntry >();
207+ for (Map .Entry <String , Object > entry : negativeCache .entrySet ()) {
208+ final String host = entry .getKey ();
209+ retNegativeCache .add (inetAddress$CacheEntry2DnsCacheEntry (host , entry .getValue ()));
162210 }
163- return list ;
211+ return new DnsCache ( retCache , retNegativeCache ) ;
164212 }
165213
166214
@@ -212,7 +260,8 @@ public static List<DnsCacheEntry> listInetAddressCache()
212260
213261 public static void clearInetAddressCache () throws NoSuchFieldException , IllegalAccessException {
214262 synchronized (getAddressCacheFieldOfInetAddress ()) {
215- getCacheFiledOfInetAddress$CacheEntry ().clear ();
263+ getCacheFiledOfAddressCacheFiledOfInetAddress ().clear ();
264+ getCacheFiledOfNegativeCacheFiledOfInetAddress ().clear ();
216265 }
217266 }
218267
0 commit comments