keycloak
静的公開メンバ関数 | 静的関数 | 非公開メンバ関数 | 静的非公開メンバ関数 | 静的非公開変数類 | 全メンバ一覧
org.keycloak.common.util.NetworkUtils クラス
org.keycloak.common.util.NetworkUtils 連携図
Collaboration graph

静的公開メンバ関数

static String formatPossibleIpv6Address (String address)
 
static String canonize (String ipv6Address) throws IllegalArgumentException
 
static String formatAddress (InetAddress inet)
 
static String formatAddress (InetSocketAddress inet)
 
static boolean isBindingToMulticastDressSupported ()
 
static boolean checkForMac ()
 

静的関数

 [static initializer]
 

非公開メンバ関数

 NetworkUtils ()
 

静的非公開メンバ関数

static boolean mayBeIPv6Address (String input)
 
static boolean isIPv4AddressInIPv6 (String ipv6Address)
 
static String formatAddress6 (int[] hexRepresentation)
 
static void compactLongestZeroSequence (int[] hexRepresentatoin)
 
static boolean checkForLinux ()
 
static boolean checkForHp ()
 
static boolean checkForSolaris ()
 
static boolean checkForWindows ()
 
static boolean checkForPresence (final String key, final String value)
 

静的非公開変数類

static final int MAX_GROUP_LENGTH = 4
 
static final int IPV6_LEN = 8
 
static final boolean can_bind_to_mcast_addr
 

詳解

Utility methods related to networking.

著者
Brian Stansberry (c) 2011 Red Hat Inc.

構築子と解体子

◆ NetworkUtils()

org.keycloak.common.util.NetworkUtils.NetworkUtils ( )
inlineprivate
438  {
439 
440  }

関数詳解

◆ [static initializer]()

org.keycloak.common.util.NetworkUtils.[static initializer] ( )
inlinestaticpackage

◆ canonize()

static String org.keycloak.common.util.NetworkUtils.canonize ( String  ipv6Address) throws IllegalArgumentException
inlinestatic

Convert IPv6 adress into RFC 5952 form. E.g. 2001:db8:0:1:0:0:0:1 -> 2001:db8:0:1::1

Method is null safe, and if IPv4 address or host name is passed to the method it is returned wihout any processing.

Method also supports IPv4 in IPv6 (e.g. 0:0:0:0:0:ffff:192.0.2.1 -> ::ffff:192.0.2.1), and zone ID (e.g. fe80:0:0:0:f0f0:c0c0:1919:1234%4 -> fe80::f0f0:c0c0:1919:1234%4).

引数
ipv6AddressString representing valid IPv6 address.
戻り値
String representing IPv6 in canonical form.
例外
IllegalArgumentExceptionif IPv6 format is unacceptable.
74  {
75 
76  if (ipv6Address == null) {
77  return null;
78  }
79 
80  // Definitely not an IPv6, return untouched input.
81  if (!mayBeIPv6Address(ipv6Address)) {
82  return ipv6Address;
83  }
84 
85  // Length without zone ID (%zone) or IPv4 address
86  int ipv6AddressLength = ipv6Address.length();
87  if (isIPv4AddressInIPv6(ipv6Address)) {
88  // IPv4 in IPv6
89  // e.g. 0:0:0:0:0:FFFF:127.0.0.1
90  int lastColonPos = ipv6Address.lastIndexOf(":");
91  int lastColonsPos = ipv6Address.lastIndexOf("::");
92  if (lastColonsPos >= 0 && lastColonPos == lastColonsPos + 1) {
93  // IPv6 part ends with two consecutive colons, last colon is part of IPv6 format.
94  // e.g. ::127.0.0.1
95  ipv6AddressLength = lastColonPos + 1;
96  } else {
97  // IPv6 part ends with only one colon, last colon is not part of IPv6 format.
98  // e.g. ::FFFF:127.0.0.1
99  ipv6AddressLength = lastColonPos;
100  }
101  } else if (ipv6Address.contains(":") && ipv6Address.contains("%")) {
102  // Zone ID
103  // e.g. fe80:0:0:0:f0f0:c0c0:1919:1234%4
104  ipv6AddressLength = ipv6Address.lastIndexOf("%");
105  }
106 
107  StringBuilder result = new StringBuilder();
108  char [][] groups = new char[IPV6_LEN][MAX_GROUP_LENGTH];
109  int groupCounter = 0;
110  int charInGroupCounter = 0;
111 
112  // Index of the current zeroGroup, -1 means not found.
113  int zeroGroupIndex = -1;
114  int zeroGroupLength = 0;
115 
116  // maximum length zero group, if there is more then one, then first one
117  int maxZeroGroupIndex = -1;
118  int maxZeroGroupLength = 0;
119 
120  boolean isZero = true;
121  boolean groupStart = true;
122 
123  /*
124  * Two consecutive colons, initial expansion.
125  * e.g. 2001:db8:0:0:1::1 -> 2001:db8:0:0:1:0:0:1
126  */
127  StringBuilder expanded = new StringBuilder(ipv6Address);
128  int colonsPos = ipv6Address.indexOf("::");
129  int length = ipv6AddressLength;
130  int change = 0;
131 
132  if (colonsPos >= 0 && colonsPos < ipv6AddressLength - 2) {
133  int colonCounter = 0;
134  for (int i = 0; i < ipv6AddressLength; i++) {
135  if (ipv6Address.charAt(i) == ':') {
136  colonCounter++;
137  }
138  }
139 
140  if (colonsPos == 0) {
141  expanded.insert(0, "0");
142  change = change + 1;
143  }
144 
145  for (int i = 0; i < IPV6_LEN - colonCounter; i++) {
146  expanded.insert(colonsPos + 1, "0:");
147  change = change + 2;
148  }
149 
150 
151  if (colonsPos == ipv6AddressLength - 2) {
152  expanded.setCharAt(colonsPos + change + 1, '0');
153  } else {
154  expanded.deleteCharAt(colonsPos + change + 1);
155  change = change - 1;
156  }
157  length = length + change;
158  }
159 
160 
161  // Processing one char at the time
162  for (int charCounter = 0; charCounter < length; charCounter++) {
163  char c = expanded.charAt(charCounter);
164  if (c >= 'A' && c <= 'F') {
165  c = (char) (c + 32);
166  }
167  if (c != ':') {
168  groups[groupCounter][charInGroupCounter] = c;
169  if (!(groupStart && c == '0')) {
170  ++charInGroupCounter;
171  groupStart = false;
172  }
173  if (c != '0') {
174  isZero = false;
175  }
176  }
177  if (c == ':' || charCounter == (length - 1)) {
178  // We reached end of current group
179  if (isZero) {
180  ++zeroGroupLength;
181  if (zeroGroupIndex == -1) {
182  zeroGroupIndex = groupCounter;
183  }
184  }
185 
186  if (!isZero || charCounter == (length - 1)) {
187  // We reached end of zero group
188  if (zeroGroupLength > maxZeroGroupLength) {
189  maxZeroGroupLength = zeroGroupLength;
190  maxZeroGroupIndex = zeroGroupIndex;
191  }
192  zeroGroupLength = 0;
193  zeroGroupIndex = -1;
194  }
195  ++groupCounter;
196  charInGroupCounter = 0;
197  isZero = true;
198  groupStart = true;
199  }
200  }
201 
202  int numberOfGroups = groupCounter;
203 
204  // Output results
205  for (groupCounter = 0; groupCounter < numberOfGroups; groupCounter++) {
206  if (maxZeroGroupLength <= 1 || groupCounter < maxZeroGroupIndex
207  || groupCounter >= maxZeroGroupIndex + maxZeroGroupLength) {
208  for (int j = 0; j < MAX_GROUP_LENGTH; j++) {
209  if (groups[groupCounter][j] != 0) {
210  result.append(groups[groupCounter][j]);
211  }
212  }
213  if (groupCounter < (numberOfGroups - 1)
214  && (groupCounter != maxZeroGroupIndex - 1
215  || maxZeroGroupLength <= 1)) {
216  result.append(':');
217  }
218  } else if (groupCounter == maxZeroGroupIndex) {
219  result.append("::");
220  }
221  }
222 
223  // Solve problem with three colons in IPv4 in IPv6 format
224  // e.g. 0:0:0:0:0:0:127.0.0.1 -> :::127.0.0.1 -> ::127.0.0.1
225  int resultLength = result.length();
226  if (result.charAt(resultLength - 1) == ':' && ipv6AddressLength < ipv6Address.length()
227  && ipv6Address.charAt(ipv6AddressLength) == ':') {
228  result.delete(resultLength - 1, resultLength);
229  }
230 
231  /*
232  * Append IPv4 from IPv4-in-IPv6 format or Zone ID
233  */
234  for (int i = ipv6AddressLength; i < ipv6Address.length(); i++) {
235  result.append(ipv6Address.charAt(i));
236  }
237 
238  return result.toString();
239  }
static boolean isIPv4AddressInIPv6(String ipv6Address)
Definition: NetworkUtils.java:280
static boolean mayBeIPv6Address(String input)
Definition: NetworkUtils.java:247
static final int IPV6_LEN
Definition: NetworkUtils.java:35
static final int MAX_GROUP_LENGTH
Definition: NetworkUtils.java:34

◆ checkForHp()

static boolean org.keycloak.common.util.NetworkUtils.checkForHp ( )
inlinestaticprivate
412  {
413  return checkForPresence("os.name", "hp");
414  }
static boolean checkForPresence(final String key, final String value)
Definition: NetworkUtils.java:428

◆ checkForLinux()

static boolean org.keycloak.common.util.NetworkUtils.checkForLinux ( )
inlinestaticprivate
408  {
409  return checkForPresence("os.name", "linux");
410  }
static boolean checkForPresence(final String key, final String value)
Definition: NetworkUtils.java:428

◆ checkForMac()

static boolean org.keycloak.common.util.NetworkUtils.checkForMac ( )
inlinestatic
424  {
425  return checkForPresence("os.name", "mac");
426  }
static boolean checkForPresence(final String key, final String value)
Definition: NetworkUtils.java:428

◆ checkForPresence()

static boolean org.keycloak.common.util.NetworkUtils.checkForPresence ( final String  key,
final String  value 
)
inlinestaticprivate
428  {
429  final String tmp = System.getProperty(key, value);
430  try {
431  return tmp != null && tmp.trim().toLowerCase(Locale.ENGLISH).startsWith(value);
432  } catch (Throwable t) {
433  return false;
434  }
435  }

◆ checkForSolaris()

static boolean org.keycloak.common.util.NetworkUtils.checkForSolaris ( )
inlinestaticprivate
416  {
417  return checkForPresence("os.name", "sun");
418  }
static boolean checkForPresence(final String key, final String value)
Definition: NetworkUtils.java:428

◆ checkForWindows()

static boolean org.keycloak.common.util.NetworkUtils.checkForWindows ( )
inlinestaticprivate
420  {
421  return checkForPresence("os.name", "win");
422  }
static boolean checkForPresence(final String key, final String value)
Definition: NetworkUtils.java:428

◆ compactLongestZeroSequence()

static void org.keycloak.common.util.NetworkUtils.compactLongestZeroSequence ( int []  hexRepresentatoin)
inlinestaticprivate
375  {
376  int bestRunStart = -1;
377  int bestRunLen = -1;
378  boolean inRun = false;
379  int runStart = -1;
380  for(int i=0;i<hexRepresentatoin.length;i++){
381 
382  if(hexRepresentatoin[i] == 0){
383  if(!inRun){
384  runStart = i;
385  inRun = true;
386  }
387  } else {
388  if(inRun){
389  inRun = false;
390  int runLen = i - runStart;
391  if(bestRunLen < 0){
392  bestRunStart = runStart;
393  bestRunLen = runLen;
394  } else {
395  if(runLen > bestRunLen){
396  bestRunStart = runStart;
397  bestRunLen = runLen;
398  }
399  }
400  }
401  }
402  }
403  if(bestRunStart >=0){
404  Arrays.fill(hexRepresentatoin, bestRunStart, bestRunStart + bestRunLen, -1);
405  }
406  }

◆ formatAddress() [1/2]

static String org.keycloak.common.util.NetworkUtils.formatAddress ( InetAddress  inet)
inlinestatic

Formats input address. For IPV4 returns simply host address, for IPV6 formats address according to RFC5952 rules. It does not embed IPV6 address in '[', ']', since those are part of IPV6 URI literal.

引数
inet
戻り値
291  {
292  if(inet == null){
293  throw new NullPointerException();
294  }
295  if(inet instanceof Inet4Address){
296  return inet.getHostAddress();
297  } else if (inet instanceof Inet6Address){
298  byte[] byteRepresentation = inet.getAddress();
299  int[] hexRepresentation = new int[IPV6_LEN];
300 
301  for(int i=0;i < hexRepresentation.length;i++){
302  hexRepresentation[i] = ( byteRepresentation[2*i] & 0xFF) << 8 | ( byteRepresentation[2*i+1] & 0xFF );
303  }
304  compactLongestZeroSequence(hexRepresentation);
305  return formatAddress6(hexRepresentation);
306  } else {
307  return inet.getHostAddress();
308  }
309  }
static final int IPV6_LEN
Definition: NetworkUtils.java:35
static void compactLongestZeroSequence(int[] hexRepresentatoin)
Definition: NetworkUtils.java:375
static String formatAddress6(int[] hexRepresentation)
Definition: NetworkUtils.java:341

◆ formatAddress() [2/2]

static String org.keycloak.common.util.NetworkUtils.formatAddress ( InetSocketAddress  inet)
inlinestatic

Converts socket address into string literal, which has form: 'address:port'. Example:

  • 127.0.0.1:8080
  • dns.name.com:8080
  • [0fe:1::20]:8080
  • [::1]:8080
引数
inet
戻り値
322  {
323  if(inet == null){
324  throw new NullPointerException();
325  }
326  StringBuilder result = new StringBuilder();
327  if(inet.isUnresolved()){
328  result.append(inet.getHostName());
329  }else{
330  result.append(formatPossibleIpv6Address(formatAddress(inet.getAddress())));
331  }
332  result.append(":").append(inet.getPort());
333  return result.toString();
334  }
static String formatPossibleIpv6Address(String address)
Definition: NetworkUtils.java:42
static String formatAddress(InetAddress inet)
Definition: NetworkUtils.java:291

◆ formatAddress6()

static String org.keycloak.common.util.NetworkUtils.formatAddress6 ( int []  hexRepresentation)
inlinestaticprivate

Converts IPV6 int[] representation into valid IPV6 string literal. Sequence of '-1' values are converted into '::'.

引数
hexRepresentation
戻り値
341  {
342  if(hexRepresentation == null){
343  throw new NullPointerException();
344  }
345  if(hexRepresentation.length != IPV6_LEN){
346  throw new IllegalArgumentException();
347  }
348  StringBuilder stringBuilder = new StringBuilder();
349  boolean inCompressedSection = false;
350  for(int i = 0;i<hexRepresentation.length;i++){
351  if(hexRepresentation[i] == -1){
352  if(!inCompressedSection){
353  inCompressedSection = true;
354  if(i == 0){
355  stringBuilder.append("::");
356  } else {
357  stringBuilder.append(':');
358  }
359  }
360  } else {
361  inCompressedSection = false;
362  stringBuilder.append(Integer.toHexString(hexRepresentation[i]));
363  if(i+1<hexRepresentation.length){
364  stringBuilder.append(":");
365  }
366  }
367  }
368  return stringBuilder.toString();
369  }
static final int IPV6_LEN
Definition: NetworkUtils.java:35

◆ formatPossibleIpv6Address()

static String org.keycloak.common.util.NetworkUtils.formatPossibleIpv6Address ( String  address)
inlinestatic
42  {
43  if(address == null) {
44  return null;
45  }
46  String ipv6Address;
47  if (address.startsWith("[") && address.endsWith("]")) {
48  ipv6Address = address.substring(0, address.lastIndexOf(']')).substring(1);
49  } else {
50  ipv6Address = address;
51  }
52  // Definitely not an IPv6, return untouched input.
53  if (!mayBeIPv6Address(ipv6Address)) {
54  return ipv6Address;
55  }
56  return '[' + canonize(ipv6Address) + ']';
57  }
static boolean mayBeIPv6Address(String input)
Definition: NetworkUtils.java:247
static String canonize(String ipv6Address)
Definition: NetworkUtils.java:74

◆ isBindingToMulticastDressSupported()

static boolean org.keycloak.common.util.NetworkUtils.isBindingToMulticastDressSupported ( )
inlinestatic
371  {
372  return can_bind_to_mcast_addr;
373  }
static final boolean can_bind_to_mcast_addr
Definition: NetworkUtils.java:36

◆ isIPv4AddressInIPv6()

static boolean org.keycloak.common.util.NetworkUtils.isIPv4AddressInIPv6 ( String  ipv6Address)
inlinestaticprivate

Check if it is an IPv4 in IPv6 format. e.g. 0:0:0:0:0:FFFF:127.0.0.1

引数
ipv6Addressthe address
戻り値
true, if input string is an IPv4 address in IPv6 format.
280  {
281  return (ipv6Address.contains(":") && ipv6Address.contains("."));
282  }

◆ mayBeIPv6Address()

static boolean org.keycloak.common.util.NetworkUtils.mayBeIPv6Address ( String  input)
inlinestaticprivate

Heuristic check if string might be an IPv6 address.

引数
inputAny string or null
戻り値
true, if input string contains only hex digits and at least two colons, before '.' or '' character.
247  {
248  if (input == null) {
249  return false;
250  }
251 
252  boolean result = false;
253  int colonsCounter = 0;
254  int length = input.length();
255  for (int i = 0; i < length; i++) {
256  char c = input.charAt(i);
257  if (c == '.' || c == '%') {
258  // IPv4 in IPv6 or Zone ID detected, end of checking.
259  break;
260  }
261  if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f')
262  || (c >= 'A' && c <= 'F') || c == ':')) {
263  return false;
264  } else if (c == ':') {
265  colonsCounter++;
266  }
267  }
268  if (colonsCounter >= 2) {
269  result = true;
270  }
271  return result;
272  }

メンバ詳解

◆ can_bind_to_mcast_addr

final boolean org.keycloak.common.util.NetworkUtils.can_bind_to_mcast_addr
staticprivate

◆ IPV6_LEN

final int org.keycloak.common.util.NetworkUtils.IPV6_LEN = 8
staticprivate

◆ MAX_GROUP_LENGTH

final int org.keycloak.common.util.NetworkUtils.MAX_GROUP_LENGTH = 4
staticprivate

このクラス詳解は次のファイルから抽出されました: