You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SRVRecord.java 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /*
  2. * Copyright (c) 2006-2017 DMDirc Developers
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to deal
  6. * in the Software without restriction, including without limitation the rights
  7. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. * copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. * SOFTWARE.
  21. */
  22. package com.dmdirc.parser.common;
  23. import java.util.ArrayList;
  24. import java.util.HashMap;
  25. import java.util.List;
  26. import javax.naming.NamingEnumeration;
  27. import javax.naming.NamingException;
  28. import javax.naming.directory.Attribute;
  29. /**
  30. * Class to represent an SRV Record.
  31. */
  32. public class SRVRecord implements Comparable<SRVRecord> {
  33. /** Priority of this record. */
  34. private final int priority;
  35. /** Weight of this record. */
  36. private final int weight;
  37. /** Port of this record. */
  38. private final int port;
  39. /** Host of this record. */
  40. private final String host;
  41. /**
  42. * Create a new SRV Record from a String.
  43. *
  44. * @param record Record as a string.
  45. * @throws NamingException if the record is invalid
  46. */
  47. public SRVRecord(final String record) throws NamingException {
  48. final String[] bits = record.split(" ", 4);
  49. if (bits.length < 4) {
  50. throw new NamingException("Invalid SRV Record.");
  51. }
  52. try {
  53. priority = Integer.parseInt(bits[0]);
  54. weight = Integer.parseInt(bits[1]);
  55. port = Integer.parseInt(bits[2]);
  56. host = bits[3].charAt(bits[3].length() - 1) == '.' ? bits[3].substring(0, bits[3].length() - 1) : bits[3];
  57. } catch (final NumberFormatException nfe) {
  58. throw new NamingException("Unable to parse SRV Record parameters."); // NOPMD
  59. }
  60. }
  61. /**
  62. * Get the priority for this SRVRecord.
  63. *
  64. * @return The priority for this SRVRecord.
  65. */
  66. public int getPriority() {
  67. return priority;
  68. }
  69. /**
  70. * Get the weight for this SRVRecord.
  71. *
  72. * @return The weight for this SRVRecord.
  73. */
  74. public int getWeight() {
  75. return weight;
  76. }
  77. /**
  78. * Get the port for this SRVRecord.
  79. *
  80. * @return The port for this SRVRecord.
  81. */
  82. public int getPort() {
  83. return port;
  84. }
  85. /**
  86. * Get the host for this SRVRecord.
  87. *
  88. * @return The host for this SRVRecord.
  89. */
  90. public String getHost() {
  91. return host;
  92. }
  93. @Override
  94. public String toString() {
  95. return priority + " " + weight + ' ' + port + ' ' + host + '.';
  96. }
  97. @Override
  98. public int compareTo(final SRVRecord o) {
  99. if (priority < o.getPriority()) { return -1; }
  100. if (priority > o.getPriority()) { return 1; }
  101. return 0;
  102. }
  103. public static List<SRVRecord> getRecords(final String host) {
  104. final List<SRVRecord> result = new ArrayList<>();
  105. final HashMap<String, String> env = new HashMap<>();
  106. env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
  107. env.put("java.naming.provider.url", "dns:");
  108. try (AutoCloseableInitialDirContext dirContext = new AutoCloseableInitialDirContext(env)) {
  109. final Attribute attr = dirContext.getAttributes(host, new String [] { "SRV" }).get("SRV");
  110. if (attr != null) {
  111. final NamingEnumeration<?> ne = attr.getAll();
  112. while (ne.hasMore()) {
  113. try {
  114. final SRVRecord record = new SRVRecord((String)ne.next());
  115. result.add(record);
  116. } catch (final NamingException nex) { /* Ignore if invalid. */ }
  117. }
  118. }
  119. } catch (final NamingException nex) { /* Ignore errors. */ }
  120. // Ideally we should be sorting this list so that it contains all
  121. // the servers with the lowest priority randomly sorted first, then the
  122. // next priority etc.
  123. // However, in general, the DNS resolver will take care of the ordering
  124. // for us, so we should already get it in a suitable order.
  125. return result;
  126. }
  127. }