/* * 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.slick.netaddr; import java.net.*; import java.util.*; import junit.framework.*; import net.java.sip.communicator.service.netaddr.*; import org.jitsi.service.configuration.*; import org.osgi.framework.*; /** * Tests basic Network Address Manager Service behaviour. * * @author Emil Ivov * @author Pierre Floury */ public class TestNetworkAddressManagerService extends TestCase { /** * The NetworkAddressManagerService that we will be testing. */ private NetworkAddressManagerService networkAddressManagerService = null; private static final String PROP_STUN_SERVER_ADDR = "net.java.sip.communicator.STUN_SERVER_ADDRESS"; private static final String PROP_STUN_SERVER_PORT = "net.java.sip.communicator.STUN_SERVER_PORT"; private static final String PROP_PREFERRED_NET_IFACE = "net.java.sip.communicator.PREFERRED_NETWORK_INTERFACE"; private static final String PROP_PREFERRED_NET_ADDR = "net.java.sip.communicator.PREFERRED_NETWORK_ADDRESS"; /** * The ConfigurationService that we will be using. */ private ConfigurationService configurationService = null; /** * Constructor. * get a reference to the configuration service * * @param name the name of the test */ public TestNetworkAddressManagerService(String name) { super(name); } /** * Generic JUnit setUp method. That's where we get the configuration and * net address manager services * service. * * @throws Exception if anything goes wrong. */ @Override protected void setUp() throws Exception { super.setUp(); BundleContext context = NetworkAddressManagerServiceLick.bc; // get the configuration service ServiceReference confRef = context .getServiceReference(ConfigurationService.class.getName()); configurationService = (ConfigurationService) context .getService(confRef); // get the netaddr service ServiceReference netRef = context.getServiceReference( NetworkAddressManagerService.class.getName()); networkAddressManagerService = (NetworkAddressManagerService) context.getService(netRef); } /** * Generic JUnit tearDown method. * * @throws Exception if anything goes wrong. */ @Override protected void tearDown() throws Exception { super.tearDown(); } private static boolean isLocalInterfaceAddress(InetAddress address) { try { Enumeration<NetworkInterface> intfs = NetworkInterface.getNetworkInterfaces(); while (intfs.hasMoreElements()) { NetworkInterface intf = intfs.nextElement(); Enumeration<InetAddress> addrs = intf.getInetAddresses(); while (addrs.hasMoreElements()) { try { InetAddress addr = addrs.nextElement(); if(addr.equals(address)) return true; } catch (Exception e) { } } } } catch (Exception e) { e.printStackTrace(); } return false; } private static boolean isLocalInterfaceAddressIPv4(InetAddress address) { if(address instanceof Inet4Address) return isLocalInterfaceAddress(address); return false; } private static boolean isLocalInterfaceAddressIPv6(InetAddress address) { if(address instanceof Inet6Address) return isLocalInterfaceAddress(address); return false; } public void testDummyTest() { //we gotta have at least one test otherwise we have an error } /** * This test will specify all local address one by one as "preferred * address" and test the returned address. * * @throws java.lang.Exception if anything goes wrong. */ /** public void testPreferredNetAddressProperty() throws Exception { initProperties(); //set the original properties String valuePropertyStunName=""; String propertyStunPort=""; //disable stun for this test. we are onlytesting simple logics here. configurationService.setProperty(PROP_STUN_SERVER_ADDR,""); configurationService.setProperty(PROP_STUN_SERVER_PORT,""); //restart the netaddress manager so the it takes the new settings into //account networkAddressManagerService.stop(); networkAddressManagerService.start(); Enumeration intfs = NetworkInterface.getNetworkInterfaces(); while (intfs.hasMoreElements()) { NetworkInterface iface = (NetworkInterface) intfs.nextElement(); Enumeration addrs = iface.getInetAddresses(); while (addrs.hasMoreElements()) { InetAddress addr = (InetAddress) addrs.nextElement(); //set the current address as the preferred one. configurationService.setProperty(PROP_PREFERRED_NET_IFACE, iface.getName()); configurationService.setProperty(PROP_PREFERRED_NET_ADDR, addr.toString()); InetAddress localHost = networkAddressManagerService.getLocalHost(); if( isRoutable(addr) ) { //if the address we set as prefered was routable then //the net address manager should have returned it. assertEquals(addr, localHost); } else { assertFalse(networkAddressManagerService. getLocalHost().isLoopbackAddress()); } } } } public void testBadIpAddressNoIPversionSpecified() throws Exception { initProperties(); //set the original properties //Integer valuePropertyPreferedIPVersion; String valuePropertyStunName="stun01.sipphone.com"; Integer valuePropertyStunPort=new Integer(3478); String valuePropertyNetworkAddress="192.169.1.1"; //String propertyNetworkInterface="" //valuePropertyPreferedIPVersion = new Integer(4); configurationService.setProperty(PROP_STUN_SERVER_ADDR, valuePropertyStunName); configurationService.setProperty(PROP_STUN_SERVER_PORT, valuePropertyStunPort); configurationService.setProperty(PROP_PREFERRED_NET_ADDR, valuePropertyNetworkAddress); InetAddress addr = networkAddressManagerService.getLocalHost(); assertTrue(isLocalInterfaceAddressIPv4(addr) || isLinkLocalIPv4Address(addr) || isRoutable(addr) || getStunAddress().equals(addr)); } public void testBadIpAddressIPv4Specified() throws Exception { initProperties(); //set th original properties //Integer valuePropertyPreferedIPVersion; String valuePropertyStunName="stun01.sipphone.com"; Integer valuePropertyStunPort=new Integer(3478); String valuePropertyNetworkAddress="2001:660:4701:1001:800:1cff:fed1:51"; Integer valuePropertyPreferedIPVersion=new Integer(4); //String propertyNetworkInterface="" //valuePropertyPreferedIPVersion = new Integer(4); configurationService.setProperty(PROP_STUN_SERVER_ADDR, valuePropertyStunName); configurationService.setProperty(PROP_STUN_SERVER_PORT, valuePropertyStunPort); configurationService.setProperty(PROP_PREFERRED_NET_ADDR, valuePropertyNetworkAddress); InetAddress addr = networkAddressManagerService.getLocalHost(); assertTrue(addr instanceof Inet4Address); } public void testBadStun() throws Exception { initProperties(); //set the original properties //Integer valuePropertyPreferedIPVersion; String valuePropertyStunName="stun01.sipphone.com"; Integer valuePropertyStunPort=new Integer(3478); String valuePropertyNetworkAddress="192.169.1.1"; //String propertyNetworkInterface="" //valuePropertyPreferedIPVersion = new Integer(4); configurationService.setProperty(PROP_STUN_SERVER_ADDR, valuePropertyStunName); configurationService.setProperty(PROP_STUN_SERVER_PORT, valuePropertyStunPort); configurationService.setProperty(PROP_PREFERRED_NET_ADDR, valuePropertyNetworkAddress); InetAddress addr = networkAddressManagerService.getLocalHost(); assertTrue(isLocalInterfaceAddressIPv4(addr) || isLinkLocalIPv4Address(addr) || isRoutable(addr)); } */ /** * Set the configuration to IPv4 pref if the network is not behind a NAT * if not it does nothing * and watch if the result of "NetworkAddressManagerService.getlocalhost() * is a valid (public) IPv4 address */ /*public void testIPv4Stack() { if(nat==true) return; // set properties Boolean propertyIpV6Pref= new Boolean(false); Boolean propertyIpV4Stack = new Boolean(true); String propertieStunValue="stun01.sipphone.com"; Integer propertieStunPort=new Integer(3478); Boolean natBoolean = new Boolean(nat); try { configurationService.setProperty(propertyIpV4Stack, propertyIpV4Stack); configurationService.setProperty(propertyStunName,propertieStunValue ); configurationService.setProperty(propertyStunPort,propertieStunPort ); configurationService.setProperty(propertyV6,propertyIpV6Pref ); configurationService.setProperty(propertyNat, natBoolean); } catch (Exception e) {} try { // get the locahost grom NetworkAddressManager Service InetAddress serviceAdress = networkAddressManagerService.getLocalHost(); // test must crash if the localHost is an IPv6 Address if(serviceAdress instanceof Inet4Address) assertTrue(foundInetAddr(serviceAdress, propertyIpV6Pref.booleanValue())); else assertTrue(false); } catch (Exception e) {} }*/ /** * Set the configuration to IPv4 pref if the network is behind a nat * if not it does nothing * and watch if the result of "NetworkAddressManagerService.getlocalhost() * is a valid (public) IPv4 address */ /*public void testIPv4StackWithNat() { if(nat==false) return; // set properties Boolean propertyIpV6Pref= new Boolean(false); Boolean propertyIpV4Stack = new Boolean(true); String propertieStunValue="stun01.sipphone.com"; Integer propertieStunPort=new Integer(3478); Boolean natBoolean = new Boolean(nat); try { configurationService.setProperty(propertIpV4Stack, propertyIpV4Stack); configurationService.setProperty(propertyStunName,propertieStunValue ); configurationService.setProperty(propertyStunPort,propertieStunPort ); configurationService.setProperty(propertyV6,propertyIpV6Pref ); configurationService.setProperty(propertyNat, natBoolean); } catch (Exception e) {} try { // get the locahost grom NetworkAddressManager Service InetAddress serviceAdress = networkAddressManagerService.getLocalHost(); // test must crash if the localHost is an IPv6 Address if(serviceAdress instanceof Inet4Address) assertTrue(!isLinkLocalIPv4Address(serviceAdress)); else assertTrue(false); } catch (Exception e) {} }*/ /** * Set the configuration to IPv6 pref * and watch if the result of "NetworkAddressManagerService.getlocalhost() * is a valid IPv6 address */ /*public void testIPv6() { if(nat==true) return; // set properties Boolean propertyIpV6Pref= new Boolean(true); Boolean propertyIpV4Stack = new Boolean(false); String propertieStunValue="stun01.sipphone.com"; Integer propertieStunPort=new Integer(3478); Boolean natBoolean = new Boolean(nat); try { configurationService.setProperty(propertIpV4Stack, propertyIpV4Stack); configurationService.setProperty(propertyStunName,propertieStunValue ); configurationService.setProperty(propertyStunPort,propertieStunPort ); configurationService.setProperty(propertyV6,propertyIpV6Pref ); configurationService.setProperty(propertyNat, natBoolean); } catch (Exception e) {} try { // get localhost address from the NetworkAddressManager bundle InetAddress serviceAdress = networkAddressManagerService.getLocalHost(); if(serviceAdress instanceof Inet6Address) assertTrue(foundInetAddr(serviceAdress, propertyIpV6Pref.booleanValue())); else assertTrue(false); } catch (Exception e) {} }*/ /** * Set the configuration to IPv6 pref * and watch if the result of "NetworkAddressManagerService.getlocalhost() * is a valid IPv6 address */ /*public void testIPv6Nat() { if(nat==false) return; // set properties Boolean propertyIpV6Pref= new Boolean(true); Boolean propertyIpV4Stack = new Boolean(false); String propertieStunValue="stun01.sipphone.com"; Integer propertieStunPort=new Integer(3478); Boolean natBoolean = new Boolean(nat); try { configurationService.setProperty(propertIpV4Stack, propertyIpV4Stack); configurationService.setProperty(propertyStunName,propertieStunValue ); configurationService.setProperty(propertyStunPort,propertieStunPort ); configurationService.setProperty(propertyV6,propertyIpV6Pref ); configurationService.setProperty(propertyNat, natBoolean); } catch (Exception e) {} try { // get localhost address from the NetworkAddressManager bundle InetAddress serviceAdress = networkAddressManagerService.getLocalHost(); if(serviceAdress instanceof Inet6Address) assertTrue( isRoutable(serviceAdress)); else assertTrue(false); } catch (Exception e) {} }*/ /** * verify if the address returned by the service is valid by listing local * interfaces and compare them to the address retruned * * @param serviceAdress : address to check * @param ipv6version : if true verifie if this address is an ipv6 belong * to the local interface. if false, et do the same thing for * IPv4 Addresses * @return : true if it is an ipv4 address and if this addres belong to the * local interface */ /*boolean foundInetAddr(InetAddress serviceAdress, boolean ipv6version) { try { Enumeration intfs = NetworkInterface.getNetworkInterfaces(); while (intfs.hasMoreElements()) { NetworkInterface intf = (NetworkInterface) intfs.nextElement(); Enumeration addrs = intf.getInetAddresses(); while (addrs.hasMoreElements()) { try { InetAddress addr = (InetAddress) addrs.nextElement(); if (!addr.isLoopbackAddress() && serviceAdress.equals(addr) && ((!ipv6version && addr.getClass().equals(Inet4Address.class) || (ipv6version && addr.getClass().equals(Inet6Address.class))))) return true; } catch (Exception e) { } } } } catch (Exception e) { e.printStackTrace(); } return false; }*/ /** * test the getPublicAddressFor methode, * but I don't know how test that * it is still TODO * */ /*public void testgetPublicAddressFor() { // set properties Boolean propertyIpV6Pref= new Boolean(true); Boolean propertyIpV4Stack = new Boolean(false); String propertieStunValue="stun01.sipphone.com"; Integer propertieStunPort=new Integer(3478); Boolean natBoolean = new Boolean(nat); try { configurationService.setProperty(propertIpV4Stack, propertyIpV4Stack); configurationService.setProperty(propertyStunName,propertieStunValue ); configurationService.setProperty(propertyStunPort,propertieStunPort ); configurationService.setProperty(propertyV6,propertyIpV6Pref ); configurationService.setProperty(propertyNat, natBoolean); } catch (Exception ex) {} InetAddress serviceAddress = (networkAddressManagerService. getPublicAddressFor(1024)).getAddress(); assertTrue(foundInetAddr(serviceAddress, propertyIpV6Pref.booleanValue())); propertyIpV4Stack = new Boolean(true); propertyIpV6Pref = new Boolean(false); try { configurationService.setProperty(propertIpV4Stack, propertyIpV4Stack); configurationService.setProperty(propertyV6,propertyIpV6Pref ); } catch (Exception e) {} serviceAddress = (networkAddressManagerService. getPublicAddressFor(1024)).getAddress(); assertTrue(foundInetAddr(serviceAddress, propertyIpV6Pref.booleanValue())); }*/ /** * Determines whether the address is an IPv4 link local address. IPv4 link * local addresses are those in the following networks: * * 10.0.0.0 to 10.255.255.255 * 172.16.0.0 to 172.31.255.255 * 192.168.0.0 to 192.168.255.255 * * @param add the address to inspect * @return true if add is a link local ipv4 address and false if not. */ private static boolean isLinkLocalIPv4Address(InetAddress add) { if(add instanceof Inet4Address) { byte address[] = add.getAddress(); if ( (address[0] & 0xFF) == 10) return true; if ( (address[0] & 0xFF) == 172 && (address[1] & 0xFF) >= 16 && address[1] <= 31) return true; if ( (address[0] & 0xFF) == 192 && (address[1] & 0xFF) == 168) return true; return false; } return false; } /** * Determines whether the address could be used in a VoIP session. Attention, * routable address as determined by this method are not only globally routable * addresses in the general sense of the term. Link local addresses such as * 192.168.x.x or fe80::xxxx are also considered usable. * @param address the address to test. * @return true if the address could be used in a VoIP session. */ private static boolean isRoutable(InetAddress address) { if(address instanceof Inet6Address) { return !address.isLoopbackAddress() && !address.isLinkLocalAddress(); } else { return (!address.isLoopbackAddress()) && (!isWindowsAutoConfiguredIPv4Address(address)); } } /** * Determines whether the address is the result of windows auto configuration. * (i.e. One that is in the 169.254.0.0 network) * @param add the address to inspect * @return true if the address is autoconfigured by windows, false otherwise. */ private static boolean isWindowsAutoConfiguredIPv4Address(InetAddress add) { return (add.getAddress()[0] & 0xFF) == 169 && (add.getAddress()[1] & 0xFF) == 254; } private void initProperties() { try { configurationService.setProperty( PROP_STUN_SERVER_ADDR , null); configurationService.setProperty( PROP_STUN_SERVER_PORT , null); configurationService.setProperty( PROP_PREFERRED_NET_IFACE, null); configurationService.setProperty( PROP_PREFERRED_NET_ADDR , null); configurationService.setProperty( PROP_STUN_SERVER_ADDR , null); } catch(Exception ex){} } }