Search in sources :

Example 1 with UpnpResponse

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]));
}
Also used : NatPortMapping(org.hyperledger.besu.nat.core.domain.NatPortMapping) UpnpResponse(org.jupnp.model.message.UpnpResponse) ActionInvocation(org.jupnp.model.action.ActionInvocation) ArrayList(java.util.ArrayList) PortMappingDelete(org.jupnp.support.igd.callback.PortMappingDelete) CompletableFuture(java.util.concurrent.CompletableFuture) RemoteService(org.jupnp.model.meta.RemoteService)

Example 2 with UpnpResponse

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);
    });
}
Also used : RemoteService(org.jupnp.model.meta.RemoteService) UpnpResponse(org.jupnp.model.message.UpnpResponse) ActionInvocation(org.jupnp.model.action.ActionInvocation) GetExternalIP(org.jupnp.support.igd.callback.GetExternalIP) RemoteDeviceIdentity(org.jupnp.model.meta.RemoteDeviceIdentity) RemoteDevice(org.jupnp.model.meta.RemoteDevice) NatInitializationException(org.hyperledger.besu.nat.core.exception.NatInitializationException)

Example 3 with UpnpResponse

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;
    });
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) NatPortMapping(org.hyperledger.besu.nat.core.domain.NatPortMapping) RemoteService(org.jupnp.model.meta.RemoteService) UpnpResponse(org.jupnp.model.message.UpnpResponse) ActionInvocation(org.jupnp.model.action.ActionInvocation) PortMappingAdd(org.jupnp.support.igd.callback.PortMappingAdd) NatServiceType(org.hyperledger.besu.nat.core.domain.NatServiceType) NatInitializationException(org.hyperledger.besu.nat.core.exception.NatInitializationException)

Aggregations

ActionInvocation (org.jupnp.model.action.ActionInvocation)3 UpnpResponse (org.jupnp.model.message.UpnpResponse)3 RemoteService (org.jupnp.model.meta.RemoteService)3 CompletableFuture (java.util.concurrent.CompletableFuture)2 NatPortMapping (org.hyperledger.besu.nat.core.domain.NatPortMapping)2 NatInitializationException (org.hyperledger.besu.nat.core.exception.NatInitializationException)2 ArrayList (java.util.ArrayList)1 NatServiceType (org.hyperledger.besu.nat.core.domain.NatServiceType)1 RemoteDevice (org.jupnp.model.meta.RemoteDevice)1 RemoteDeviceIdentity (org.jupnp.model.meta.RemoteDeviceIdentity)1 GetExternalIP (org.jupnp.support.igd.callback.GetExternalIP)1 PortMappingAdd (org.jupnp.support.igd.callback.PortMappingAdd)1 PortMappingDelete (org.jupnp.support.igd.callback.PortMappingDelete)1