Skip to content

Commit

Permalink
Adjusted for TCP handling
Browse files Browse the repository at this point in the history
  • Loading branch information
mondain committed May 14, 2018
1 parent 5e2108e commit 774b0c5
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 233 deletions.
5 changes: 5 additions & 0 deletions src/main/java/org/ice4j/ice/ConnectivityCheckClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,11 @@ public void run() {
pairToCheck = checkList.getNextOrdinaryPairToCheck();
}
if (pairToCheck != null) {
// check for a TCP candidate with a destination port of 9 (masked) and don't attempt to connect to it!
if (pairToCheck.getRemoteCandidate().getTcpType() == CandidateTcpType.ACTIVE) {
logger.info("TCP remote candidate is active with masked port, skip attempt to connect directly");
continue;
}
// Since we suspect that it is possible to startCheckForPair, processSuccessResponse and only then
// setStateInProgress, we'll synchronize. The synchronization root is the one of the CandidatePair#setState method.
synchronized (pairToCheck) {
Expand Down
7 changes: 2 additions & 5 deletions src/main/java/org/ice4j/ice/DefaultNominator.java
Original file line number Diff line number Diff line change
Expand Up @@ -122,19 +122,16 @@ private void strategyNominateFirstValid(PropertyChangeEvent evt) {
*/
private void strategyNominateHighestPrio(PropertyChangeEvent ev) {
String pname = ev.getPropertyName();

if (IceMediaStream.PROPERTY_PAIR_VALIDATED.equals(pname) || (IceMediaStream.PROPERTY_PAIR_STATE_CHANGED.equals(pname) && (ev.getNewValue() == CandidatePairState.FAILED))) {
CandidatePair validPair = (CandidatePair) ev.getSource();
Component parentComponent = validPair.getParentComponent();
IceMediaStream parentStream = parentComponent.getParentStream();
CheckList parentCheckList = parentStream.getCheckList();

if (!parentCheckList.allChecksCompleted())
if (!parentCheckList.allChecksCompleted()) {
return;

}
for (Component component : parentStream.getComponents()) {
CandidatePair pair = parentStream.getValidPair(component);

if (pair != null) {
logger.info("Nominate (highest priority): " + validPair.toShortString());
parentAgent.nominate(pair);
Expand Down
15 changes: 13 additions & 2 deletions src/main/java/org/ice4j/ice/IceMediaStream.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.TreeSet;
import java.util.concurrent.ConcurrentLinkedQueue;

import org.ice4j.Transport;
import org.ice4j.TransportAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -301,6 +302,17 @@ protected void pruneCheckList(Queue<CandidatePair> checkList) {
}
break;
}
// if the local candidate is TCP and tcptype is not set, configure it
if (localCnd.getTransport() == Transport.TCP && localCnd.getTcpType() == null) {
// if the remote is passive, set ours to active and anything else (passive or so) we go passive
switch (pair.getRemoteCandidate().getTcpType()) {
case PASSIVE:
localCnd.setTcpType(CandidateTcpType.ACTIVE);
break;
default:
localCnd.setTcpType(CandidateTcpType.PASSIVE);
}
}
tmpCheckList.add(pair);
}
// clear original
Expand Down Expand Up @@ -491,8 +503,7 @@ protected boolean validListContainsNomineeForComponent(Component component) {
protected boolean validListContainsAllComponents() {
for (Component cmp : getComponents()) {
if (getValidPair(cmp) == null) {
//it looks like there's at least one component we don't have a
//valid candidate for.
//it looks like there's at least one component we don't have a valid candidate for.
return false;
}
}
Expand Down
43 changes: 14 additions & 29 deletions src/main/java/org/ice4j/ice/harvest/MappingCandidateHarvester.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,14 @@
import org.slf4j.LoggerFactory;

/**
* Uses a list of addresses as a predefined static mask in order to generate
* {@link TransportAddress}es. This harvester is meant for use in situations
* Uses a list of addresses as a predefined static mask in order to generate {@link TransportAddress}es. This harvester is meant for use in situations
* where servers are deployed behind a NAT or in a DMZ with static port mapping.
* <br>
* Every time the {@link #harvest(Component)} method is called, the mapping
* harvester will return a list of candidates that provide masked alternatives
* Every time the {@link #harvest(Component)} method is called, the mapping harvester will return a list of candidates that provide masked alternatives
* for every host candidate in the component. Kind of like a STUN server.
* <br>
* Example: You run this on a server with address 192.168.0.1, that is behind
* a NAT with public IP: 93.184.216.119. You allocate a host candidate
* 192.168.0.1/UDP/5000. This harvester is going to then generate an address
* 93.184.216.119/UDP/5000
* Example: You run this on a server with address 192.168.0.1, that is behind a NAT with public IP: 93.184.216.119. You allocate a host candidate
* 192.168.0.1/UDP/5000. This harvester is going to then generate an address 93.184.216.119/UDP/5000
* <br>
* This harvester is instant and does not introduce any harvesting latency.
*
Expand All @@ -50,30 +46,26 @@ public class MappingCandidateHarvester extends AbstractCandidateHarvester {
/**
* Creates a mapping harvester with the specified mask
*
* @param mask the TransportAddresses that would be used as a mask.
* @param face the TransportAddresses that we will be masking.
* @param mask the TransportAddresses that would be used as a mask
* @param face the TransportAddresses that we will be masking
*/
public MappingCandidateHarvester(TransportAddress mask, TransportAddress face) {
this.mask = Objects.requireNonNull(mask);
this.face = Objects.requireNonNull(face);
}

/**
* Initializes a {@link MappingCandidateHarvester} instance without
* specified addresses (only useful in subclasses which override
* Initializes a {@link MappingCandidateHarvester} instance without specified addresses (only useful in subclasses which override
* {@link #getMask()} and {@link #getFace()}).
*/
protected MappingCandidateHarvester() {
}

/**
* Maps all candidates to this harvester's mask and adds them to
* component.
* Maps all candidates to this harvester's mask and adds them to component.
*
* @param component the {@link Component} that we'd like to map candidates
* to.
* @return the LocalCandidates gathered by this
* CandidateHarvester or null if no mask is specified.
* @param component the {@link Component} that we'd like to map candidates to
* @return the LocalCandidates gathered by this CandidateHarvester or null if no mask is specified
*/
@Override
public Collection<LocalCandidate> harvest(Component component) {
Expand All @@ -83,30 +75,23 @@ public Collection<LocalCandidate> harvest(Component component) {
logger.info("Harvester not configured: face={}, mask={}", face, mask);
return null;
}

// Report the LocalCandidates gathered by this CandidateHarvester so
// that the harvest is sure to be considered successful.
// Report the LocalCandidates gathered by this CandidateHarvester so that the harvest is sure to be considered successful.
Collection<LocalCandidate> candidates = new HashSet<>();

for (Candidate<?> cand : component.getLocalCandidates()) {
if (!(cand instanceof HostCandidate) || !cand.getTransportAddress().getHostAddress().equals(face.getHostAddress()) || cand.getTransport() != face.getTransport()) {
continue;
}

HostCandidate hostCandidate = (HostCandidate) cand;
TransportAddress mappedAddress = new TransportAddress(mask.getHostAddress(), hostCandidate.getHostAddress().getPort(), hostCandidate.getHostAddress().getTransport());

ServerReflexiveCandidate mappedCandidate = new ServerReflexiveCandidate(mappedAddress, hostCandidate, hostCandidate.getStunServerAddress(), CandidateExtendedType.STATICALLY_MAPPED_CANDIDATE);
if (hostCandidate.isSSL())
if (hostCandidate.isSSL()) {
mappedCandidate.setSSL(true);

//try to add the candidate to the component and then
//only add it to the harvest not redundant
}
//try to add the candidate to the component and then only add it to the harvest not redundant
if (!candidates.contains(mappedCandidate) && component.addLocalCandidate(mappedCandidate)) {
candidates.add(mappedCandidate);
}
}

return candidates;
}

Expand Down
Loading

0 comments on commit 774b0c5

Please sign in to comment.