/** * The method queries a Stun server for a binding for the port and address that <tt>sock</tt> is * bound on. * * @param sock the socket whose port and address we'dlike to resolve (the stun message gets sent * trhough that socket) * @return StunAddress the address returned by the stun server or null if an error occurred or no * address was returned * @throws IOException if an error occurs while stun4j is using sockets. * @throws BindException if the port is already in use. */ private StunAddress queryStunServer(DatagramSocket sock) throws IOException, BindException { StunAddress mappedAddress = null; if (detector != null && useStun) { mappedAddress = detector.getMappingFor(sock); if (logger.isTraceEnabled()) { logger.trace( "For socket with address " + sock.getLocalAddress().getHostAddress() + " and port " + sock.getLocalPort() + " the stun server returned the " + "following mapping [" + mappedAddress + "]"); } } return mappedAddress; }
/** * Returns an InetAddress instance that represents the localhost, and that a socket can bind upon * or distribute to peers as a contact address. * * @param intendedDestination the destination that we'd like to use the localhost address with. * @return an InetAddress instance representing the local host, and that a socket can bind upon or * distribute to peers as a contact address. */ public synchronized InetAddress getLocalHost(InetAddress intendedDestination) { // no point in making sure that the localHostFinderSocket is initialized. // better let it through a NullPointerException. InetAddress localHost = null; localHostFinderSocket.connect(intendedDestination, this.RANDOM_ADDR_DISC_PORT); localHost = localHostFinderSocket.getLocalAddress(); localHostFinderSocket.disconnect(); // windows socket implementations return the any address so we need to // find something else here ... InetAddress.getLocalHost seems to work // better on windows so lets hope it'll do the trick. if (localHost.isAnyLocalAddress()) { try { // all that's inside the if is an ugly IPv6 hack // (good ol' IPv6 - always causing more problems than it solves.) if (intendedDestination instanceof Inet6Address) { // return the first globally routable ipv6 address we find // on the machine (and hope it's a good one) Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); while (interfaces.hasMoreElements()) { NetworkInterface iface = (NetworkInterface) interfaces.nextElement(); Enumeration addresses = iface.getInetAddresses(); while (addresses.hasMoreElements()) { InetAddress address = (InetAddress) addresses.nextElement(); if (address instanceof Inet6Address) { if (!address.isAnyLocalAddress() && !address.isLinkLocalAddress() && !address.isSiteLocalAddress() && !address.isLoopbackAddress()) { return address; } } } } } else localHost = InetAddress.getLocalHost(); /** @todo test on windows for ipv6 cases */ } catch (Exception ex) { // sigh ... ok return 0.0.0.0 logger.warn("Failed to get localhost ", ex); } } return localHost; }