in sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java [145:228]
protected OpenFuture doInit(Buffer buffer) {
String hostToConnect = buffer.getString();
int portToConnect = buffer.getInt();
String originatorIpAddress = buffer.getString();
int originatorPort = buffer.getInt();
boolean debugEnabled = log.isDebugEnabled();
if (debugEnabled) {
log.debug("doInit({}) Receiving request for direct tcpip:"
+ " hostToConnect={}, portToConnect={}, originatorIpAddress={}, originatorPort={}",
this, hostToConnect, portToConnect, originatorIpAddress, originatorPort);
}
SshdSocketAddress address;
Type channelType = getTcpipChannelType();
switch (type) {
case Direct:
address = new SshdSocketAddress(hostToConnect, portToConnect);
break;
case Forwarded: {
Forwarder forwarder = service.getForwarder();
address = forwarder.getForwardedPort(portToConnect);
break;
}
default:
throw new IllegalStateException("Unknown server channel type: " + channelType);
}
originatorAddress = new SshdSocketAddress(originatorIpAddress, originatorPort);
tunnelEntrance = new SshdSocketAddress(hostToConnect, portToConnect);
tunnelExit = address;
Session session = getSession();
FactoryManager manager = Objects.requireNonNull(session.getFactoryManager(), "No factory manager");
TcpForwardingFilter filter = manager.getTcpForwardingFilter();
OpenFuture f = new DefaultOpenFuture(this, this);
try {
if ((address == null) || (filter == null) || (!filter.canConnect(channelType, address, session))) {
if (debugEnabled) {
log.debug("doInit({})[{}][haveFilter={}] filtered out {}", this, type, filter != null, address);
}
try {
f.setException(new SshChannelOpenException(getChannelId(),
SshConstants.SSH_OPEN_ADMINISTRATIVELY_PROHIBITED, "Connection denied"));
} finally {
super.close(true);
}
return f;
}
} catch (Error e) {
warn("doInit({})[{}] failed ({}) to consult forwarding filter: {}",
session, channelType, e.getClass().getSimpleName(), e.getMessage(), e);
throw new RuntimeSshException(e);
}
out = new ChannelAsyncOutputStream(this, SshConstants.SSH_MSG_CHANNEL_DATA) {
@Override
@SuppressWarnings("synthetic-access")
protected CloseFuture doCloseGracefully() {
DefaultCloseFuture result = new DefaultCloseFuture(getChannelId(), futureLock);
CloseFuture packetsWritten = super.doCloseGracefully();
packetsWritten.addListener(p -> {
try {
// The channel writes EOF directly through the SSH session
IoWriteFuture eofSent = sendEof();
if (eofSent != null) {
eofSent.addListener(f -> result.setClosed());
return;
}
} catch (Exception e) {
getSession().exceptionCaught(e);
}
result.setClosed();
});
return result;
}
};
IoServiceFactory ioServiceFactory = manager.getIoServiceFactory();
connector = ioServiceFactory.createConnector(new PortIoHandler());
IoConnectFuture future = connector.connect(address.toInetSocketAddress(), null, getLocalAddress());
future.addListener(future1 -> handleChannelConnectResult(f, future1));
return f;
}