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);
    }

    // return a future that completes successfully only when each of our port delete requests
    // complete
    return CompletableFuture.allOf(futures.toArray(new CompletableFuture<?>[0]));
  }
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
nat/src/main/java/org/hyperledger/besu/nat/upnp/UpnpNatManager.java