forked from I2P_Developers/i2p.i2p
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:
@ -1,4 +1,5 @@
|
||||
2022-05-11 zzz
|
||||
* Transport: Fix thrashing of UPnP IPv6 listen sockets
|
||||
* Util: Rename modified apache classes (Gitlab ticket #353)
|
||||
|
||||
2022-05-02 zzz
|
||||
|
@ -18,7 +18,7 @@ public class RouterVersion {
|
||||
/** deprecated */
|
||||
public final static String ID = "Git";
|
||||
public final static String VERSION = CoreVersion.VERSION;
|
||||
public final static long BUILD = 17;
|
||||
public final static long BUILD = 18;
|
||||
|
||||
/** for example "-test" */
|
||||
public final static String EXTRA = "-rc";
|
||||
|
@ -3,6 +3,7 @@
|
||||
* http://www.gnu.org/ for further details of the GPL. */
|
||||
package net.i2p.router.transport;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Inet6Address;
|
||||
@ -724,12 +725,20 @@ public class UPnP extends ControlPoint implements DeviceChangeListener, EventLis
|
||||
int slash = addr.indexOf('/');
|
||||
if (slash >= 0)
|
||||
addr = addr.substring(slash + 1);
|
||||
int pct = addr.indexOf('%');
|
||||
if (pct > 0)
|
||||
addr = addr.substring(0, pct);
|
||||
if (!addrs.contains(addr)) {
|
||||
// the first time through this will close a lot of sockets,
|
||||
// because HTTPServerList binds to every address,
|
||||
// including IPv6 deprecated
|
||||
iter.remove();
|
||||
skt.close();
|
||||
skt.stop();
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Closed HTTP server socket: " + addr);
|
||||
} else if (_log.shouldDebug()) {
|
||||
_log.debug("Retained HTTP server socket: " + addr);
|
||||
}
|
||||
oldaddrs.add(addr);
|
||||
}
|
||||
@ -758,6 +767,9 @@ public class UPnP extends ControlPoint implements DeviceChangeListener, EventLis
|
||||
for (Iterator<SSDPSearchResponseSocket> iter = list.iterator(); iter.hasNext(); ) {
|
||||
SSDPSearchResponseSocket skt = iter.next();
|
||||
String addr = skt.getLocalAddress();
|
||||
int pct = addr.indexOf('%');
|
||||
if (pct > 0)
|
||||
addr = addr.substring(0, pct);
|
||||
if (!addrs.contains(addr)) {
|
||||
iter.remove();
|
||||
skt.setControlPoint(null);
|
||||
@ -765,6 +777,8 @@ public class UPnP extends ControlPoint implements DeviceChangeListener, EventLis
|
||||
skt.stop();
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Closed SSDP search response socket: " + addr);
|
||||
} else if (_log.shouldDebug()) {
|
||||
_log.debug("Retained SSDP search response socket: " + addr);
|
||||
}
|
||||
oldaddrs.add(addr);
|
||||
}
|
||||
@ -785,6 +799,9 @@ public class UPnP extends ControlPoint implements DeviceChangeListener, EventLis
|
||||
for (Iterator<SSDPNotifySocket> iter = nlist.iterator(); iter.hasNext(); ) {
|
||||
SSDPNotifySocket skt = iter.next();
|
||||
String addr = skt.getLocalAddress();
|
||||
int pct = addr.indexOf('%');
|
||||
if (pct > 0)
|
||||
addr = addr.substring(0, pct);
|
||||
if (!addrs.contains(addr)) {
|
||||
iter.remove();
|
||||
skt.setControlPoint(null);
|
||||
@ -792,20 +809,29 @@ public class UPnP extends ControlPoint implements DeviceChangeListener, EventLis
|
||||
skt.stop();
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Closed SSDP notify socket: " + addr);
|
||||
} else if (_log.shouldDebug()) {
|
||||
_log.debug("Retained SSDP notify socket: " + addr);
|
||||
}
|
||||
oldaddrs.add(addr);
|
||||
}
|
||||
for (String addr : addrs) {
|
||||
if (!oldaddrs.contains(addr)) {
|
||||
// TODO this calls open() in constructor, fails silently
|
||||
SSDPNotifySocket socket = new SSDPNotifySocket(addr);
|
||||
socket.setControlPoint(this);
|
||||
socket.start();
|
||||
nlist.add(socket);
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Added SSDP notify socket: " + addr);
|
||||
try {
|
||||
SSDPNotifySocket socket = new SSDPNotifySocket(addr);
|
||||
socket.setControlPoint(this);
|
||||
socket.start();
|
||||
nlist.add(socket);
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Added SSDP notify socket: " + addr);
|
||||
} catch (IOException ioe) {
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Failed to add SSDP notify socket: " + addr, ioe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_log.shouldDebug())
|
||||
_log.debug("Current sockets:\nHTTP: " + hlist + "\nSearch response: " + list + "\nNotify: " + nlist);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1562,7 +1588,8 @@ public class UPnP extends ControlPoint implements DeviceChangeListener, EventLis
|
||||
Service service;
|
||||
synchronized(lock) {
|
||||
if(!isNATPresent()) {
|
||||
_log.error("Can't removeMapping: " + isNATPresent() + " " + _router);
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Can't removeMapping: " + isNATPresent() + " " + _router);
|
||||
return false;
|
||||
}
|
||||
service = fp.isIP6 ? _service6 : _service;
|
||||
|
@ -262,4 +262,8 @@ public class HTTPServer implements Runnable
|
||||
httpServerThread = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** I2P */
|
||||
@Override
|
||||
public String toString() { return getBindAddress(); }
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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(); }
|
||||
|
||||
}
|
||||
|
||||
|
@ -268,5 +268,10 @@ public class HTTPUSocket
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
/** I2P */
|
||||
@Override
|
||||
public String toString() { return localAddr; }
|
||||
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user