123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- /*
- * This file is part of JSTUN.
- *
- * Copyright (c) 2005 Thomas King <king@t-king.de> - All rights
- * reserved.
- *
- * This software is licensed under either the GNU Public License (GPL),
- * or the Apache 2.0 license. Copies of both license agreements are
- * included in this distribution.
- */
-
- package de.javawi.jstun.test.demo.ice;
-
- import java.net.InetAddress;
- import java.net.NetworkInterface;
- import java.util.Collections;
- import java.util.Enumeration;
- import java.util.HashSet;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Vector;
-
- import de.javawi.jstun.test.DiscoveryInfo;
- import de.javawi.jstun.test.DiscoveryTest;
- import de.javawi.jstun.test.demo.ice.Candidate.CandidateType;
- import de.javawi.jstun.util.Address;
-
- public class ICENegociator {
- // type preference must be an integere from 0 (=lowest) to 126 (=highest) (inclusive)
- private final static int LOCAL_PREFERENCE = 0;
- private final static int SERVER_REFLEXIVE_PREFERENCE = 42;
- private final static int PEER_REFLEXIVE_PREFERENCE = 84;
- private final static int RELAYED_PREFERENCE = 126;
-
- // component id
- private short componentId;
-
- // candidates
- HashSet<Candidate> candidates;
-
- public ICENegociator(short componentId) {
- this.componentId = componentId;
- candidates = new HashSet<Candidate>();
- }
-
- /*
- * This method gathers candidate addresses as described in draft-ietf-mmusic-ice-12.txt Chapter 2.1
- * Unfortunately, only the candidates of the direct attached network interfaces and server reflexive
- * addreses are gathered. So far, no support for relayed candidates is available (because I am not
- * aware of any STUN relay server).
- */
- public void gatherCandidateAddresses() {
- candidates = new HashSet<Candidate>();
- try {
- Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces();
- while (ifaces.hasMoreElements()) {
- NetworkInterface iface = ifaces.nextElement();
- Enumeration<InetAddress> iaddresses = iface.getInetAddresses();
- while (iaddresses.hasMoreElements()) {
- InetAddress iaddress = iaddresses.nextElement();
- if (!iaddress.isLoopbackAddress() && !iaddress.isLinkLocalAddress()) {
- // add host candidate
- Candidate local = new Candidate(new Address(iaddress.getAddress()), componentId);
- candidates.add(local);
- // add server reflexive address
- DiscoveryTest test = new DiscoveryTest(iaddress, "iphone-stun.freenet.de", 3478);
- DiscoveryInfo di = test.test();
- if (di.getPublicIP() != null) {
- Candidate cand = new Candidate(new Address(di.getPublicIP().getAddress()), CandidateType.ServerReflexive, componentId, local);
- cand.setComponentId(componentId);
- candidates.add(cand);
- }
- }
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- public void prioritizeCandidates() {
- // count number of candidate types
- int numberLocal = 0;
- int numberServerReflexive = 0;
- int numberPeerReflexive = 0;
- int numberRelayed = 0;
- // count number of candidates of a particular type
- Iterator<Candidate> iterCandidates = candidates.iterator();
- while (iterCandidates.hasNext()) {
- Candidate cand = iterCandidates.next();
- CandidateType type = cand.getCandidateType();
- if (type == CandidateType.Local) numberLocal++;
- else if (type == CandidateType.ServerReflexive) numberServerReflexive++;
- else if (type == CandidateType.PeerReflexive) numberPeerReflexive++;
- else if (type == CandidateType.Relayed) numberRelayed++;
- }
- // assign priorities
- iterCandidates = candidates.iterator();
- while (iterCandidates.hasNext()) {
- int typeValue = 0;
- int localValue = 0;
- int componentValue = 0;
- Candidate cand = iterCandidates.next();
- CandidateType type = cand.getCandidateType();
- if (type == CandidateType.Local) {
- typeValue = LOCAL_PREFERENCE;
- localValue = numberLocal--;
- }
- else if (type == CandidateType.ServerReflexive) {
- typeValue = SERVER_REFLEXIVE_PREFERENCE;
- localValue = numberServerReflexive--;
- }
- else if (type == CandidateType.PeerReflexive) {
- typeValue = PEER_REFLEXIVE_PREFERENCE;
- localValue = numberPeerReflexive--;
- }
- else if (type == CandidateType.Relayed) {
- typeValue = RELAYED_PREFERENCE;
- localValue = numberRelayed--;
- }
- componentValue = cand.getComponentId();
- int priority = ((2 ^ 24) * typeValue) + ((2 ^ 8) * localValue) + componentValue;
- cand.setPriority(priority);
- }
- }
-
- public List<Candidate> getSortedCandidates() {
- Vector<Candidate> sortedCandidates = new Vector<Candidate>(candidates);
- Collections.sort(sortedCandidates);
- return sortedCandidates;
- }
-
- public static void main(String args[]) {
- ICENegociator cc = new ICENegociator((short) 1);
- // gather candidates
- cc.gatherCandidateAddresses();
- // priorize candidates
- cc.prioritizeCandidates();
- // get SortedCandidates
- List<Candidate> sortedCandidates = cc.getSortedCandidates();
-
- // sent sorted candidate addresses to peer over SDP
- // received sorted candidate addresses of peer over SDP
-
- }
- }
|