Unsupported library that attempts to punch holes through NAT
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

ICENegociator.java 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /*
  2. * This file is part of JSTUN.
  3. *
  4. * Copyright (c) 2005 Thomas King <king@t-king.de> - All rights
  5. * reserved.
  6. *
  7. * This software is licensed under either the GNU Public License (GPL),
  8. * or the Apache 2.0 license. Copies of both license agreements are
  9. * included in this distribution.
  10. */
  11. package de.javawi.jstun.test.demo.ice;
  12. import java.net.InetAddress;
  13. import java.net.NetworkInterface;
  14. import java.util.Collections;
  15. import java.util.Enumeration;
  16. import java.util.HashSet;
  17. import java.util.Iterator;
  18. import java.util.List;
  19. import java.util.Vector;
  20. import de.javawi.jstun.test.DiscoveryInfo;
  21. import de.javawi.jstun.test.DiscoveryTest;
  22. import de.javawi.jstun.test.demo.ice.Candidate.CandidateType;
  23. import de.javawi.jstun.util.Address;
  24. public class ICENegociator {
  25. // type preference must be an integere from 0 (=lowest) to 126 (=highest) (inclusive)
  26. private final static int LOCAL_PREFERENCE = 0;
  27. private final static int SERVER_REFLEXIVE_PREFERENCE = 42;
  28. private final static int PEER_REFLEXIVE_PREFERENCE = 84;
  29. private final static int RELAYED_PREFERENCE = 126;
  30. // component id
  31. private short componentId;
  32. // candidates
  33. HashSet<Candidate> candidates;
  34. public ICENegociator(short componentId) {
  35. this.componentId = componentId;
  36. candidates = new HashSet<Candidate>();
  37. }
  38. /*
  39. * This method gathers candidate addresses as described in draft-ietf-mmusic-ice-12.txt Chapter 2.1
  40. * Unfortunately, only the candidates of the direct attached network interfaces and server reflexive
  41. * addreses are gathered. So far, no support for relayed candidates is available (because I am not
  42. * aware of any STUN relay server).
  43. */
  44. public void gatherCandidateAddresses() {
  45. candidates = new HashSet<Candidate>();
  46. try {
  47. Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces();
  48. while (ifaces.hasMoreElements()) {
  49. NetworkInterface iface = ifaces.nextElement();
  50. Enumeration<InetAddress> iaddresses = iface.getInetAddresses();
  51. while (iaddresses.hasMoreElements()) {
  52. InetAddress iaddress = iaddresses.nextElement();
  53. if (!iaddress.isLoopbackAddress() && !iaddress.isLinkLocalAddress()) {
  54. // add host candidate
  55. Candidate local = new Candidate(new Address(iaddress.getAddress()), componentId);
  56. candidates.add(local);
  57. // add server reflexive address
  58. DiscoveryTest test = new DiscoveryTest(iaddress, "iphone-stun.freenet.de", 3478);
  59. DiscoveryInfo di = test.test();
  60. if (di.getPublicIP() != null) {
  61. Candidate cand = new Candidate(new Address(di.getPublicIP().getAddress()), CandidateType.ServerReflexive, componentId, local);
  62. cand.setComponentId(componentId);
  63. candidates.add(cand);
  64. }
  65. }
  66. }
  67. }
  68. } catch (Exception e) {
  69. e.printStackTrace();
  70. }
  71. }
  72. public void prioritizeCandidates() {
  73. // count number of candidate types
  74. int numberLocal = 0;
  75. int numberServerReflexive = 0;
  76. int numberPeerReflexive = 0;
  77. int numberRelayed = 0;
  78. // count number of candidates of a particular type
  79. Iterator<Candidate> iterCandidates = candidates.iterator();
  80. while (iterCandidates.hasNext()) {
  81. Candidate cand = iterCandidates.next();
  82. CandidateType type = cand.getCandidateType();
  83. if (type == CandidateType.Local) numberLocal++;
  84. else if (type == CandidateType.ServerReflexive) numberServerReflexive++;
  85. else if (type == CandidateType.PeerReflexive) numberPeerReflexive++;
  86. else if (type == CandidateType.Relayed) numberRelayed++;
  87. }
  88. // assign priorities
  89. iterCandidates = candidates.iterator();
  90. while (iterCandidates.hasNext()) {
  91. int typeValue = 0;
  92. int localValue = 0;
  93. int componentValue = 0;
  94. Candidate cand = iterCandidates.next();
  95. CandidateType type = cand.getCandidateType();
  96. if (type == CandidateType.Local) {
  97. typeValue = LOCAL_PREFERENCE;
  98. localValue = numberLocal--;
  99. }
  100. else if (type == CandidateType.ServerReflexive) {
  101. typeValue = SERVER_REFLEXIVE_PREFERENCE;
  102. localValue = numberServerReflexive--;
  103. }
  104. else if (type == CandidateType.PeerReflexive) {
  105. typeValue = PEER_REFLEXIVE_PREFERENCE;
  106. localValue = numberPeerReflexive--;
  107. }
  108. else if (type == CandidateType.Relayed) {
  109. typeValue = RELAYED_PREFERENCE;
  110. localValue = numberRelayed--;
  111. }
  112. componentValue = cand.getComponentId();
  113. int priority = ((2 ^ 24) * typeValue) + ((2 ^ 8) * localValue) + componentValue;
  114. cand.setPriority(priority);
  115. }
  116. }
  117. public List<Candidate> getSortedCandidates() {
  118. Vector<Candidate> sortedCandidates = new Vector<Candidate>(candidates);
  119. Collections.sort(sortedCandidates);
  120. return sortedCandidates;
  121. }
  122. public static void main(String args[]) {
  123. ICENegociator cc = new ICENegociator((short) 1);
  124. // gather candidates
  125. cc.gatherCandidateAddresses();
  126. // priorize candidates
  127. cc.prioritizeCandidates();
  128. // get SortedCandidates
  129. List<Candidate> sortedCandidates = cc.getSortedCandidates();
  130. // sent sorted candidate addresses to peer over SDP
  131. // received sorted candidate addresses of peer over SDP
  132. }
  133. }