diff options
Diffstat (limited to 'src/net/java/sip/communicator/impl/protocol/jabber/IceUdpTransportManager.java')
-rw-r--r-- | src/net/java/sip/communicator/impl/protocol/jabber/IceUdpTransportManager.java | 141 |
1 files changed, 103 insertions, 38 deletions
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/IceUdpTransportManager.java b/src/net/java/sip/communicator/impl/protocol/jabber/IceUdpTransportManager.java index 1f4e3d8..c3c852c 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/IceUdpTransportManager.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/IceUdpTransportManager.java @@ -58,11 +58,21 @@ public class IceUdpTransportManager = Logger.getLogger(IceUdpTransportManager.class); /** + * Default STUN server address. + */ + protected static final String DEFAULT_STUN_SERVER_ADDRESS = "stun.jitsi.net"; + + /** + * Default STUN server port. + */ + protected static final int DEFAULT_STUN_SERVER_PORT = 3478; + + /** * The ICE <tt>Component</tt> IDs in their common order used, for example, * by <tt>DefaultStreamConnector</tt>, <tt>MediaStreamTarget</tt>. */ private static final int[] COMPONENT_IDS - = new int[] { Component.RTP, Component.RTCP }; + = new int[] { Component.RTP, Component.RTCP }; /** * This is where we keep our answer between the time we get the offer and @@ -76,15 +86,6 @@ public class IceUdpTransportManager */ protected final Agent iceAgent; - /** - * Default STUN server address. - */ - protected static final String DEFAULT_STUN_SERVER_ADDRESS = "stun.jitsi.net"; - - /** - * Default STUN server port. - */ - protected static final int DEFAULT_STUN_SERVER_PORT = 3478; /** * Creates a new instance of this transport manager, binding it to the @@ -156,7 +157,10 @@ public class IceUdpTransportManager // in case user has canceled the login window if(credentials == null) + { + logger.info("Credentials were null. User has most likely canceled the login operation"); return null; + } //extract the password the user passed us. char[] pass = credentials.getPassword(); @@ -164,7 +168,10 @@ public class IceUdpTransportManager // the user didn't provide us a password (i.e. canceled the // operation) if(pass == null) + { + logger.info("Password was null. User has most likely canceled the login operation"); return null; + } password = new String(pass); if (credentials.isPasswordPersistent()) @@ -390,28 +397,29 @@ public class IceUdpTransportManager for (int i = 0; i < COMPONENT_IDS.length; i++) { Component component = stream.getComponent(COMPONENT_IDS[i]); - - if (component != null) + if (component == null) { - CandidatePair selectedPair = component.getSelectedPair(); - - if (selectedPair != null) - { - DatagramSocket streamConnectorSocket - = selectedPair.getLocalCandidate(). - getDatagramSocket(); + continue; + } - if (streamConnectorSocket != null) - { - streamConnectorSockets[i] = streamConnectorSocket; - streamConnectorSocketCount++; - } - } + DatagramSocket streamConnectorSocket = component.getSocket(); + if (streamConnectorSocket != null) + { + streamConnectorSockets[i] = streamConnectorSocket; + streamConnectorSocketCount++; + logger.trace("Added a streamConnectorSocket to the array " + + "StreamConnectorSocket and increased " + + "the count of streamConnectorSocketCount by one to " + + streamConnectorSocketCount); } } + if (streamConnectorSocketCount > 0) + { return streamConnectorSockets; + } } + return null; } @@ -742,20 +750,25 @@ public class IceUdpTransportManager ex); } - //let's now update the next port var as best we can: we would assume - //that all local candidates are bound on the same port and set it - //to the one just above. if the assumption is wrong the next bind - //would simply include one more bind retry. + // Attempt to minimize subsequent bind retries: see if we have allocated + // any ports from the dynamic range, and if so update the port tracker. + // Do NOT update the port tracker with non-dynamic ports (e.g. 4443 + // coming from TCP) because this will force it to revert back it its + // configured min port. When maxPort is reached, allocation will begin + // from minPort again, so we don't have to worry about wraps. try { - portTracker.setNextPort( - 1 - + stream - .getComponent(Component.RTCP) - .getLocalCandidates() - .get(0) - .getTransportAddress() - .getPort()); + int maxAllocatedPort = getMaxAllocatedPort( + stream, + portTracker.getMinPort(), + portTracker.getMaxPort()); + + if(maxAllocatedPort > 0) + { + int nextPort = 1 + maxAllocatedPort; + portTracker.setNextPort(nextPort); + logger.debug("Updating the port tracker min port: " + nextPort); + } } catch(Throwable t) { @@ -768,6 +781,48 @@ public class IceUdpTransportManager } /** + * @return the highest local port used by any of the local candidates of + * {@code iceStream}, which falls in the range [{@code min}, {@code max}]. + */ + private int getMaxAllocatedPort(IceMediaStream iceStream, int min, int max) + { + return + Math.max( + getMaxAllocatedPort( + iceStream.getComponent(Component.RTP), + min, max), + getMaxAllocatedPort( + iceStream.getComponent(Component.RTCP), + min, max)); + } + + /** + * @return the highest local port used by any of the local candidates of + * {@code component}, which falls in the range [{@code min}, {@code max}]. + */ + private int getMaxAllocatedPort(Component component, int min, int max) + { + int maxAllocatedPort = -1; + + if (component != null) + { + for (LocalCandidate candidate : component.getLocalCandidates()) + { + int candidatePort = candidate.getTransportAddress().getPort(); + + if (min <= candidatePort + && candidatePort <= max + && maxAllocatedPort < candidatePort) + { + maxAllocatedPort = candidatePort; + } + } + } + + return maxAllocatedPort; + } + + /** * Simply returns the list of local candidates that we gathered during the * harvest. * @@ -898,8 +953,12 @@ public class IceUdpTransportManager = transport.getChildExtensionsOfType( CandidatePacketExtension.class); - if (iceAgentStateIsRunning && (candidates.size() == 0)) + if (iceAgentStateIsRunning && candidates.isEmpty()) + { + logger.info("connectivity establishment has not been started " + + "because candidate list is empty"); return false; + } String media = e.getKey(); IceMediaStream stream = iceAgent.getStream(media); @@ -938,6 +997,12 @@ public class IceUdpTransportManager if (candidate.getGeneration() != generation) continue; + if (candidate.getIP() == null || "".equals(candidate.getIP())) + { + logger.warn("Skipped ICE candidate with empty IP"); + continue; + } + Component component = stream.getComponent(candidate.getComponent()); String relAddr; |