in sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java [143:221]
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() {
// First get the last packets out
CloseFuture result = super.doCloseGracefully();
result.addListener(f -> {
try {
// The channel writes EOF directly through the SSH session
sendEof();
} catch (IOException e) {
session.exceptionCaught(e);
}
});
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;
}