mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-18 18:42:46 +00:00
Add support for discovering IPv6 addresses with mDNS
This commit is contained in:
parent
68040394fb
commit
d00824d49c
@ -14,6 +14,7 @@ public class ComputerDetails {
|
||||
public String localAddress;
|
||||
public String remoteAddress;
|
||||
public String manualAddress;
|
||||
public String ipv6Address;
|
||||
public String macAddress;
|
||||
public X509Certificate serverCert;
|
||||
|
||||
@ -50,6 +51,9 @@ public class ComputerDetails {
|
||||
if (details.manualAddress != null) {
|
||||
this.manualAddress = details.manualAddress;
|
||||
}
|
||||
if (details.ipv6Address != null) {
|
||||
this.ipv6Address = details.ipv6Address;
|
||||
}
|
||||
if (details.macAddress != null && !details.macAddress.equals("00:00:00:00:00:00")) {
|
||||
this.macAddress = details.macAddress;
|
||||
}
|
||||
@ -70,6 +74,7 @@ public class ComputerDetails {
|
||||
str.append("UUID: ").append(uuid).append("\n");
|
||||
str.append("Local Address: ").append(localAddress).append("\n");
|
||||
str.append("Remote Address: ").append(remoteAddress).append("\n");
|
||||
str.append("IPv6 Address: ").append(ipv6Address).append("\n");
|
||||
str.append("Manual Address: ").append(manualAddress).append("\n");
|
||||
str.append("MAC Address: ").append(macAddress).append("\n");
|
||||
str.append("Pair State: ").append(pairState).append("\n");
|
||||
|
@ -1,22 +1,29 @@
|
||||
package com.limelight.nvstream.mdns;
|
||||
|
||||
import java.net.Inet4Address;
|
||||
import java.net.Inet6Address;
|
||||
|
||||
public class MdnsComputer {
|
||||
private Inet4Address ipAddr;
|
||||
private Inet4Address v4Addr;
|
||||
private Inet6Address v6Addr;
|
||||
private String name;
|
||||
|
||||
public MdnsComputer(String name, Inet4Address addr) {
|
||||
public MdnsComputer(String name, Inet4Address v4Addr, Inet6Address v6Addr) {
|
||||
this.name = name;
|
||||
this.ipAddr = addr;
|
||||
this.v4Addr = v4Addr;
|
||||
this.v6Addr = v6Addr;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Inet4Address getAddress() {
|
||||
return ipAddr;
|
||||
public Inet4Address getAddressV4() {
|
||||
return v4Addr;
|
||||
}
|
||||
|
||||
public Inet6Address getAddressV6() {
|
||||
return v6Addr;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -28,10 +35,24 @@ public class MdnsComputer {
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof MdnsComputer) {
|
||||
MdnsComputer other = (MdnsComputer)o;
|
||||
if (other.ipAddr.equals(ipAddr) &&
|
||||
other.name.equals(name)) {
|
||||
return true;
|
||||
|
||||
if (!other.name.equals(name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((other.v4Addr != null && v4Addr == null) ||
|
||||
(other.v4Addr == null && v4Addr != null) ||
|
||||
(other.v4Addr != null && !other.v4Addr.equals(v4Addr))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((other.v6Addr != null && v6Addr == null) ||
|
||||
(other.v6Addr == null && v6Addr != null) ||
|
||||
(other.v6Addr != null && !other.v6Addr.equals(v6Addr))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -39,6 +60,6 @@ public class MdnsComputer {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "["+name+" - "+ipAddr+"]";
|
||||
return "["+name+" - "+v4Addr+" - "+v6Addr+"]";
|
||||
}
|
||||
}
|
||||
|
@ -87,7 +87,6 @@ public class MdnsDiscoveryAgent implements ServiceListener {
|
||||
public boolean useInetAddress(NetworkInterface networkInterface, InetAddress interfaceAddress) {
|
||||
// This is an copy of jmDNS's implementation, except we omit the multicast check, since
|
||||
// it seems at least some devices lie about interfaces not supporting multicast when they really do.
|
||||
// We also will skip IPv6 addresses since GeForce Experience doesn't listen on IPv6 ports.
|
||||
try {
|
||||
if (!networkInterface.isUp()) {
|
||||
return false;
|
||||
@ -99,10 +98,6 @@ public class MdnsDiscoveryAgent implements ServiceListener {
|
||||
}
|
||||
*/
|
||||
|
||||
if (interfaceAddress instanceof Inet6Address) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (networkInterface.isLoopback()) {
|
||||
return false;
|
||||
}
|
||||
@ -165,16 +160,84 @@ public class MdnsDiscoveryAgent implements ServiceListener {
|
||||
}
|
||||
}
|
||||
|
||||
private Inet6Address getBestIpv6Address(Inet6Address[] addresses) {
|
||||
// First try to find a link local address, so we can match the interface identifier
|
||||
// with a global address (this will work for SLAAC but not DHCPv6).
|
||||
Inet6Address linkLocalAddr = null;
|
||||
for (Inet6Address addr : addresses) {
|
||||
if (addr.isLinkLocalAddress()) {
|
||||
LimeLog.info("Found link-local address: "+addr.getHostAddress());
|
||||
linkLocalAddr = addr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// We will try once to match a SLAAC interface suffix, then
|
||||
// pick the first matching address
|
||||
for (int tries = 0; tries < 2; tries++) {
|
||||
// We assume the addresses are already sorted in descending order
|
||||
// of preference from Bonjour.
|
||||
for (Inet6Address addr : addresses) {
|
||||
if (addr.isLinkLocalAddress() || addr.isSiteLocalAddress() || addr.isLoopbackAddress()) {
|
||||
// Link-local, site-local, and loopback aren't global
|
||||
LimeLog.info("Ignoring non-global address: "+addr.getHostAddress());
|
||||
continue;
|
||||
}
|
||||
|
||||
byte[] addrBytes = addr.getAddress();
|
||||
|
||||
// 2002::/16
|
||||
if (addrBytes[0] == 0x20 && addrBytes[1] == 0x02) {
|
||||
// 6to4 has horrible performance
|
||||
LimeLog.info("Ignoring 6to4 address: "+addr.getHostAddress());
|
||||
continue;
|
||||
}
|
||||
// 2001::/32
|
||||
else if (addrBytes[0] == 0x20 && addrBytes[1] == 0x01 && addrBytes[2] == 0x00 && addrBytes[3] == 0x00) {
|
||||
// Teredo also has horrible performance
|
||||
LimeLog.info("Ignoring Teredo address: "+addr.getHostAddress());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Compare the final 64-bit interface identifier and skip the address
|
||||
// if it doesn't match our link-local address.
|
||||
if (linkLocalAddr != null && tries == 0) {
|
||||
boolean matched = true;
|
||||
|
||||
for (int i = 8; i < 16; i++) {
|
||||
if (linkLocalAddr.getAddress()[i] != addr.getAddress()[i]) {
|
||||
matched = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!matched) {
|
||||
LimeLog.info("Ignoring non-matching global address: "+addr.getHostAddress());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void handleServiceInfo(ServiceInfo info) throws UnsupportedEncodingException {
|
||||
Inet4Address addrs[] = info.getInet4Addresses();
|
||||
Inet6Address v6Addrs[] = info.getInet6Addresses();
|
||||
|
||||
LimeLog.info("mDNS: "+info.getName()+" has "+addrs.length+" addresses");
|
||||
LimeLog.info("mDNS: "+info.getName()+" has "+addrs.length+" IPv4 addresses");
|
||||
LimeLog.info("mDNS: "+info.getName()+" has "+v6Addrs.length+" IPv6 addresses");
|
||||
|
||||
Inet6Address v6Addr = getBestIpv6Address(v6Addrs);
|
||||
|
||||
// Add a computer object for each IPv4 address reported by the PC
|
||||
for (Inet4Address addr : addrs) {
|
||||
for (Inet4Address v4Addr : addrs) {
|
||||
synchronized (computers) {
|
||||
MdnsComputer computer = new MdnsComputer(info.getName(), addr);
|
||||
if (computers.put(computer.getAddress(), computer) == null) {
|
||||
MdnsComputer computer = new MdnsComputer(info.getName(), v4Addr, v6Addr);
|
||||
if (computers.put(computer.getAddressV4(), computer) == null) {
|
||||
// This was a new entry
|
||||
listener.notifyComputerAdded(computer);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user