Transport: Fix thrashing of UPnP IPv6 listen sockets

Strip % suffixes from addresses before comparing
Fix HTTPMUSocket.getLocalAddress() to return the correct bound address
Throw exception on multicast socket bind failures, don't attempt
further operations on failed sockets
Add toString() to sockets for debugging
Log tweaks
This commit is contained in:
zzz
2022-05-11 11:54:25 -04:00
parent 07dbab9f02
commit 81255e19ae
12 changed files with 128 additions and 32 deletions

View File

@@ -262,4 +262,8 @@ public class HTTPServer implements Runnable
httpServerThread = null;
return true;
}
/** I2P */
@Override
public String toString() { return getBindAddress(); }
}

View File

@@ -98,6 +98,7 @@ package org.cybergarage.upnp;
import java.io.File;
import java.io.InputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.URL;
import java.util.Calendar;
@@ -1439,7 +1440,14 @@ public class Device implements org.cybergarage.http.HTTPRequestListener,
public void announce(String bindAddr) {
String devLocation = getLocationURL(bindAddr);
SSDPNotifySocket ssdpSock = new SSDPNotifySocket(bindAddr);
SSDPNotifySocket ssdpSock;
// I2P
try {
ssdpSock = new SSDPNotifySocket(bindAddr);
} catch (IOException ioe) {
Debug.warning("Failed announce from " + bindAddr, ioe);
return;
}
SSDPNotifyRequest ssdpReq = new SSDPNotifyRequest();
ssdpReq.setServer(UPnP.getServerName());
@@ -1514,7 +1522,14 @@ public class Device implements org.cybergarage.http.HTTPRequestListener,
}
public void byebye(String bindAddr) {
SSDPNotifySocket ssdpSock = new SSDPNotifySocket(bindAddr);
SSDPNotifySocket ssdpSock;
// I2P
try {
ssdpSock = new SSDPNotifySocket(bindAddr);
} catch (IOException ioe) {
Debug.warning("Failed byebye from " + bindAddr, ioe);
return;
}
SSDPNotifyRequest ssdpReq = new SSDPNotifyRequest();
ssdpReq.setNTS(NTS.BYEBYE);

View File

@@ -73,6 +73,7 @@ package org.cybergarage.upnp;
import java.io.File;
import java.io.InputStream;
import java.io.IOException;
import java.net.URL;
import java.util.Iterator;
@@ -662,9 +663,14 @@ public class Service
ssdpReq.setNT(serviceNT);
ssdpReq.setUSN(serviceUSN);
SSDPNotifySocket ssdpSock = new SSDPNotifySocket(bindAddr);
Device.notifyWait();
ssdpSock.post(ssdpReq);
// I2P
try {
SSDPNotifySocket ssdpSock = new SSDPNotifySocket(bindAddr);
Device.notifyWait();
ssdpSock.post(ssdpReq);
} catch (IOException ioe) {
Debug.warning("Failed announce from " + bindAddr, ioe);
}
}
public void byebye(String bindAddr)
@@ -679,9 +685,14 @@ public class Service
ssdpReq.setNT(devNT);
ssdpReq.setUSN(devUSN);
SSDPNotifySocket ssdpSock = new SSDPNotifySocket(bindAddr);
Device.notifyWait();
ssdpSock.post(ssdpReq);
// I2P
try {
SSDPNotifySocket ssdpSock = new SSDPNotifySocket(bindAddr);
Device.notifyWait();
ssdpSock.post(ssdpReq);
} catch (IOException ioe) {
Debug.warning("Failed announce from " + bindAddr, ioe);
}
}
public boolean serviceSearchResponse(SSDPPacket ssdpPacket)

View File

@@ -55,6 +55,8 @@ public class HTTPMUSocket
private InetSocketAddress ssdpMultiGroup = null;
private MulticastSocket ssdpMultiSock = null;
private NetworkInterface ssdpMultiIf = null;
/** I2P */
private InetAddress _bindAddress;
////////////////////////////////////////////////
// Constructor
@@ -80,6 +82,7 @@ public class HTTPMUSocket
public String getLocalAddress()
{
/**** I2P fix
if (ssdpMultiGroup == null || ssdpMultiIf == null)
return "";
InetAddress mcastAddr = ssdpMultiGroup.getAddress();
@@ -92,6 +95,10 @@ public class HTTPMUSocket
return addr.getHostAddress();
}
return "";
****/
if (_bindAddress == null)
return "";
return _bindAddress.getHostAddress();
}
/**
@@ -151,6 +158,8 @@ public class HTTPMUSocket
ssdpMultiGroup = new InetSocketAddress(InetAddress.getByName(addr), port);
ssdpMultiIf = NetworkInterface.getByInetAddress(bindAddr);
ssdpMultiSock.joinGroup(ssdpMultiGroup, ssdpMultiIf);
// I2P
_bindAddress = bindAddr;
}
catch (Exception e) {
Debug.warning(e);
@@ -256,5 +265,10 @@ public class HTTPMUSocket
return recvPacket;
}
/** I2P */
@Override
public String toString() { return getLocalAddress(); }
}

View File

@@ -268,5 +268,10 @@ public class HTTPUSocket
return true;
}
*/
/** I2P */
@Override
public String toString() { return localAddr; }
}

View File

@@ -54,7 +54,7 @@ public class SSDPNotifySocket extends HTTPMUSocket implements Runnable
// Constructor
////////////////////////////////////////////////
public SSDPNotifySocket(String bindAddr)
public SSDPNotifySocket(String bindAddr) throws IOException
{
String addr = SSDP.ADDRESS;
useIPv6Address = false;
@@ -62,7 +62,9 @@ public class SSDPNotifySocket extends HTTPMUSocket implements Runnable
addr = SSDP.getIPv6Address();
useIPv6Address = true;
}
open(addr, SSDP.PORT, bindAddr);
boolean ok = open(addr, SSDP.PORT, bindAddr);
if (!ok)
throw new IOException("Bind to " + bindAddr + " failed");
Debug.message("Opened SSDP notify socket at " + bindAddr + ':' + SSDP.PORT);
setControlPoint(null);
}

View File

@@ -15,12 +15,14 @@
package org.cybergarage.upnp.ssdp;
import java.io.IOException;
import java.net.InetAddress;
import java.util.*;
import org.cybergarage.net.*;
import org.cybergarage.upnp.*;
import org.cybergarage.util.Debug;
public class SSDPNotifySocketList extends Vector<SSDPNotifySocket>
{
@@ -86,8 +88,12 @@ public class SSDPNotifySocketList extends Vector<SSDPNotifySocket>
for (int i = 0; i < bindAddresses.length; i++) {
if(bindAddresses[i]!=null){
SSDPNotifySocket ssdpNotifySocket = new SSDPNotifySocket(bindAddresses[i]);
add(ssdpNotifySocket);
try {
SSDPNotifySocket ssdpNotifySocket = new SSDPNotifySocket(bindAddresses[i]);
add(ssdpNotifySocket);
} catch (IOException ioe) {
Debug.warning("Failed bind to " + bindAddresses[i], ioe);
}
}
}
return true;

View File

@@ -54,8 +54,10 @@ public class SSDPSearchSocket extends HTTPMUSocket implements Runnable
* @param multicast The multicast address to use as destination
* @since 1.8
*/
public SSDPSearchSocket(String bindAddr,int port,String multicast){
open(bindAddr,multicast);
public SSDPSearchSocket(String bindAddr,int port,String multicast) throws IOException {
boolean ok = open(bindAddr,multicast);
if (!ok)
throw new IOException("Bind to " + bindAddr + " failed");
}
/**
@@ -63,12 +65,15 @@ public class SSDPSearchSocket extends HTTPMUSocket implements Runnable
* @param bindAddr the binding address for sending multicast packet
* @since 1.8
*/
public SSDPSearchSocket(InetAddress bindAddr){
public SSDPSearchSocket(InetAddress bindAddr) throws IOException {
boolean ok;
if(bindAddr.getAddress().length!=4){
this.open((Inet6Address)bindAddr);
ok = this.open((Inet6Address)bindAddr);
}else{
this.open((Inet4Address)bindAddr);
ok = this.open((Inet4Address)bindAddr);
}
if (!ok)
throw new IOException("Bind to " + bindAddr + " failed");
}
////////////////////////////////////////////////

View File

@@ -18,11 +18,13 @@
package org.cybergarage.upnp.ssdp;
import java.io.IOException;
import java.net.InetAddress;
import java.util.Vector;
import org.cybergarage.net.HostInterface;
import org.cybergarage.upnp.device.SearchListener;
import org.cybergarage.util.Debug;
public class SSDPSearchSocketList extends Vector<SSDPSearchSocket>
{
@@ -101,12 +103,16 @@ public class SSDPSearchSocketList extends Vector<SSDPSearchSocket>
for (int i = 0; i < bindAddresses.length; i++) {
if(bindAddresses[i]!=null){
SSDPSearchSocket ssdpSearchSocket;
if(HostInterface.isIPv6Address(bindAddresses[i]))
ssdpSearchSocket = new SSDPSearchSocket(bindAddresses[i],port ,multicastIPv6 );
else
ssdpSearchSocket = new SSDPSearchSocket(bindAddresses[i],port,multicastIPv4 );
add(ssdpSearchSocket);
try {
SSDPSearchSocket ssdpSearchSocket;
if(HostInterface.isIPv6Address(bindAddresses[i]))
ssdpSearchSocket = new SSDPSearchSocket(bindAddresses[i],port ,multicastIPv6 );
else
ssdpSearchSocket = new SSDPSearchSocket(bindAddresses[i],port,multicastIPv4 );
add(ssdpSearchSocket);
} catch (IOException ioe) {
Debug.warning("Failed bind to " + bindAddresses[i], ioe);
}
}
}
return true;