/* * Jitsi, the OpenSource Java VoIP and Instant Messaging client. * * Copyright @ 2015 Atlassian Pty Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.java.sip.communicator.service.netaddr; import java.io.*; import java.net.*; import net.java.sip.communicator.service.netaddr.event.*; import org.ice4j.ice.*; import org.ice4j.ice.harvest.*; /** * The NetworkAddressManagerService takes care of problems such as * @author Emil Ivov */ public interface NetworkAddressManagerService { /** * The default number of binds that a <tt>NetworkAddressManagerService</tt> * implementation should execute in case a port is already bound to (each * retry would be on a different port). */ public static final int BIND_RETRIES_DEFAULT_VALUE = 50; /** * The name of the property containing number of binds that a * <tt>NetworkAddressManagerService</tt> implementation should execute in * case a port is already bound to (each retry would be on a different * port). */ public static final String BIND_RETRIES_PROPERTY_NAME = "net.java.sip.communicator.service.netaddr.BIND_RETRIES"; /** * Returns an InetAddress instance that represents the localhost, and that * a socket can bind upon or distribute to peers as a contact address. * <p> * This method tries to make for the ambiguity in the implementation of the * InetAddress.getLocalHost() method. * (see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4665037). * <p> * To put it briefly, the issue is about choosing a local source * address to bind to or to distribute to peers. It is possible and even * quite probable to expect that a machine may dispose with multiple * addresses and each of them may be valid for a specific destination. * Example cases include: * <p> * 1) A dual stack IPv6/IPv4 box. <br> * 2) A double NIC box with a leg on the Internet and another one in a * private LAN <br> * 3) In the presence of a virtual interface over a VPN or a MobileIP(v6) * tunnel. * <p> * In all such cases a source local address needs to be chosen according to * the intended destination and after consulting the local routing table. * <p> * @param intendedDestination the address of the destination that we'd like * to access through the local address that we are requesting. * * @return an InetAddress instance representing the local host, and that * a socket can bind upon or distribute to peers as a contact address. */ public InetAddress getLocalHost(InetAddress intendedDestination); /** * Tries to obtain a mapped/public address for the specified port. If the * STUN lib fails, tries to retrieve localhost, if that fails too, returns * null. * * @param intendedDestination the destination that we'd like to use this * address with. * @param port the port whose mapping we are interested in. * * @return a public address corresponding to the specified port or null if * all attempts to retrieve such an address have failed. * * @throws IOException if an error occurs while the underlying resolver lib * is using sockets. * @throws BindException if the port is already in use. */ public InetSocketAddress getPublicAddressFor( InetAddress intendedDestination, int port) throws IOException, BindException; /** * Returns the hardware address (i.e. MAC address) of the specified * interface name. * * @param iface the <tt>NetworkInterface</tt> * @return array of bytes representing the layer 2 address */ public byte[] getHardwareAddress(NetworkInterface iface); /** * Creates a <tt>DatagramSocket</tt> and binds it to on the specified * <tt>localAddress</tt> and a port in the range specified by the * <tt>minPort</tt> and <tt>maxPort</tt> parameters. We first try to bind * the newly created socket on the <tt>preferredPort</tt> port number and * then proceed incrementally upwards until we succeed or reach the bind * retries limit. If we reach the <tt>maxPort</tt> port number before the * bind retries limit, we will then start over again at <tt>minPort</tt> * and keep going until we run out of retries. * * @param laddr the address that we'd like to bind the socket on. * @param preferredPort the port number that we should try to bind to first. * @param minPort the port number where we should first try to bind before * moving to the next one (i.e. <tt>minPort + 1</tt>) * @param maxPort the maximum port number where we should try binding * before giving up and throwinG an exception. * * @return the newly created <tt>DatagramSocket</tt>. * * @throws IllegalArgumentException if either <tt>minPort</tt> or * <tt>maxPort</tt> is not a valid port number. * @throws IOException if an error occurs while the underlying resolver lib * is using sockets. * @throws BindException if we couldn't find a free port between * <tt>minPort</tt> and <tt>maxPort</tt> before reaching the maximum allowed * number of retries. */ public DatagramSocket createDatagramSocket(InetAddress laddr, int preferredPort, int minPort, int maxPort) throws IllegalArgumentException, IOException, BindException; /** * Adds new <tt>NetworkConfigurationChangeListener</tt> which will * be informed for network configuration changes. * @param listener the listener. */ public void addNetworkConfigurationChangeListener( NetworkConfigurationChangeListener listener); /** * Remove <tt>NetworkConfigurationChangeListener</tt>. * @param listener the listener. */ public void removeNetworkConfigurationChangeListener( NetworkConfigurationChangeListener listener); /** * Creates and returns an ICE agent that a protocol could use for the * negotiation of media transport addresses. One ICE agent should only be * used for a single session negotiation. * * @return the newly created ICE Agent. */ public Agent createIceAgent(); /** * Tries to discover a TURN or a STUN server for the specified * <tt>domainName</tt>. The method would first try to discover a TURN * server and then fall back to STUN only. In both cases we would only care * about a UDP transport. * * @param domainName the domain name that we are trying to discover a * TURN server for. * @param userName the name of the user we'd like to use when connecting to * a TURN server (we won't be using credentials in case we only have a STUN * server). * @param password the password that we'd like to try when connecting to * a TURN server (we won't be using credentials in case we only have a STUN * server). * * @return A {@link StunCandidateHarvester} corresponding to the TURN or * STUN server we discovered or <tt>null</tt> if there were no such records * for the specified <tt>domainName</tt> */ public StunCandidateHarvester discoverStunServer(String domainName, byte[] userName, byte[] password); /** * Creates an <tt>IceMediaStrean</tt> and adds to it an RTP and and RTCP * component, which also implies running the currently installed * harvesters so that they would. * * @param rtpPort the port that we should try to bind the RTP component on * (the RTCP one would automatically go to rtpPort + 1) * @param streamName the name of the stream to create * @param agent the <tt>Agent</tt> that should create the stream. * *@return the newly created <tt>IceMediaStream</tt>. * * @throws IllegalArgumentException if <tt>rtpPort</tt> is not a valid port * number. * @throws IOException if an error occurs while the underlying resolver * is using sockets. * @throws BindException if we couldn't find a free port between within the * default number of retries. */ public IceMediaStream createIceStream( int rtpPort, String streamName, Agent agent) throws IllegalArgumentException, IOException, BindException; /** * Creates an <tt>IceMediaStrean</tt> and adds to it one or two * components, which also implies running the currently installed * harvesters. * * @param portBase the port that we should try to bind first component on * (the second one would automatically go to portBase + 1) * @param streamName the name of the stream to create * @param agent the <tt>Agent</tt> that should create the stream. * * @return the newly created <tt>IceMediaStream</tt>. * * @throws IllegalArgumentException if <tt>portBase</tt> is not a valid port * number. If <tt>numComponents</tt> is neither 1 nor 2. * @throws IOException if an error occurs while the underlying resolver * is using sockets. * @throws BindException if we couldn't find a free port between within the * default number of retries. * */ public IceMediaStream createIceStream( int numComponents, int portBase, String streamName, Agent agent) throws IllegalArgumentException, IOException, BindException; }