use of org.jupnp.model.message.UpnpResponse in project besu by hyperledger.
the class UpnpNatManager method releaseAllPortForwards.
/**
* Attempts to release any forwarded ports.
*
* <p>Note that this is not synchronized, as it is expected to be called within an
* already-synchronized context ({@link #stop()}).
*
* @return A CompletableFuture that will complete when all port forward requests have been made
*/
private CompletableFuture<Void> releaseAllPortForwards() {
// if we haven't observed the WANIPConnection service yet, we should have no port forwards to
// release
CompletableFuture<RemoteService> wanIPConnectionServiceFuture = getService(SERVICE_TYPE_WAN_IP_CONNECTION);
if (!wanIPConnectionServiceFuture.isDone()) {
return CompletableFuture.completedFuture(null);
}
RemoteService service = wanIPConnectionServiceFuture.join();
List<CompletableFuture<Void>> futures = new ArrayList<>();
boolean done = false;
while (!done) {
NatPortMapping portMapping;
synchronized (forwardedPorts) {
if (forwardedPorts.isEmpty()) {
done = true;
continue;
}
portMapping = forwardedPorts.get(0);
forwardedPorts.remove(0);
}
LOG.info("Releasing port forward for {} {} -> {}", portMapping.getProtocol(), portMapping.getInternalPort(), portMapping.getExternalPort());
CompletableFuture<Void> future = new CompletableFuture<>();
PortMappingDelete callback = new PortMappingDelete(service, toJupnpPortMapping(portMapping)) {
/**
* Because the underlying jupnp library omits generics info in this method signature, we
* must too when we override it.
*/
@Override
@SuppressWarnings("rawtypes")
public void success(final ActionInvocation invocation) {
LOG.info("Port forward {} {} -> {} removed successfully.", portMapping.getProtocol(), portMapping.getInternalPort(), portMapping.getExternalPort());
future.complete(null);
}
/**
* Because the underlying jupnp library omits generics info in this method signature, we
* must too when we override it.
*/
@Override
@SuppressWarnings("rawtypes")
public void failure(final ActionInvocation invocation, final UpnpResponse operation, final String msg) {
LOG.warn("Port forward removal request for {} {} -> {} failed (ignoring): {}", portMapping.getProtocol(), portMapping.getInternalPort(), portMapping.getExternalPort(), msg);
// ignore exceptions; we did our best
future.complete(null);
}
};
upnpService.getControlPoint().execute(callback);
futures.add(future);
}
// complete
return CompletableFuture.allOf(futures.toArray(new CompletableFuture<?>[0]));
}
use of org.jupnp.model.message.UpnpResponse in project besu by hyperledger.
the class UpnpNatManager method initiateExternalIpQuery.
/**
* Sends a UPnP request to the discovered IGD for the external ip address.
*
* <p>Note that this is not synchronized, as it is expected to be called within an
* already-synchronized context ({@link #start()}).
*/
private void initiateExternalIpQuery() {
discoverService(SERVICE_TYPE_WAN_IP_CONNECTION).thenAccept(service -> {
// our query, which will be handled asynchronously by the jupnp library
GetExternalIP callback = new GetExternalIP(service) {
/**
* Override the success(ActionInvocation) version of success so that we can take
* a peek at the network interface that we discovered this on.
*
* <p>Because the underlying jupnp library omits generics info in this method
* signature, we must too when we override it.
*/
@Override
@SuppressWarnings("rawtypes")
public void success(final ActionInvocation invocation) {
RemoteService service = (RemoteService) invocation.getAction().getService();
RemoteDevice device = service.getDevice();
RemoteDeviceIdentity identity = device.getIdentity();
discoveredOnLocalAddress = Optional.of(identity.getDiscoveredOnLocalAddress().getHostAddress());
super.success(invocation);
}
@Override
protected void success(final String result) {
LOG.info("External IP address {} detected for internal address {}", result, discoveredOnLocalAddress.get());
externalIpQueryFuture.complete(result);
}
/**
* Because the underlying jupnp library omits generics info in this method
* signature, we must too when we override it.
*/
@Override
@SuppressWarnings("rawtypes")
public void failure(final ActionInvocation invocation, final UpnpResponse operation, final String msg) {
externalIpQueryFuture.completeExceptionally(new Exception(msg));
}
};
upnpService.getControlPoint().execute(callback);
});
}
use of org.jupnp.model.message.UpnpResponse in project besu by hyperledger.
the class UpnpNatManager method requestPortForward.
/**
* Sends a UPnP request to the discovered IGD to request a port forward.
*
* @param portMapping is a portMapping object describing the desired port mapping parameters.
* @return A CompletableFuture that can be used to query the result (or error).
*/
private CompletableFuture<Void> requestPortForward(final PortMapping portMapping) {
CompletableFuture<Void> upnpQueryFuture = new CompletableFuture<>();
return externalIpQueryFuture.thenCompose(address -> {
// note that this future is a dependency of externalIpQueryFuture, so it must be completed
// by now
RemoteService service = getService(SERVICE_TYPE_WAN_IP_CONNECTION).join();
// so we can prime the NewInternalClient field if it was omitted
if (null == portMapping.getInternalClient()) {
portMapping.setInternalClient(discoveredOnLocalAddress.get());
}
// our query, which will be handled asynchronously by the jupnp library
PortMappingAdd callback = new PortMappingAdd(service, portMapping) {
/**
* Because the underlying jupnp library omits generics info in this method
* signature, we must too when we override it.
*/
@Override
@SuppressWarnings("rawtypes")
public void success(final ActionInvocation invocation) {
LOG.info("Port forward request for {} {} -> {} succeeded.", portMapping.getProtocol(), portMapping.getInternalPort(), portMapping.getExternalPort());
synchronized (forwardedPorts) {
final NatServiceType natServiceType = NatServiceType.fromString(portMapping.getDescription());
final NatPortMapping natPortMapping = new NatPortMapping(natServiceType, NetworkProtocol.valueOf(portMapping.getProtocol().name()), portMapping.getInternalClient(), portMapping.getRemoteHost(), portMapping.getExternalPort().getValue().intValue(), portMapping.getInternalPort().getValue().intValue());
forwardedPorts.add(natPortMapping);
}
upnpQueryFuture.complete(null);
}
/**
* Because the underlying jupnp library omits generics info in this method
* signature, we must too when we override it.
*/
@Override
@SuppressWarnings("rawtypes")
public void failure(final ActionInvocation invocation, final UpnpResponse operation, final String msg) {
LOG.warn("Port forward request for {} {} -> {} failed: {}", portMapping.getProtocol(), portMapping.getInternalPort(), portMapping.getExternalPort(), msg);
upnpQueryFuture.completeExceptionally(new Exception(msg));
}
};
LOG.info("Requesting port forward for {} {} -> {}", portMapping.getProtocol(), portMapping.getInternalPort(), portMapping.getExternalPort());
upnpService.getControlPoint().execute(callback);
return upnpQueryFuture;
});
}
Aggregations