connect method
Future<SshHandshakeInfo>
connect({
- required SshEndpoint endpoint,
- required SshTransportSettings settings,
override
Implementation
@override
Future<SshHandshakeInfo> connect({
required SshEndpoint endpoint,
required SshTransportSettings settings,
}) async {
if (_state == SshTransportState.connecting ||
_state == SshTransportState.connected) {
throw StateError('SSH secure socket transport is already connected.');
}
_state = SshTransportState.connecting;
Socket? socket;
StreamIterator<List<int>>? incoming;
try {
socket = await Socket.connect(
endpoint.host,
endpoint.port,
timeout: settings.connectTimeout,
);
if (tcpNoDelay) {
socket.setOption(SocketOption.tcpNoDelay, true);
}
incoming = StreamIterator<List<int>>(socket);
_socket = socket;
_incoming = incoming;
_incomingBuffer.clear();
_packetQueue.clear();
_pendingPacketReaders.clear();
_pendingGlobalRequestReplies.clear();
_writerState = SshPlainPacketWriterState();
_readerState = SshPlainPacketReaderState();
_incomingCompression = const _SshIdentityCompressionState();
_outgoingCompression = const _SshIdentityCompressionState();
_hasAuthenticated = false;
_delayedIncomingCompressionPending = false;
_delayedOutgoingCompressionPending = false;
_activeRekey = null;
_pendingClientKexInit = null;
_outgoingPacketSequenceNumber = 0;
_incomingPacketSequenceNumber = 0;
_terminalError = null;
_terminalStackTrace = null;
_readLoop = null;
final SshBannerExchangeResult exchange = await _exchangeBanners(
localIdentification: settings.clientIdentification,
);
final SshKexInitMessage clientKexInit = _buildClientKexInit();
await _writePlainPacket(clientKexInit.encodePayload());
final SshKexInitMessage serverKexInit = SshKexInitMessage.decodePayload(
(await _readPacketWithState(SshPlainPacketReaderState())).payload,
);
final _SshKeyExchangeResult keyExchange = await _runKeyExchangeRound(
localIdentification: exchange.localBanner.value,
remoteIdentification: exchange.remoteBanner.value,
clientKexInit: clientKexInit,
serverKexInit: serverKexInit,
sessionIdentifier: null,
writePacket: _writePlainPacket,
readPacket: () => _readPacketWithState(SshPlainPacketReaderState()),
);
_handshake = keyExchange.handshake;
_resetRekeyCounters();
_state = SshTransportState.connected;
_startReadLoop();
return keyExchange.handshake;
} catch (_) {
_handshake = null;
_state = SshTransportState.disconnected;
await _closeResources();
rethrow;
}
}