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 c568bdb7a..13239546c 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/IceUdpTransportManager.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/IceUdpTransportManager.java @@ -88,22 +88,12 @@ private Agent createIceAgent() String password = JabberActivator .getProtocolProviderFactory().loadPassword(accID); - StunCandidateHarvester autoHarvester = null; + StunCandidateHarvester autoHarvester = namSer.discoverStunServer( + accID.getService(), + StringUtils.getUTF8Bytes(username), + StringUtils.getUTF8Bytes(password) ); - try - { - autoHarvester = namSer.discoverStunServer( accID.getService(), - username.getBytes("UTF-8"), - password.getBytes("UTF-8")); - - logger.info("Auto discovered harvester is " + autoHarvester); - } - catch(UnsupportedEncodingException exc) - { - //this shouldn't really happen because UTF-8 should always be - //supported. anyways, let's just act as if there were no STUN/ - //TURN record for our domain and leave the harvester to null - } + logger.info("Auto discovered harvester is " + autoHarvester); if (autoHarvester != null) agent.addCandidateHarvester(autoHarvester); diff --git a/src/net/java/sip/communicator/impl/protocol/sip/AddressResolverImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/AddressResolverImpl.java index f120864d3..62435fee4 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/AddressResolverImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/AddressResolverImpl.java @@ -23,13 +23,26 @@ * * @author Damian Minkov * @author Alan Kelly + * @author Emil Ivov */ public class AddressResolverImpl implements AddressResolver { + /** + * Our class logger + */ private static final Logger logger = Logger.getLogger(AddressResolverImpl.class); + /** + * Implements the actual resolving. This is where we do the DNS queries. + * + * @param inputAddress the unresolved Hop that we'd need to find + * an address for. + * + * @return the newly created Hop containing the resolved + * destination. + */ public Hop resolveAddress(Hop inputAddress) { try @@ -47,12 +60,12 @@ public Hop resolveAddress(Hop inputAddress) { byte[] addr = null; - addr = IPAddressUtil.textToNumericFormatV4(hostAddress); + addr = NetworkUtils.strToIPv4(hostAddress); // not an IPv4, try IPv6 if (addr == null) { - addr = IPAddressUtil.textToNumericFormatV6(hostAddress); + addr = NetworkUtils.strToIPv6(hostAddress); } host = new InetSocketAddress( diff --git a/src/net/java/sip/communicator/launcher/BrowserLauncher.java b/src/net/java/sip/communicator/launcher/BrowserLauncher.java index b10a54f2e..4d231d2fb 100644 --- a/src/net/java/sip/communicator/launcher/BrowserLauncher.java +++ b/src/net/java/sip/communicator/launcher/BrowserLauncher.java @@ -13,28 +13,46 @@ /** * A simple implementation of the BrowserLauncherService. Checks the operating * system and launches the appropriate browser. - * + * * @author Yana Stamcheva */ public class BrowserLauncher { + /** + * Creates a LaunchBrowser thread for the specified url. + * + * @param url the url we'd like to launch a browser for. + */ public void openURL(String url) { new LaunchBrowser(url).start(); } - + /** * Launch browser in a separate thread. */ private static class LaunchBrowser extends Thread { + /** + * The URL we'd be launching a browser for. + */ private final String url; - + + /** + * Creates a new instance. + * + * @param url the url we'd like to launch a browser for. + */ public LaunchBrowser(String url) { this.url = url; } - + + /** + * On mac, asks FileManager to open the the url, on Windows uses + * FileProtocolHandler to do so, on Linux, loops through a list of + * known browsers until we find one that seems to work. + */ public void run() { try @@ -51,11 +69,11 @@ else if (OSUtils.IS_WINDOWS) else { /* Linux and other Unix systems */ - String[] browsers = {"firefox", "iceweasel", "opera", "konqueror", - "epiphany", "mozilla", "netscape" }; - + String[] browsers = {"firefox", "iceweasel", "opera", + "konqueror", "epiphany", "mozilla", "netscape" }; + String browser = null; - + for (int i = 0; i < browsers.length && browser == null; i ++) { if (Runtime.getRuntime().exec( diff --git a/src/net/java/sip/communicator/launcher/SIPCommunicator.java b/src/net/java/sip/communicator/launcher/SIPCommunicator.java index 3a9c05bb6..d5e79834e 100644 --- a/src/net/java/sip/communicator/launcher/SIPCommunicator.java +++ b/src/net/java/sip/communicator/launcher/SIPCommunicator.java @@ -23,16 +23,24 @@ */ public class SIPCommunicator { + /** + * The name of the property that stores our home dir location. + */ public static final String PNAME_SC_HOME_DIR_LOCATION = "net.java.sip.communicator.SC_HOME_DIR_LOCATION"; + /** + * The name of the property that stores our home dir name. + */ public static final String PNAME_SC_HOME_DIR_NAME = "net.java.sip.communicator.SC_HOME_DIR_NAME"; /** * Starts the SIP Communicator. * - * @param args + * @param args command line args if any + * + * @throws Exception whenever it makes sense. */ public static void main(String[] args) throws Exception @@ -48,7 +56,7 @@ public static void main(String[] args) */ setScHomeDir(osName); - if (version.startsWith("1.4") || vmVendor.startsWith("Gnu") || + if (version.startsWith("1.4") || vmVendor.startsWith("Gnu") || vmVendor.startsWith("Free")) { String os = ""; diff --git a/src/net/java/sip/communicator/plugin/jabberaccregwizz/IceConfigPanel.java b/src/net/java/sip/communicator/plugin/jabberaccregwizz/IceConfigPanel.java index f4d810edf..81b8a870d 100644 --- a/src/net/java/sip/communicator/plugin/jabberaccregwizz/IceConfigPanel.java +++ b/src/net/java/sip/communicator/plugin/jabberaccregwizz/IceConfigPanel.java @@ -115,9 +115,9 @@ public void actionPerformed(ActionEvent e) stunServer.getAddress(), stunServer.getPort(), stunServer.isTurnSupported(), - StunServerDescriptor.getUTF8String( + StringUtils.getUTF8String( stunServer.getUsername()), - StunServerDescriptor.getUTF8String( + StringUtils.getUTF8String( stunServer.getPassword())); dialog.setVisible(true); diff --git a/src/net/java/sip/communicator/service/protocol/StunServerDescriptor.java b/src/net/java/sip/communicator/service/protocol/StunServerDescriptor.java index b0177c24e..7cef900f5 100644 --- a/src/net/java/sip/communicator/service/protocol/StunServerDescriptor.java +++ b/src/net/java/sip/communicator/service/protocol/StunServerDescriptor.java @@ -8,6 +8,8 @@ import java.io.*; import java.util.*; + +import net.java.sip.communicator.util.*; import static net.java.sip.communicator.service.protocol.ProtocolProviderFactory.*; /** @@ -73,8 +75,8 @@ public StunServerDescriptor( String address, this.address = address; this.port = port; this.isTurnSupported = supportTurn; - this.username = getUTF8Bytes( username ); - this.password = getUTF8Bytes( password ); + this.username = StringUtils.getUTF8Bytes( username ); + this.password = StringUtils.getUTF8Bytes( password ); } /** @@ -156,7 +158,7 @@ public byte[] getUsername() */ public void setUsername(String username) { - this.username = getUTF8Bytes(username); + this.username = StringUtils.getUTF8Bytes(username); } /** @@ -176,7 +178,7 @@ public byte[] getPassword() */ public void setPassword(String password) { - this.password = getUTF8Bytes(password); + this.password = StringUtils.getUTF8Bytes(password); } /** @@ -201,7 +203,8 @@ public void storeDescriptor(Map props, String namePrefix) props.put(namePrefix + STUN_PORT, Integer.toString( getPort() )); if (getUsername() != null && getUsername().length > 0) - props.put(namePrefix + STUN_USERNAME, getUTF8String(getUsername())); + props.put(namePrefix + STUN_USERNAME, + StringUtils.getUTF8String(getUsername())); if (getPassword() != null && getPassword().length > 0) props.put(namePrefix + STUN_PASSWORD, new String(getPassword())); @@ -266,51 +269,6 @@ public static StunServerDescriptor loadDescriptor( return stunServer; } - /** - * Returns the UTF8 bytes for string and handles the unlikely case - * where UTF-8 is not supported. - * - * @param string the String whose bytes we'd like to obtain. - * - * @return string's bytes. - */ - public static byte[] getUTF8Bytes(String string) - { - try - { - return string.getBytes("UTF-8"); - } - catch(UnsupportedEncodingException exc) - { - // shouldn't happen. UTF-8 is always supported, anyways ... if - //this happens, we'll cheat - return string.getBytes(); - } - } - - /** - * Converts string into an UTF8 String and handles the - * unlikely case where UTF-8 is not supported. - * - * @param bytes the byte array that we'd like to convert into a - * String. - * - * @return the UTF-8 String. - */ - public static String getUTF8String(byte[] bytes) - { - try - { - return new String(bytes, "UTF-8"); - } - catch(UnsupportedEncodingException exc) - { - // shouldn't happen. UTF-8 is always supported, anyways ... if - //this happens, we'll cheat - return new String(bytes); - } - } - /** * Returns a String representation of this descriptor * diff --git a/src/net/java/sip/communicator/util/FileHandler.java b/src/net/java/sip/communicator/util/FileHandler.java index 589f2e49d..c686ea115 100644 --- a/src/net/java/sip/communicator/util/FileHandler.java +++ b/src/net/java/sip/communicator/util/FileHandler.java @@ -42,9 +42,13 @@ public class FileHandler * %t, %h, %g, %u. * Also adds the special component : * %s sip-communicator's home directory, typically - - * ${net.java.sip.communicator.SC_HOME_DIR_LOCATION}/${net.java.sip.communicator.SC_HOME_DIR_NAME}. + * ${net.java.sip.communicator.SC_HOME_DIR_LOCATION}/ + * ${net.java.sip.communicator.SC_HOME_DIR_NAME}. + *

+ * The field is public so that our Logger could reset it if + * necessary. */ - private static String pattern = null; + public static String pattern = null; /** * Initialize a FileHandler to write to a set of files. When @@ -65,7 +69,7 @@ public class FileHandler * @param count the number of files to use * @exception IOException if there are IO problems opening the files. * @exception SecurityException if a security manager exists and if - * the caller does not have LoggingPermission("control"). + * the caller does not have LoggingPermission("control"). * @exception IllegalArgumentException if limit < 0, or count < 1. * @exception IllegalArgumentException if pattern is an empty string */ @@ -82,7 +86,7 @@ public FileHandler(String pattern, int limit, int count) *

* @exception IOException if there are IO problems opening the files. * @exception SecurityException if a security manager exists and if - * the caller does not have LoggingPermission("control")). + * the caller does not have LoggingPermission("control")). * @exception NullPointerException if pattern property is an empty String. */ public FileHandler() @@ -101,15 +105,17 @@ private static int getLimit() { if(limit == -1) { - String limitStr = - LogManager.getLogManager().getProperty(FileHandler.class.getName() + ".limit"); + String limitStr = LogManager.getLogManager().getProperty( + FileHandler.class.getName() + ".limit"); // default value limit = 0; - try { + try + { limit = Integer.parseInt(limitStr); - } catch (Exception ex) {} + } + catch (Exception ex) {} } return limit; @@ -129,10 +135,10 @@ private static String getPattern() LogManager.getLogManager().getProperty( FileHandler.class.getName() + ".pattern"); - String homeLocation = - System.getProperty("net.java.sip.communicator.SC_HOME_DIR_LOCATION"); - String dirName = - System.getProperty("net.java.sip.communicator.SC_HOME_DIR_NAME"); + String homeLocation = System.getProperty( + "net.java.sip.communicator.SC_HOME_DIR_LOCATION"); + String dirName = System.getProperty( + "net.java.sip.communicator.SC_HOME_DIR_NAME"); if(homeLocation != null && dirName != null) { @@ -164,15 +170,17 @@ private static int getCount() { if(count == -1) { - String countStr = - LogManager.getLogManager().getProperty(FileHandler.class.getName() + ".count"); + String countStr = LogManager.getLogManager().getProperty( + FileHandler.class.getName() + ".count"); // default value count = 1; - try { + try + { count = Integer.parseInt(countStr); - } catch (Exception ex) {} + } + catch (Exception ex) {} } return count; @@ -180,7 +188,8 @@ private static int getCount() /** * Creates the directory in the pattern. - * @param pattern + * + * @param pattern the directory we'd like to check. */ private static void checkDestinationDirectory(String pattern) { @@ -191,8 +200,10 @@ private static void checkDestinationDirectory(String pattern) if(ix != -1) { String dirName = pattern.substring(0, ix); - dirName = dirName.replaceAll("%h", System.getProperty("user.home")); - dirName = dirName.replaceAll("%t", System.getProperty("java.io.tmpdir")); + dirName = dirName.replaceAll( + "%h", System.getProperty("user.home")); + dirName = dirName.replaceAll( + "%t", System.getProperty("java.io.tmpdir")); new File(dirName).mkdirs(); } diff --git a/src/net/java/sip/communicator/util/IPAddressUtil.java b/src/net/java/sip/communicator/util/IPAddressUtil.java deleted file mode 100644 index e4fedeaee..000000000 --- a/src/net/java/sip/communicator/util/IPAddressUtil.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.util; - -/** - * Contains utility methods for work with IPv4 and IPv6 addresses. - *

- * TODO Rewrite to not depend on sun.net.util.IPAddressUtil. - *

- * - * @author Alan Kelly - * @author Lubomir Marinov - */ -public class IPAddressUtil - extends sun.net.util.IPAddressUtil -{ -} diff --git a/src/net/java/sip/communicator/util/Logger.java b/src/net/java/sip/communicator/util/Logger.java index 9baf45b01..d04a8f810 100644 --- a/src/net/java/sip/communicator/util/Logger.java +++ b/src/net/java/sip/communicator/util/Logger.java @@ -6,6 +6,7 @@ */ package net.java.sip.communicator.util; +import java.io.*; import java.util.logging.*; /** @@ -15,8 +16,11 @@ */ public class Logger { + /** + * The java.util.Logger that would actually be doing the logging. + */ private final java.util.logging.Logger loggerDelegate; - + /** * Base constructor * @@ -353,4 +357,25 @@ private void setLevel(java.util.logging.Level level) loggerDelegate.setLevel(level); } + + /** + * Reinitialize the logging properties and reread the logging configuration. + *

+ * The same rules are used for locating the configuration properties + * as are used at startup. So if the properties containing the log dir + * locations have changed, we would read the new configuration. + */ + public void reset() + { + try + { + FileHandler.pattern = null; + LogManager.getLogManager().reset(); + LogManager.getLogManager().readConfiguration(); + } + catch (Exception e) + { + loggerDelegate.log(Level.INFO, "Failed to reinit logger.", e); + } + } } diff --git a/src/net/java/sip/communicator/util/NetworkUtils.java b/src/net/java/sip/communicator/util/NetworkUtils.java index 36fbb66da..5e3261e63 100644 --- a/src/net/java/sip/communicator/util/NetworkUtils.java +++ b/src/net/java/sip/communicator/util/NetworkUtils.java @@ -8,6 +8,7 @@ import java.net.*; import java.util.*; + import org.xbill.DNS.*; import java.text.*; @@ -43,12 +44,28 @@ public class NetworkUtils public static final String IN_ADDR_ANY = determineAnyAddress(); /** - * The maximum int value that could correspond to a port nubmer. + * The length of IPv6 addresses. + */ + private final static int IN6_ADDR_SIZE = 16; + + /** + * The size of the tokens in a String representation of IPv6 + * addresses. + */ + private final static int IN6_ADDR_TOKEN_SIZE = 2; + + /** + * The length of IPv4 addresses. + */ + private final static int IN4_ADDR_SIZE = 4; + + /** + * The maximum int value that could correspond to a port number. */ public static final int MAX_PORT_NUMBER = 65535; /** - * The minimum int value that could correspond to a port nubmer bindable + * The minimum int value that could correspond to a port number bindable * by the SIP Communicator. */ public static final int MIN_PORT_NUMBER = 1024; @@ -161,7 +178,7 @@ public static int getRandomPortNumber(int min, int max, boolean pair) */ public static boolean isIPv4Address(String address) { - return IPAddressUtil.isIPv4LiteralAddress(address); + return strToIPv4(address) != null; } /** @@ -174,7 +191,7 @@ public static boolean isIPv4Address(String address) */ public static boolean isIPv6Address(String address) { - return IPAddressUtil.isIPv6LiteralAddress(address); + return strToIPv6(address) != null; } /** @@ -195,7 +212,7 @@ public static boolean isValidIPAddress(String address) boolean ipv6Expected = false; if (address.charAt(0) == '[') { - // This is supposed to be an IPv6 litteral + // This is supposed to be an IPv6 literal if (address.length() > 2 && address.charAt(address.length() - 1) == ']') { @@ -216,11 +233,11 @@ public static boolean isValidIPAddress(String address) byte[] addr = null; // see if it is IPv4 address - addr = IPAddressUtil.textToNumericFormatV4(address); + addr = strToIPv4(address); // if not, see if it is IPv6 address if (addr == null) { - addr = IPAddressUtil.textToNumericFormatV6(address); + addr = strToIPv6(address); } // if IPv4 is found when IPv6 is expected else if (ipv6Expected) @@ -239,6 +256,256 @@ else if (ipv6Expected) return false; } + /** + * Creates a byte array containing the specified ipv4AddStr. + * + * @param ipv4AddrStr a String containing an IPv4 address. + * + * @return a byte array containing the four bytes of the address represented + * by ipv4AddrStr or null if ipv4AddrStr does not contain + * a valid IPv4 address string. + */ + public static byte[] strToIPv4(String ipv4AddrStr) + { + if (ipv4AddrStr.length() == 0) + return null; + + byte[] address = new byte[IN4_ADDR_SIZE]; + String[] tokens = ipv4AddrStr.split("\\.", -1); + long currentTkn; + try + { + switch(tokens.length) + { + case 1: + //If the address was specified as a single String we can + //directly copy it into the byte array. + currentTkn = Long.parseLong(tokens[0]); + if (currentTkn < 0 || currentTkn > 0xffffffffL) + return null; + address[0] = (byte) ((currentTkn >> 24) & 0xff); + address[1] = (byte) (((currentTkn & 0xffffff) >> 16) & 0xff); + address[2] = (byte) (((currentTkn & 0xffff) >> 8) & 0xff); + address[3] = (byte) (currentTkn & 0xff); + break; + case 2: + // If the address was passed in two parts (e.g. when dealing + // with a Class A address representation), we place the + // first one in the leftmost byte and the rest in the three + // remaining bytes of the address array. + currentTkn = Integer.parseInt(tokens[0]); + + if (currentTkn < 0 || currentTkn > 0xff) + return null; + + address[0] = (byte) (currentTkn & 0xff); + currentTkn = Integer.parseInt(tokens[1]); + + if (currentTkn < 0 || currentTkn > 0xffffff) + return null; + + address[1] = (byte) ((currentTkn >> 16) & 0xff); + address[2] = (byte) (((currentTkn & 0xffff) >> 8) &0xff); + address[3] = (byte) (currentTkn & 0xff); + break; + case 3: + // If the address was passed in three parts (e.g. when + // dealing with a Class B address representation), we place + // the first two parts in the two leftmost bytes and the + // rest in the two remaining bytes of the address array. + for (int i = 0; i < 2; i++) + { + currentTkn = Integer.parseInt(tokens[i]); + + if (currentTkn < 0 || currentTkn > 0xff) + return null; + + address[i] = (byte) (currentTkn & 0xff); + } + + currentTkn = Integer.parseInt(tokens[2]); + + if (currentTkn < 0 || currentTkn > 0xffff) + return null; + + address[2] = (byte) ((currentTkn >> 8) & 0xff); + address[3] = (byte) (currentTkn & 0xff); + break; + case 4: + // And now for the most common - four part case. This time + // there's a byte for every part :). Yuppiee! :) + for (int i = 0; i < 4; i++) + { + currentTkn = Integer.parseInt(tokens[i]); + + if (currentTkn < 0 || currentTkn > 0xff) + return null; + + address[i] = (byte) (currentTkn & 0xff); + } + break; + default: + return null; + } + } + catch(NumberFormatException e) + { + return null; + } + + return address; + } + + /** + * Creates a byte array containing the specified ipv6AddStr. + * + * @param ipv6AddrStr a String containing an IPv6 address. + * + * @return a byte array containing the four bytes of the address represented + * by ipv6AddrStr or null if ipv6AddrStr does + * not contain a valid IPv6 address string. + */ + public static byte[] strToIPv6(String ipv6AddrStr) + { + // Bail out if the string is shorter than "::" + if (ipv6AddrStr.length() < 2) + return null; + + int colonIndex; + char currentChar; + boolean sawtDigit; + int currentTkn; + char[] addrBuff = ipv6AddrStr.toCharArray(); + byte[] dst = new byte[IN6_ADDR_SIZE]; + + int srcb_length = addrBuff.length; + int scopeID = ipv6AddrStr.indexOf ("%"); + + if (scopeID == srcb_length -1) + return null; + + if (scopeID != -1) + srcb_length = scopeID; + + colonIndex = -1; + int i = 0, j = 0; + // Starting : mean we need to have at least one more. + if (addrBuff[i] == ':') + if (addrBuff[++i] != ':') + return null; + + int curtok = i; + sawtDigit = false; + currentTkn = 0; + while (i < srcb_length) + { + currentChar = addrBuff[i++]; + int chval = Character.digit(currentChar, 16); + if (chval != -1) + { + currentTkn <<= 4; + currentTkn |= chval; + if (currentTkn > 0xffff) + return null; + sawtDigit = true; + continue; + } + + if (currentChar == ':') + { + curtok = i; + + if (!sawtDigit) + { + if (colonIndex != -1) + return null; + colonIndex = j; + continue; + } + else if (i == srcb_length) + { + return null; + } + + if (j + IN6_ADDR_TOKEN_SIZE > IN6_ADDR_SIZE) + return null; + + dst[j++] = (byte) ((currentTkn >> 8) & 0xff); + dst[j++] = (byte) (currentTkn & 0xff); + sawtDigit = false; + currentTkn = 0; + continue; + } + + if (currentChar == '.' && ((j + IN4_ADDR_SIZE) <= IN6_ADDR_SIZE)) + { + String ia4 = ipv6AddrStr.substring(curtok, srcb_length); + // check this IPv4 address has 3 dots, ie. A.B.C.D + int dot_count = 0, index=0; + while ((index = ia4.indexOf ('.', index)) != -1) + { + dot_count ++; + index ++; + } + + if (dot_count != 3) + return null; + + byte[] v4addr = strToIPv4(ia4); + if (v4addr == null) + return null; + + for (int k = 0; k < IN4_ADDR_SIZE; k++) + { + dst[j++] = v4addr[k]; + } + + sawtDigit = false; + break; /* '\0' was seen by inet_pton4(). */ + } + return null; + } + + if (sawtDigit) + { + if (j + IN6_ADDR_TOKEN_SIZE > IN6_ADDR_SIZE) + return null; + + dst[j++] = (byte) ((currentTkn >> 8) & 0xff); + dst[j++] = (byte) (currentTkn & 0xff); + } + + if (colonIndex != -1) + { + int n = j - colonIndex; + + if (j == IN6_ADDR_SIZE) + return null; + + for (i = 1; i <= n; i++) + { + dst[IN6_ADDR_SIZE - i] = dst[colonIndex + n - i]; + dst[colonIndex + n - i] = 0; + } + + j = IN6_ADDR_SIZE; + } + + if (j != IN6_ADDR_SIZE) + return null; + + byte[] newdst = mappedIPv4ToRealIPv4(dst); + + if (newdst != null) + { + return newdst; + } + else + { + return dst; + } + } + /** * Returns array of hosts from the SRV record of the specified domain. * The records are ordered against the SRV record priority @@ -419,12 +686,12 @@ public static InetAddress getInetAddress(String hostAddress) byte[] addr = null; // attempt parse as IPv4 address - addr = IPAddressUtil.textToNumericFormatV4(hostAddress); + addr = strToIPv4(hostAddress); // if not IPv4, parse as IPv6 address if (addr == null) { - addr = IPAddressUtil.textToNumericFormatV6(hostAddress); + addr = strToIPv6(hostAddress); } return InetAddress.getByAddress(hostAddress, addr); } @@ -562,6 +829,57 @@ private static String determineAnyAddress() public static boolean isValidPortNumber(int port) { return MIN_PORT_NUMBER < port && port < MAX_PORT_NUMBER; + } + /** + * Returns an IPv4 address matching the one mapped in the IPv6 + * addr. Both input and returned value are in network order. + * + * @param addr a String representing an IPv4-Mapped address in textual + * format + * + * @return a byte array numerically representing the IPv4 address + */ + public static byte[] mappedIPv4ToRealIPv4(byte[] addr) + { + if (isMappedIPv4Addr(addr)) + { + byte[] newAddr = new byte[IN4_ADDR_SIZE]; + System.arraycopy(addr, 12, newAddr, 0, IN6_ADDR_SIZE); + return newAddr; + } + + return null; + } + + /** + * Utility method to check if the specified address is an IPv4 + * mapped IPv6 address. + * + * @param address the address that we'd like to determine as an IPv4 mapped + * one or not. + * + * @return true if address is an IPv4 mapped IPv6 address and + * false otherwise. + */ + private static boolean isMappedIPv4Addr(byte[] address) + { + if (address.length < IN6_ADDR_SIZE) + { + return false; + } + + if ((address[0] == 0x00) && (address[1] == 0x00) + && (address[2] == 0x00) && (address[3] == 0x00) + && (address[4] == 0x00) && (address[5] == 0x00) + && (address[6] == 0x00) && (address[7] == 0x00) + && (address[8] == 0x00) && (address[9] == 0x00) + && (address[10] == (byte)0xff) + && (address[11] == (byte)0xff)) + { + return true; + } + + return false; } } diff --git a/src/net/java/sip/communicator/util/StringUtils.java b/src/net/java/sip/communicator/util/StringUtils.java index d621b2aaf..e72a41dfc 100644 --- a/src/net/java/sip/communicator/util/StringUtils.java +++ b/src/net/java/sip/communicator/util/StringUtils.java @@ -12,6 +12,7 @@ * Utility class that helps to work with String class. * * @author Grigorii Balutsel + * @author Emil Ivov */ public final class StringUtils { @@ -28,7 +29,7 @@ private StringUtils() * with spaces between the words). * * @param camelCase a camel-case (or Pascal-case) formatted String - * from which a human-readable String is to be constructed + * from which a human-readable String is to be constructed * @return a String which represents the conversion of the specified * camel-case formatted String to a more human-readable form */ @@ -64,10 +65,10 @@ public static String convertCamelCaseToDisplayString(String camelCase) } /** - * Indicates whether string is null or empty. + * Indicates whether string is null or empty. * * @param s the string to analyze. - * @return true if string is null or empty. + * @return true if string is null or empty. */ public static boolean isNullOrEmpty(String s) { @@ -75,11 +76,11 @@ public static boolean isNullOrEmpty(String s) } /** - * Indicates whether string is null or empty. + * Indicates whether string is null or empty. * * @param s the string to analyze. * @param trim indicates whether to trim the string. - * @return true if string is null or empty. + * @return true if string is null or empty. */ public static boolean isNullOrEmpty(String s, boolean trim) { @@ -129,4 +130,49 @@ public static InputStream fromString(String string, String encoding) byte[] bytes = string.getBytes(encoding); return new ByteArrayInputStream(bytes); } + + /** + * Returns the UTF8 bytes for string and handles the unlikely case + * where UTF-8 is not supported. + * + * @param string the String whose bytes we'd like to obtain. + * + * @return string's bytes. + */ + public static byte[] getUTF8Bytes(String string) + { + try + { + return string.getBytes("UTF-8"); + } + catch(UnsupportedEncodingException exc) + { + // shouldn't happen. UTF-8 is always supported, anyways ... if + //this happens, we'll cheat + return string.getBytes(); + } + } + + /** + * Converts string into an UTF8 String and handles the + * unlikely case where UTF-8 is not supported. + * + * @param bytes the byte array that we'd like to convert into a + * String. + * + * @return the UTF-8 String. + */ + public static String getUTF8String(byte[] bytes) + { + try + { + return new String(bytes, "UTF-8"); + } + catch(UnsupportedEncodingException exc) + { + // shouldn't happen. UTF-8 is always supported, anyways ... if + //this happens, we'll cheat + return new String(bytes); + } + } } diff --git a/src/net/java/sip/communicator/util/launchutils/LaunchArgHandler.java b/src/net/java/sip/communicator/util/launchutils/LaunchArgHandler.java index 1de969ba1..8a00969a0 100644 --- a/src/net/java/sip/communicator/util/launchutils/LaunchArgHandler.java +++ b/src/net/java/sip/communicator/util/launchutils/LaunchArgHandler.java @@ -21,6 +21,9 @@ */ public class LaunchArgHandler { + /** + * Our class logger. + */ private static final net.java.sip.communicator.util.Logger logger = net.java.sip.communicator.util.Logger.getLogger(LaunchArgHandler.class); @@ -120,6 +123,9 @@ public class LaunchArgHandler */ private static LaunchArgHandler argHandler = null; + /** + * The properties where we load version info from our update location. + */ private Properties versionProperties = new Properties(); /** @@ -293,7 +299,7 @@ private void handleIPv4Enforcement() /** * Passes uriArg to our uri manager for handling. * - * @param arg the uri that we'd like to pass to + * @param uri the uri that we'd like to pass to */ private void handleUri(String uri) { @@ -305,7 +311,7 @@ private void handleUri(String uri) /** * Instructs SIP Communicator to print logging messages to the console. * - * @param the debug arg which we are not really using in this method. + * @param arg the debug arg which we are not really using in this method. */ private void handleDebugArg(String arg) { @@ -338,8 +344,9 @@ private void handleDebugArg(String arg) } /** - * Instructs SIP Communicator to allow for more than a single running - * instance. + * Instructs SIP Communicator change the location of its home dir. + * + * @param configArg the arg containing the location of the new dir. * * @return either ACTION_ERROR or ACTION_CONTINUE depending on whether or * not parsing the option went fine. @@ -366,6 +373,10 @@ private int handleConfigArg(String configArg) System.setProperty(PNAME_SC_HOME_DIR_LOCATION, configDir.getParent()); System.setProperty(PNAME_SC_HOME_DIR_NAME, configDir.getName()); + //we instantiated our class logger before we had a chance to change + //the dir so we need to reset it now. + logger.reset(); + return ACTION_CONTINUE; } @@ -426,6 +437,8 @@ private String getApplicationName() } /** * Prints an error message and then prints the help message. + * + * @param arg the unknown argument we need to print */ public void handleUnknownArg(String arg) {