@@ -57,6 +57,9 @@ public class NetUtils {
57
57
private static final Map <String , String > hostNameCache = new LRUCache <>(1000 );
58
58
private static volatile InetAddress LOCAL_ADDRESS = null ;
59
59
60
+ private static final String SPLIT_IPV4_CHARECTER = "\\ ." ;
61
+ private static final String SPLIT_IPV6_CHARECTER = ":" ;
62
+
60
63
public static int getRandomPort () {
61
64
return RND_PORT_START + ThreadLocalRandom .current ().nextInt (RND_PORT_RANGE );
62
65
}
@@ -340,13 +343,13 @@ public static String toURL(String protocol, String host, int port, String path)
340
343
return sb .toString ();
341
344
}
342
345
343
- public static void joinMulticastGroup (MulticastSocket multicastSocket , InetAddress multicastAddress ) throws IOException {
346
+ public static void joinMulticastGroup (MulticastSocket multicastSocket , InetAddress multicastAddress ) throws IOException {
344
347
setInterface (multicastSocket , multicastAddress instanceof Inet6Address );
345
348
multicastSocket .setLoopbackMode (false );
346
349
multicastSocket .joinGroup (multicastAddress );
347
350
}
348
351
349
- public static void setInterface (MulticastSocket multicastSocket , boolean preferIpv6 ) throws IOException {
352
+ public static void setInterface (MulticastSocket multicastSocket , boolean preferIpv6 ) throws IOException {
350
353
boolean interfaceSet = false ;
351
354
Enumeration interfaces = NetworkInterface .getNetworkInterfaces ();
352
355
while (interfaces .hasMoreElements ()) {
@@ -370,4 +373,134 @@ public static void setInterface (MulticastSocket multicastSocket, boolean prefer
370
373
}
371
374
}
372
375
376
+ public static boolean matchIpExpression (String pattern , String host , int port ) throws UnknownHostException {
377
+
378
+ // if the pattern is subnet format, it will not be allowed to config port param in pattern.
379
+ if (pattern .contains ("/" )) {
380
+ CIDRUtils utils = new CIDRUtils (pattern );
381
+ return utils .isInRange (host );
382
+ }
383
+
384
+
385
+ return matchIpRange (pattern , host , port );
386
+ }
387
+
388
+ /**
389
+ * @param pattern
390
+ * @param host
391
+ * @param port
392
+ * @return
393
+ * @throws UnknownHostException
394
+ */
395
+ public static boolean matchIpRange (String pattern , String host , int port ) throws UnknownHostException {
396
+ if (pattern == null || host == null ) {
397
+ throw new IllegalArgumentException ("Illegal Argument pattern or hostName. Pattern:" + pattern + ", Host:" + host );
398
+ }
399
+ pattern = pattern .trim ();
400
+ if (pattern .equals ("*.*.*.*" ) || pattern .equals ("*" )) {
401
+ return true ;
402
+ }
403
+
404
+ InetAddress inetAddress = InetAddress .getByName (host );
405
+ boolean isIpv4 = isValidV4Address (inetAddress ) ? true : false ;
406
+ String [] hostAndPort = getPatternHostAndPort (pattern , isIpv4 );
407
+ if (hostAndPort [1 ] != null && !hostAndPort [1 ].equals (String .valueOf (port ))) {
408
+ return false ;
409
+ }
410
+ pattern = hostAndPort [0 ];
411
+
412
+ String splitCharacter = SPLIT_IPV4_CHARECTER ;
413
+ if (!isIpv4 ) {
414
+ splitCharacter = SPLIT_IPV6_CHARECTER ;
415
+ }
416
+ String [] mask = pattern .split (splitCharacter );
417
+ //check format of pattern
418
+ checkHostPattern (pattern , mask , isIpv4 );
419
+
420
+ host = inetAddress .getHostAddress ();
421
+
422
+ String [] ip_address = host .split (splitCharacter );
423
+ if (pattern .equals (host )) {
424
+ return true ;
425
+ }
426
+ // short name condition
427
+ if (!ipPatternContainExpression (pattern )) {
428
+ InetAddress patternAddress = InetAddress .getByName (pattern );
429
+ if (patternAddress .getHostAddress ().equals (host )) {
430
+ return true ;
431
+ } else {
432
+ return false ;
433
+ }
434
+ }
435
+ for (int i = 0 ; i < mask .length ; i ++) {
436
+ if (mask [i ].equals ("*" ) || mask [i ].equals (ip_address [i ])) {
437
+ continue ;
438
+ } else if (mask [i ].contains ("-" )) {
439
+ String [] rangeNumStrs = mask [i ].split ("-" );
440
+ if (rangeNumStrs .length != 2 ) {
441
+ throw new IllegalArgumentException ("There is wrong format of ip Address: " + mask [i ]);
442
+ }
443
+ Integer min = getNumOfIpSegment (rangeNumStrs [0 ], isIpv4 );
444
+ Integer max = getNumOfIpSegment (rangeNumStrs [1 ], isIpv4 );
445
+ Integer ip = getNumOfIpSegment (ip_address [i ], isIpv4 );
446
+ if (ip < min || ip > max ) {
447
+ return false ;
448
+ }
449
+ } else if ("0" .equals (ip_address [i ]) && ("0" .equals (mask [i ]) || "00" .equals (mask [i ]) || "000" .equals (mask [i ]) || "0000" .equals (mask [i ]))) {
450
+ continue ;
451
+ } else if (!mask [i ].equals (ip_address [i ])) {
452
+ return false ;
453
+ }
454
+ }
455
+ return true ;
456
+ }
457
+
458
+ private static boolean ipPatternContainExpression (String pattern ) {
459
+ return pattern .contains ("*" ) || pattern .contains ("-" );
460
+ }
461
+
462
+ private static void checkHostPattern (String pattern , String [] mask , boolean isIpv4 ) {
463
+ if (!isIpv4 ) {
464
+ if (mask .length != 8 && ipPatternContainExpression (pattern )) {
465
+ throw new IllegalArgumentException ("If you config ip expression that contains '*' or '-', please fill qulified ip pattern like 234e:0:4567:0:0:0:3d:*. " );
466
+ }
467
+ if (mask .length != 8 && !pattern .contains ("::" )) {
468
+ throw new IllegalArgumentException ("The host is ipv6, but the pattern is not ipv6 pattern : " + pattern );
469
+ }
470
+ } else {
471
+ if (mask .length != 4 ) {
472
+ throw new IllegalArgumentException ("The host is ipv4, but the pattern is not ipv4 pattern : " + pattern );
473
+ }
474
+ }
475
+ }
476
+
477
+ private static String [] getPatternHostAndPort (String pattern , boolean isIpv4 ) {
478
+ String [] result = new String [2 ];
479
+ if (pattern .startsWith ("[" ) && pattern .contains ("]:" )) {
480
+ int end = pattern .indexOf ("]:" );
481
+ result [0 ] = pattern .substring (1 , end );
482
+ result [1 ] = pattern .substring (end + 2 );
483
+ return result ;
484
+ } else if (pattern .startsWith ("[" ) && pattern .endsWith ("]" )) {
485
+ result [0 ] = pattern .substring (1 , pattern .length () - 1 );
486
+ result [1 ] = null ;
487
+ return result ;
488
+ } else if (isIpv4 && pattern .contains (":" )) {
489
+ int end = pattern .indexOf (":" );
490
+ result [0 ] = pattern .substring (0 , end );
491
+ result [1 ] = pattern .substring (end + 1 );
492
+ return result ;
493
+ } else {
494
+ result [0 ] = pattern ;
495
+ return result ;
496
+ }
497
+ }
498
+
499
+ private static Integer getNumOfIpSegment (String ipSegment , boolean isIpv4 ) {
500
+ if (isIpv4 ) {
501
+ return Integer .parseInt (ipSegment );
502
+ }
503
+ return Integer .parseInt (ipSegment , 16 );
504
+ }
505
+
373
506
}
0 commit comments