Add support for zero configuration IPv6 streaming

This commit is contained in:
Cameron Gutman
2019-07-13 20:43:14 -07:00
parent ba0171221c
commit 83b66b19de
5 changed files with 166 additions and 57 deletions
@@ -220,8 +220,8 @@ public class ComputerManagerService extends Service {
}
}
public boolean addComputerBlocking(String addr, boolean manuallyAdded) {
return ComputerManagerService.this.addComputerBlocking(addr, manuallyAdded);
public boolean addComputerBlocking(ComputerDetails fakeDetails) {
return ComputerManagerService.this.addComputerBlocking(fakeDetails);
}
public void removeComputer(String name) {
@@ -297,8 +297,25 @@ public class ComputerManagerService extends Service {
return new MdnsDiscoveryListener() {
@Override
public void notifyComputerAdded(MdnsComputer computer) {
ComputerDetails details = new ComputerDetails();
// Populate the computer template with mDNS info
if (computer.getAddressV4() != null) {
details.localAddress = computer.getAddressV4().getHostAddress();
}
if (computer.getAddressV6() != null) {
details.ipv6Address = computer.getAddressV6().getHostAddress();
}
// Since we're on the same network, we can use STUN to find
// our WAN address, which is also very likely the WAN address
// of the PC. We can use this later to connect remotely.
details.remoteAddress = NvConnection.findExternalAddressForMdns("stun.moonlight-stream.org", 3478);
// Kick off a serverinfo poll on this machine
addComputerBlocking(computer.getAddress().getHostAddress(), false);
if (!addComputerBlocking(details)) {
LimeLog.warning("Auto-discovered PC failed to respond: "+details);
}
}
@Override
@@ -345,24 +362,7 @@ public class ComputerManagerService extends Service {
}
}
public boolean addComputerBlocking(String addr, boolean manuallyAdded) {
// Setup a placeholder
ComputerDetails fakeDetails = new ComputerDetails();
if (manuallyAdded) {
// Add PC UI
fakeDetails.manualAddress = addr;
}
else {
// mDNS
fakeDetails.localAddress = addr;
// Since we're on the same network, we can use STUN to find
// our WAN address, which is also very likely the WAN address
// of the PC. We can use this later to connect remotely.
fakeDetails.remoteAddress = NvConnection.findExternalAddressForMdns("stun.moonlight-stream.org", 3478);
}
public boolean addComputerBlocking(ComputerDetails fakeDetails) {
// Block while we try to fill the details
try {
// We cannot use runPoll() here because it will attempt to persist the state of the machine
@@ -395,10 +395,6 @@ public class ComputerManagerService extends Service {
return true;
}
else {
if (!manuallyAdded) {
LimeLog.warning("Auto-discovered PC failed to respond: "+addr);
}
return false;
}
}
@@ -514,14 +510,16 @@ public class ComputerManagerService extends Service {
t.start();
}
private String fastPollPc(final String localAddress, final String remoteAddress, final String manualAddress) throws InterruptedException {
private String fastPollPc(final String localAddress, final String remoteAddress, final String manualAddress, final String ipv6Address) throws InterruptedException {
final boolean[] remoteInfo = new boolean[2];
final boolean[] localInfo = new boolean[2];
final boolean[] manualInfo = new boolean[2];
final boolean[] ipv6Info = new boolean[2];
startFastPollThread(localAddress, localInfo);
startFastPollThread(remoteAddress, remoteInfo);
startFastPollThread(manualAddress, manualInfo);
startFastPollThread(ipv6Address, ipv6Info);
// Check local first
synchronized (localInfo) {
@@ -545,7 +543,7 @@ public class ComputerManagerService extends Service {
}
}
// And finally, remote
// Now remote IPv4
synchronized (remoteInfo) {
while (!remoteInfo[0]) {
remoteInfo.wait(500);
@@ -556,6 +554,17 @@ public class ComputerManagerService extends Service {
}
}
// Now global IPv6
synchronized (ipv6Info) {
while (!ipv6Info[0]) {
ipv6Info.wait(500);
}
if (ipv6Info[1]) {
return ipv6Address;
}
}
return null;
}
@@ -566,8 +575,8 @@ public class ComputerManagerService extends Service {
// Do not write this address to details.activeAddress because:
// a) it's only a candidate and may be wrong (multiple PCs behind a single router)
// b) if it's null, it will be unexpectedly nulling the activeAddress of a possibly online PC
LimeLog.info("Starting fast poll for "+details.name+" ("+details.localAddress +", "+details.remoteAddress +", "+details.manualAddress +")");
String candidateAddress = fastPollPc(details.localAddress, details.remoteAddress, details.manualAddress);
LimeLog.info("Starting fast poll for "+details.name+" ("+details.localAddress +", "+details.remoteAddress +", "+details.manualAddress+", "+details.ipv6Address+")");
String candidateAddress = fastPollPc(details.localAddress, details.remoteAddress, details.manualAddress, details.ipv6Address);
LimeLog.info("Fast poll for "+details.name+" returned candidate address: "+candidateAddress);
// If no connection could be established to either IP address, there's nothing we can do
@@ -582,8 +591,9 @@ public class ComputerManagerService extends Service {
// already tried
HashSet<String> uniqueAddresses = new HashSet<>();
uniqueAddresses.add(details.localAddress);
uniqueAddresses.add(details.remoteAddress);
uniqueAddresses.add(details.manualAddress);
uniqueAddresses.add(details.remoteAddress);
uniqueAddresses.add(details.ipv6Address);
for (String addr : uniqueAddresses) {
if (addr == null || addr.equals(candidateAddress)) {
continue;