/** * @param address The request bind address * @param handlerFactory A {@link Factory} to create an {@link IoHandler} if necessary * @return The {@link InetSocketAddress} to which the binding occurred * @throws IOException If failed to bind */ private InetSocketAddress doBind( SshdSocketAddress address, Factory<? extends IoHandler> handlerFactory) throws IOException { if (acceptor == null) { FactoryManager manager = session.getFactoryManager(); IoServiceFactory factory = manager.getIoServiceFactory(); IoHandler handler = handlerFactory.create(); acceptor = factory.createAcceptor(handler); } // TODO find a better way to determine the resulting bind address - what if multi-threaded // calls... Set<SocketAddress> before = acceptor.getBoundAddresses(); try { InetSocketAddress bindAddress = address.toInetSocketAddress(); acceptor.bind(bindAddress); Set<SocketAddress> after = acceptor.getBoundAddresses(); if (GenericUtils.size(after) > 0) { after.removeAll(before); } if (GenericUtils.isEmpty(after)) { throw new IOException( "Error binding to " + address + "[" + bindAddress + "]: no local addresses bound"); } if (after.size() > 1) { throw new IOException( "Multiple local addresses have been bound for " + address + "[" + bindAddress + "]"); } return (InetSocketAddress) after.iterator().next(); } catch (IOException bindErr) { Set<SocketAddress> after = acceptor.getBoundAddresses(); if (GenericUtils.isEmpty(after)) { close(); } throw bindErr; } }
@Override public synchronized void stopDynamicPortForwarding(SshdSocketAddress local) throws IOException { Closeable obj; synchronized (dynamicLocal) { obj = dynamicLocal.remove(local.getPort()); } if (obj != null) { if (log.isDebugEnabled()) { log.debug("stopDynamicPortForwarding(" + local + ") unbinding"); } obj.close(true); acceptor.unbind(local.toInetSocketAddress()); } else { if (log.isDebugEnabled()) { log.debug("stopDynamicPortForwarding(" + local + ") no binding found"); } } }
@Override public synchronized void stopLocalPortForwarding(SshdSocketAddress local) throws IOException { ValidateUtils.checkNotNull(local, "Local address is null"); SshdSocketAddress bound; synchronized (localToRemote) { bound = localToRemote.remove(local.getPort()); } if ((bound != null) && (acceptor != null)) { if (log.isDebugEnabled()) { log.debug("stopLocalPortForwarding(" + local + ") unbind " + bound); } acceptor.unbind(bound.toInetSocketAddress()); } else { if (log.isDebugEnabled()) { log.debug("stopLocalPortForwarding(" + local + ") no mapping/acceptor for " + bound); } } }
@Override public synchronized void localPortForwardingCancelled(SshdSocketAddress local) throws IOException { LocalForwardingEntry entry; synchronized (localForwards) { entry = LocalForwardingEntry.findMatchingEntry( local.getHostName(), local.getPort(), localForwards); if (entry != null) { localForwards.remove(entry); } } if ((entry != null) && (acceptor != null)) { if (log.isDebugEnabled()) { log.debug("localPortForwardingCancelled(" + local + ") unbind " + entry); } acceptor.unbind(entry.toInetSocketAddress()); } else { if (log.isDebugEnabled()) { log.debug("localPortForwardingCancelled(" + local + ") no match/acceptor: " + entry); } } }