mirror of https://github.com/tp4a/teleport
格式化代码;使用auto和nullptr。
parent
c2cf5b1842
commit
d8c6bd0c84
|
@ -43,6 +43,7 @@
|
|||
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/telnet/telnet_conn.cpp" charset="GBK" />
|
||||
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/telnet/telnet_conn.h" charset="GBK" />
|
||||
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/telnet/telnet_proxy.cpp" charset="GBK" />
|
||||
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/telnet/telnet_recorder.h" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/telnet/telnet_session.cpp" charset="GBK" />
|
||||
<file url="file://$PROJECT_DIR$/server/tp_core/protocol/telnet/telnet_session.h" charset="GBK" />
|
||||
<file url="file://$PROJECT_DIR$/server/tp_web/src/main.cpp" charset="GBK" />
|
||||
|
|
|
@ -108,10 +108,12 @@ void SshChannelPair::process_pty_data_from_client(const uint8_t* data, uint32_t
|
|||
}
|
||||
|
||||
break;
|
||||
case 0x0d:return_count++;
|
||||
case 0x0d:
|
||||
return_count++;
|
||||
last_return_pos = offset;
|
||||
break;
|
||||
default:break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!valid_input)
|
||||
|
@ -220,12 +222,14 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t* data, uint32_t
|
|||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':esc_arg = esc_arg * 10 + (ch - '0');
|
||||
case '9':
|
||||
esc_arg = esc_arg * 10 + (ch - '0');
|
||||
break;
|
||||
|
||||
case 0x3f:
|
||||
case ';':
|
||||
case '>':m_cmd.reset();
|
||||
case '>':
|
||||
m_cmd.reset();
|
||||
return;
|
||||
|
||||
case 0x4b: { // 'K'
|
||||
|
@ -279,7 +283,8 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t* data, uint32_t
|
|||
break;
|
||||
}
|
||||
|
||||
default:esc_mode = false;
|
||||
default:
|
||||
esc_mode = false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -332,7 +337,8 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t* data, uint32_t
|
|||
|
||||
break;
|
||||
}
|
||||
default:m_cmd.replace(ch);
|
||||
default:
|
||||
m_cmd.replace(ch);
|
||||
if (m_pty_stat == PTY_STAT_WAIT_SERVER_ECHO) {
|
||||
m_pty_stat = PTY_STAT_WAIT_CLIENT_INPUT;
|
||||
// EXLOGD("------ turn to PTY_STAT_WAIT_CLIENT_INPUT, recv something.\n");
|
||||
|
@ -489,7 +495,8 @@ void SshChannelPair::process_sftp_command(ssh_channel ch, const uint8_t* data, u
|
|||
str2_len = (int) ((str2_ptr[0] << 24) | (str2_ptr[1] << 16) | (str2_ptr[2] << 8) | str2_ptr[3]);
|
||||
EXLOGD("[sftp-%s] SSH_FXP_LINK\n", m_owner->dbg_name().c_str());
|
||||
break;
|
||||
default:return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
int total_len = 5 + str1_len + 4;
|
||||
|
|
|
@ -5,10 +5,9 @@
|
|||
|
||||
#include <ex.h>
|
||||
|
||||
typedef std::map<SshSession *, unsigned char> ts_ssh_sessions;
|
||||
typedef std::map<SshSession*, unsigned char> ts_ssh_sessions;
|
||||
|
||||
class SshProxy : public ExThreadBase
|
||||
{
|
||||
class SshProxy : public ExThreadBase {
|
||||
public:
|
||||
SshProxy() noexcept;
|
||||
|
||||
|
@ -20,7 +19,7 @@ public:
|
|||
|
||||
void set_cfg(ex_u32 noop_timeout);
|
||||
|
||||
void kill_sessions(const ex_astrs &sessions);
|
||||
void kill_sessions(const ex_astrs& sessions);
|
||||
|
||||
protected:
|
||||
void _thread_loop() override;
|
||||
|
@ -29,14 +28,14 @@ protected:
|
|||
|
||||
private:
|
||||
ssh_bind m_bind;
|
||||
int m_timer_counter_check_noop;
|
||||
int m_timer_counter_keep_alive;
|
||||
int m_timer_counter_check_noop;
|
||||
int m_timer_counter_keep_alive;
|
||||
|
||||
ExThreadLock m_lock;
|
||||
bool m_listener_running;
|
||||
bool m_listener_running;
|
||||
|
||||
ex_astr m_host_ip;
|
||||
int m_host_port;
|
||||
int m_host_port;
|
||||
|
||||
ts_ssh_sessions m_sessions;
|
||||
|
||||
|
|
|
@ -67,7 +67,6 @@ void TppSshRec::record(ex_u8 type, const ex_u8* data, size_t size) {
|
|||
_save_to_data_file();
|
||||
|
||||
TS_RECORD_PKG pkg = {0};
|
||||
//memset(&pkg, 0, sizeof(TS_RECORD_PKG));
|
||||
pkg.type = type;
|
||||
pkg.size = (ex_u32) size;
|
||||
|
||||
|
@ -79,9 +78,6 @@ void TppSshRec::record(ex_u8 type, const ex_u8* data, size_t size) {
|
|||
|
||||
m_cache.append((ex_u8*) &pkg, sizeof(TS_RECORD_PKG));
|
||||
m_cache.append(data, size);
|
||||
|
||||
//m_head.info.packages++;
|
||||
//m_header_changed = true;
|
||||
}
|
||||
|
||||
void TppSshRec::record_win_size_startup(int width, int height) {
|
||||
|
@ -100,20 +96,6 @@ void TppSshRec::record_win_size_change(int width, int height) {
|
|||
// 为了录像回放和命令历史能够对应(比如点击命令直接跳到录像的对应时点),仿照录像数据包的方式记录相对时间偏移,而不是绝对时间。
|
||||
void TppSshRec::record_command(int flag, const ex_astr& cmd) {
|
||||
char szTime[100] = {0};
|
||||
#ifdef EX_OS_WIN32
|
||||
// SYSTEMTIME st;
|
||||
// GetLocalTime(&st);
|
||||
// sprintf_s(szTime, 100, "[%04d-%02d-%02d %02d:%02d:%02d %d] ", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, flag);
|
||||
#else
|
||||
// time_t timep;
|
||||
// struct tm *p;
|
||||
// time(&timep);
|
||||
// p = localtime(&timep);
|
||||
// if (p == nullptr)
|
||||
// return;
|
||||
// sprintf(szTime, "[%04d-%02d-%02d %02d:%02d:%02d %d] ", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, flag);
|
||||
#endif
|
||||
|
||||
ex_strformat(szTime, 99, "%d,%d,", (ex_u32) (ex_get_tick_count() - m_start_time), flag);
|
||||
size_t lenTime = strlen(szTime);
|
||||
|
||||
|
|
|
@ -3,46 +3,51 @@
|
|||
|
||||
#include "../../common/base_record.h"
|
||||
|
||||
#define TS_RECORD_TYPE_SSH_TERM_SIZE 0x01 // 终端大小(行数与列数)
|
||||
#define TS_RECORD_TYPE_SSH_DATA 0x02 // 用于展示的数据内容
|
||||
#define TS_RECORD_TYPE_SSH_TERM_SIZE 0x01 // 终端大小(行数与列数)
|
||||
#define TS_RECORD_TYPE_SSH_DATA 0x02 // 用于展示的数据内容
|
||||
|
||||
#pragma pack(push,1)
|
||||
#pragma pack(push, 1)
|
||||
|
||||
// 记录窗口大小改变的数据包
|
||||
typedef struct TS_RECORD_WIN_SIZE
|
||||
{
|
||||
ex_u16 width;
|
||||
ex_u16 height;
|
||||
}TS_RECORD_WIN_SIZE;
|
||||
typedef struct TS_RECORD_WIN_SIZE {
|
||||
ex_u16 width;
|
||||
ex_u16 height;
|
||||
} TS_RECORD_WIN_SIZE;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
class TppSshRec : public TppRecBase
|
||||
{
|
||||
class TppSshRec : public TppRecBase {
|
||||
public:
|
||||
TppSshRec();
|
||||
virtual ~TppSshRec();
|
||||
TppSshRec();
|
||||
|
||||
void record(ex_u8 type, const ex_u8* data, size_t size);
|
||||
void record_win_size_startup(int width, int height);
|
||||
void record_win_size_change(int width, int height);
|
||||
void record_command(int flag, const ex_astr& cmd);
|
||||
virtual ~TppSshRec();
|
||||
|
||||
void record(ex_u8 type, const ex_u8* data, size_t size);
|
||||
|
||||
void record_win_size_startup(int width, int height);
|
||||
|
||||
void record_win_size_change(int width, int height);
|
||||
|
||||
void record_command(int flag, const ex_astr& cmd);
|
||||
|
||||
void save_record();
|
||||
|
||||
protected:
|
||||
bool _on_begin(const TPP_CONNECT_INFO* info);
|
||||
bool _on_end();
|
||||
bool _on_begin(const TPP_CONNECT_INFO* info) override;
|
||||
|
||||
bool _save_to_info_file();
|
||||
bool _save_to_data_file();
|
||||
bool _save_to_cmd_file();
|
||||
bool _on_end() override;
|
||||
|
||||
bool _save_to_info_file();
|
||||
|
||||
bool _save_to_data_file();
|
||||
|
||||
bool _save_to_cmd_file();
|
||||
|
||||
protected:
|
||||
TS_RECORD_HEADER m_head;
|
||||
bool m_header_changed;
|
||||
TS_RECORD_HEADER m_head;
|
||||
bool m_header_changed;
|
||||
|
||||
MemBuffer m_cmd_cache;
|
||||
MemBuffer m_cmd_cache;
|
||||
|
||||
bool m_save_full_header;
|
||||
|
||||
|
|
|
@ -82,8 +82,7 @@ void SshSession::_on_stopped() {
|
|||
void SshSession::_set_last_error(int err_code) {
|
||||
#ifndef TEST_SSH_SESSION_000000
|
||||
int db_id = 0;
|
||||
if (!g_ssh_env.session_begin(m_conn_info, &db_id) || db_id == 0)
|
||||
{
|
||||
if (!g_ssh_env.session_begin(m_conn_info, &db_id) || db_id == 0) {
|
||||
EXLOGE("[%s] can not write session error to database.\n", m_dbg_name.c_str());
|
||||
return;
|
||||
}
|
||||
|
@ -323,7 +322,7 @@ bool SshSession::make_channel_pair(ssh_channel ch_tp2cli, ssh_channel ch_tp2srv)
|
|||
uint32_t dbg_id = m_pair_id++;
|
||||
auto _pair = new SshChannelPair(this, dbg_id, ch_tp2cli, ch_tp2srv);
|
||||
|
||||
if(!_pair->record_begin(m_conn_info)) {
|
||||
if (!_pair->record_begin(m_conn_info)) {
|
||||
delete _pair;
|
||||
return false;
|
||||
}
|
||||
|
@ -784,7 +783,7 @@ int SshSession::_on_client_pty_request(ssh_session /*session*/, ssh_channel chan
|
|||
}
|
||||
|
||||
cp->win_width = x;
|
||||
cp->rec.record_win_size_change(x, y);
|
||||
cp->rec.record_win_size_startup(x, y);
|
||||
|
||||
int rc = ssh_channel_request_pty_size(cp->rsc_tp2srv, term, x, y);
|
||||
while (rc == SSH_AGAIN) {
|
||||
|
|
|
@ -33,8 +33,7 @@ class SshProxy;
|
|||
|
||||
class SshSession;
|
||||
|
||||
class SshSession :
|
||||
public ExThreadBase {
|
||||
class SshSession : public ExThreadBase {
|
||||
public:
|
||||
SshSession(SshProxy* proxy, ssh_session rs_tp2cli, uint32_t dbg_id, const char* client_ip, uint16_t client_port);
|
||||
|
||||
|
|
|
@ -96,8 +96,11 @@ TPP_API ex_rv tpp_command(ex_u32 cmd, const char* param) {
|
|||
return TPE_PARAM;
|
||||
|
||||
switch (cmd) {
|
||||
case TPP_CMD_SET_RUNTIME_CFG:return tpp_cmd_set_runtime_config(param);
|
||||
case TPP_CMD_KILL_SESSIONS:return tpp_cmd_kill_sessions(param);
|
||||
default:return TPE_UNKNOWN_CMD;
|
||||
case TPP_CMD_SET_RUNTIME_CFG:
|
||||
return tpp_cmd_set_runtime_config(param);
|
||||
case TPP_CMD_KILL_SESSIONS:
|
||||
return tpp_cmd_kill_sessions(param);
|
||||
default:
|
||||
return TPE_UNKNOWN_CMD;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,11 +12,12 @@ ex_astr _uv_str_error(int retcode) {
|
|||
return err;
|
||||
}
|
||||
|
||||
TelnetConn::TelnetConn(TelnetSession *sess, bool is_server_side) : m_session(sess), m_is_server(is_server_side) {
|
||||
TelnetConn::TelnetConn(TelnetSession* sess, bool is_server_side) : m_session(sess), m_is_server(is_server_side) {
|
||||
if (is_server_side) {
|
||||
m_name = "cli<->tp";
|
||||
m_state = TELNET_CONN_STATE_CONNECTED;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
m_name = "tp<->srv";
|
||||
m_state = TELNET_CONN_STATE_FREE;
|
||||
}
|
||||
|
@ -29,11 +30,10 @@ TelnetConn::TelnetConn(TelnetSession *sess, bool is_server_side) : m_session(ses
|
|||
m_stop_handle.data = this;
|
||||
}
|
||||
|
||||
TelnetConn::~TelnetConn() {
|
||||
}
|
||||
TelnetConn::~TelnetConn() = default;
|
||||
|
||||
bool TelnetConn::start_recv() {
|
||||
int err = uv_read_start((uv_stream_t *) &m_handle, _on_alloc, _on_recv);
|
||||
int err = uv_read_start((uv_stream_t*) &m_handle, _on_alloc, _on_recv);
|
||||
if (err != 0) {
|
||||
EXLOGE("[telnet] [%s] can not start to read.\n", m_name);
|
||||
m_session->close(TP_SESS_STAT_ERR_IO);
|
||||
|
@ -59,46 +59,46 @@ void TelnetConn::_do_close() {
|
|||
|
||||
EXLOGW("[telnet] [%s] try to close while it connecting.\n", m_name);
|
||||
m_state = TELNET_CONN_STATE_CLOSING;
|
||||
uv_close(handle(), NULL);
|
||||
uv_close(handle(), nullptr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
uv_read_stop((uv_stream_t *) &m_handle);
|
||||
uv_read_stop((uv_stream_t*) &m_handle);
|
||||
uv_close(handle(), _uv_on_closed);
|
||||
}
|
||||
|
||||
//static
|
||||
void TelnetConn::_on_stop_cb(uv_async_t *handle) {
|
||||
TelnetConn *_this = (TelnetConn *) handle->data;
|
||||
uv_close((uv_handle_t *) &_this->m_stop_handle, _this->_on_stop_handler_closed);
|
||||
void TelnetConn::_on_stop_cb(uv_async_t* handle) {
|
||||
auto _this = (TelnetConn*) handle->data;
|
||||
uv_close((uv_handle_t*) &_this->m_stop_handle, _this->_on_stop_handler_closed);
|
||||
}
|
||||
|
||||
//static
|
||||
void TelnetConn::_on_stop_handler_closed(uv_handle_t *handle) {
|
||||
TelnetConn *_this = (TelnetConn *) handle->data;
|
||||
void TelnetConn::_on_stop_handler_closed(uv_handle_t* handle) {
|
||||
auto _this = (TelnetConn*) handle->data;
|
||||
_this->_do_close();
|
||||
}
|
||||
|
||||
void TelnetConn::_uv_on_closed(uv_handle_t *handle) {
|
||||
TelnetConn *_this = (TelnetConn *) handle->data;
|
||||
void TelnetConn::_uv_on_closed(uv_handle_t* handle) {
|
||||
auto _this = (TelnetConn*) handle->data;
|
||||
_this->m_state = TELNET_CONN_STATE_FREE;
|
||||
_this->m_session->on_conn_close();
|
||||
}
|
||||
|
||||
void TelnetConn::_on_alloc(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) {
|
||||
// TelnetConn *_this = (TelnetConn *) handle->data;
|
||||
buf->base = (char *) calloc(1, suggested_size);
|
||||
void TelnetConn::_on_alloc(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
|
||||
buf->base = (char*) calloc(1, suggested_size);
|
||||
buf->len = suggested_size;
|
||||
}
|
||||
|
||||
void TelnetConn::_on_recv(uv_stream_t *handle, ssize_t nread, const uv_buf_t *buf) {
|
||||
TelnetConn *_this = (TelnetConn *) handle->data;
|
||||
void TelnetConn::_on_recv(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) {
|
||||
auto _this = (TelnetConn*) handle->data;
|
||||
|
||||
if (nread == 0) {
|
||||
free(buf->base);
|
||||
return;
|
||||
} else if (nread < 0) {
|
||||
}
|
||||
else if (nread < 0) {
|
||||
free(buf->base);
|
||||
|
||||
if (nread == UV_EOF)
|
||||
|
@ -118,49 +118,50 @@ void TelnetConn::_on_recv(uv_stream_t *handle, ssize_t nread, const uv_buf_t *bu
|
|||
|
||||
_this->m_session->close(TP_SESS_STAT_END);
|
||||
return;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// #ifdef LOG_DATA
|
||||
// if(!_this->m_session->is_relay())
|
||||
// EXLOG_BIN((ex_u8*)buf->base, nread, "[telnet] [%s] RECV %d.", _this->m_name, nread);
|
||||
// #endif
|
||||
}
|
||||
|
||||
_this->m_buf_data.append((ex_u8 *) buf->base, nread);
|
||||
_this->m_buf_data.append((ex_u8*) buf->base, nread);
|
||||
free(buf->base);
|
||||
|
||||
_this->m_session->do_next(_this);
|
||||
}
|
||||
|
||||
bool TelnetConn::send(MemBuffer &mbuf) {
|
||||
bool TelnetConn::send(MemBuffer& mbuf) {
|
||||
return _raw_send(mbuf.data(), mbuf.size());
|
||||
}
|
||||
|
||||
bool TelnetConn::send(const ex_u8 *data, size_t size) {
|
||||
bool TelnetConn::send(const ex_u8* data, size_t size) {
|
||||
return _raw_send(data, size);
|
||||
}
|
||||
|
||||
bool TelnetConn::_raw_send(const ex_u8 *data, size_t size) {
|
||||
bool TelnetConn::_raw_send(const ex_u8* data, size_t size) {
|
||||
// #ifdef LOG_DATA
|
||||
// if (!m_session->is_relay())
|
||||
// EXLOG_BIN(data, size, "[telnet] [%s] SEND %dB.", m_name, size);
|
||||
// #endif
|
||||
|
||||
uv_write_t *w = (uv_write_t *) calloc(1, sizeof(uv_write_t));
|
||||
auto w = (uv_write_t*) calloc(1, sizeof(uv_write_t));
|
||||
|
||||
ex_u8 *_data = (ex_u8 *) calloc(1, size);
|
||||
if (NULL == _data) {
|
||||
auto _data = (ex_u8*) calloc(1, size);
|
||||
if (nullptr == _data) {
|
||||
free(w);
|
||||
EXLOGE("[telnet] alloc buffer %dB failed.\n", size);
|
||||
return false;
|
||||
}
|
||||
memcpy(_data, data, size);
|
||||
|
||||
uv_buf_t *_buf = (uv_buf_t *) calloc(1, sizeof(uv_buf_t));
|
||||
_buf->base = (char *) _data;
|
||||
auto _buf = (uv_buf_t*) calloc(1, sizeof(uv_buf_t));
|
||||
_buf->base = (char*) _data;
|
||||
_buf->len = size;
|
||||
|
||||
w->data = _buf;
|
||||
if (0 == uv_write(w, (uv_stream_t *) &m_handle, _buf, 1, _on_send_done))
|
||||
if (0 == uv_write(w, (uv_stream_t*) &m_handle, _buf, 1, _on_send_done))
|
||||
return true;
|
||||
else {
|
||||
EXLOGE("[telnet] [%s] raw_send() failed.\n", m_name);
|
||||
|
@ -168,8 +169,8 @@ bool TelnetConn::_raw_send(const ex_u8 *data, size_t size) {
|
|||
}
|
||||
}
|
||||
|
||||
void TelnetConn::_on_send_done(uv_write_t *req, int status) {
|
||||
uv_buf_t *_buf = (uv_buf_t *) req->data;
|
||||
void TelnetConn::_on_send_done(uv_write_t* req, int status) {
|
||||
auto _buf = (uv_buf_t*) req->data;
|
||||
free(_buf->base);
|
||||
free(_buf);
|
||||
free(req);
|
||||
|
@ -180,26 +181,31 @@ void TelnetConn::_on_send_done(uv_write_t *req, int status) {
|
|||
}
|
||||
}
|
||||
|
||||
void TelnetConn::connect(const char *server_ip, ex_u16 server_port) {
|
||||
void TelnetConn::connect(const char* server_ip, ex_u16 server_port) {
|
||||
m_server_ip = server_ip;
|
||||
m_server_port = server_port;
|
||||
|
||||
if (m_state == TELNET_CONN_STATE_CONNECTED) {
|
||||
// 当前已经连接上了服务器了,断开重连
|
||||
EXLOGV("[telnet] [%s] [%s] try to disconnect from real TELNET server %s:%d and reconnect.\n", m_name,
|
||||
m_session->client_addr(), server_ip, server_port);
|
||||
EXLOGV(
|
||||
"[telnet] [%s] [%s] try to disconnect from real TELNET server %s:%d and reconnect.\n", m_name,
|
||||
m_session->client_addr(), server_ip, server_port
|
||||
);
|
||||
m_state = TELNET_CONN_STATE_CLOSING;
|
||||
uv_close((uv_handle_t *) &m_handle, _uv_on_reconnect);
|
||||
uv_close((uv_handle_t*) &m_handle, _uv_on_reconnect);
|
||||
return;
|
||||
} else {
|
||||
EXLOGV("[telnet] [%s] [%s] try to connect to real TELNET server %s:%d\n", m_name, m_session->client_addr(),
|
||||
server_ip, server_port);
|
||||
}
|
||||
else {
|
||||
EXLOGV(
|
||||
"[telnet] [%s] [%s] try to connect to real TELNET server %s:%d\n", m_name, m_session->client_addr(),
|
||||
server_ip, server_port
|
||||
);
|
||||
}
|
||||
|
||||
struct sockaddr_in addr;
|
||||
uv_ip4_addr(server_ip, server_port, &addr);
|
||||
|
||||
uv_connect_t *conn_req = (uv_connect_t *) calloc(1, sizeof(uv_connect_t));
|
||||
auto conn_req = (uv_connect_t*) calloc(1, sizeof(uv_connect_t));
|
||||
conn_req->data = this;
|
||||
|
||||
// 设置一个超时回调,如果超时发生时连接尚未完成,就报错
|
||||
|
@ -216,26 +222,26 @@ void TelnetConn::connect(const char *server_ip, ex_u16 server_port) {
|
|||
|
||||
m_state = TELNET_CONN_STATE_CONNECTING;
|
||||
int err = 0;
|
||||
if ((err = uv_tcp_connect(conn_req, &m_handle, (const struct sockaddr *) &addr, _uv_on_connected)) != 0) {
|
||||
if ((err = uv_tcp_connect(conn_req, &m_handle, (const struct sockaddr*) &addr, _uv_on_connected)) != 0) {
|
||||
free(conn_req);
|
||||
EXLOGE("[telnet] [%s] can not connect to server: %s\n", m_name, uv_strerror(err));
|
||||
|
||||
m_timer_running = false;
|
||||
uv_timer_stop(&m_timer_connect_timeout);
|
||||
uv_close((uv_handle_t *) &m_timer_connect_timeout, NULL);
|
||||
uv_close((uv_handle_t*) &m_timer_connect_timeout, nullptr);
|
||||
|
||||
m_state = TELNET_CONN_STATE_FREE;
|
||||
m_session->close(TP_SESS_STAT_ERR_CONNECT);
|
||||
}
|
||||
}
|
||||
|
||||
void TelnetConn::_uv_on_connect_timeout(uv_timer_t *timer) {
|
||||
TelnetConn *_this = (TelnetConn *) timer->data;
|
||||
void TelnetConn::_uv_on_connect_timeout(uv_timer_t* timer) {
|
||||
auto _this = (TelnetConn*) timer->data;
|
||||
|
||||
if (_this->m_timer_running) {
|
||||
_this->m_timer_running = false;
|
||||
uv_timer_stop(&_this->m_timer_connect_timeout);
|
||||
uv_close((uv_handle_t *) &_this->m_timer_connect_timeout, NULL);
|
||||
uv_close((uv_handle_t*) &_this->m_timer_connect_timeout, nullptr);
|
||||
}
|
||||
|
||||
// 如果在连接成功之前就超时了,则关闭连接
|
||||
|
@ -244,8 +250,8 @@ void TelnetConn::_uv_on_connect_timeout(uv_timer_t *timer) {
|
|||
uv_close(_this->handle(), _uv_on_closed);
|
||||
}
|
||||
|
||||
void TelnetConn::_uv_on_reconnect(uv_handle_t *handle) {
|
||||
TelnetConn *_this = (TelnetConn *) handle->data;
|
||||
void TelnetConn::_uv_on_reconnect(uv_handle_t* handle) {
|
||||
auto _this = (TelnetConn*) handle->data;
|
||||
_this->m_state = TELNET_CONN_STATE_FREE;
|
||||
|
||||
uv_tcp_init(_this->m_session->get_loop(), &_this->m_handle);
|
||||
|
@ -254,14 +260,14 @@ void TelnetConn::_uv_on_reconnect(uv_handle_t *handle) {
|
|||
_this->connect(_this->m_server_ip.c_str(), _this->m_server_port);
|
||||
}
|
||||
|
||||
void TelnetConn::_uv_on_connected(uv_connect_t *req, int status) {
|
||||
TelnetConn *_this = (TelnetConn *) req->data;
|
||||
void TelnetConn::_uv_on_connected(uv_connect_t* req, int status) {
|
||||
auto _this = (TelnetConn*) req->data;
|
||||
free(req);
|
||||
|
||||
if (_this->m_timer_running) {
|
||||
_this->m_timer_running = false;
|
||||
uv_timer_stop(&_this->m_timer_connect_timeout);
|
||||
uv_close((uv_handle_t *) &_this->m_timer_connect_timeout, NULL);
|
||||
uv_close((uv_handle_t*) &_this->m_timer_connect_timeout, nullptr);
|
||||
}
|
||||
|
||||
if (status != 0) {
|
||||
|
|
|
@ -18,33 +18,33 @@ class TelnetSession;
|
|||
|
||||
class TelnetConn {
|
||||
public:
|
||||
TelnetConn(TelnetSession *sess, bool is_server_side);
|
||||
TelnetConn(TelnetSession* sess, bool is_server_side);
|
||||
|
||||
~TelnetConn();
|
||||
|
||||
TelnetSession *session() { return m_session; }
|
||||
TelnetSession* session() { return m_session; }
|
||||
|
||||
// just for debug-info
|
||||
const char *name() const { return m_name; }
|
||||
const char* name() const { return m_name; }
|
||||
|
||||
bool is_server_side() const { return m_is_server; }
|
||||
|
||||
ex_u8 state() const { return m_state; }
|
||||
|
||||
uv_handle_t *handle() { return (uv_handle_t *) &m_handle; }
|
||||
uv_handle_t* handle() { return (uv_handle_t*) &m_handle; }
|
||||
|
||||
uv_tcp_t *tcp_handle() { return &m_handle; }
|
||||
uv_tcp_t* tcp_handle() { return &m_handle; }
|
||||
|
||||
uv_stream_t *stream_handle() { return (uv_stream_t *) &m_handle; }
|
||||
uv_stream_t* stream_handle() { return (uv_stream_t*) &m_handle; }
|
||||
|
||||
MemBuffer &data() { return m_buf_data; }
|
||||
MemBuffer& data() { return m_buf_data; }
|
||||
|
||||
bool send(MemBuffer &mbuf);
|
||||
bool send(MemBuffer& mbuf);
|
||||
|
||||
bool send(const ex_u8 *data, size_t size);
|
||||
bool send(const ex_u8* data, size_t size);
|
||||
|
||||
// connect to real server, for proxy-client-side only.
|
||||
void connect(const char *server_ip, ex_u16 server_port = 3389);
|
||||
void connect(const char* server_ip, ex_u16 server_port = 3389);
|
||||
|
||||
// try to close this connection. return current TELNET_CONN_STATE_XXXX.
|
||||
void close();
|
||||
|
@ -52,35 +52,35 @@ public:
|
|||
bool start_recv();
|
||||
|
||||
private:
|
||||
static void _on_alloc(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf);
|
||||
static void _on_alloc(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf);
|
||||
|
||||
static void _on_recv(uv_stream_t *handle, ssize_t nread, const uv_buf_t *buf);
|
||||
static void _on_recv(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf);
|
||||
|
||||
static void _on_send_done(uv_write_t *req, int status);
|
||||
static void _on_send_done(uv_write_t* req, int status);
|
||||
|
||||
static void _uv_on_connect_timeout(uv_timer_t *timer);
|
||||
static void _uv_on_connect_timeout(uv_timer_t* timer);
|
||||
|
||||
static void _uv_on_connected(uv_connect_t *req, int status);
|
||||
static void _uv_on_connected(uv_connect_t* req, int status);
|
||||
|
||||
static void _uv_on_reconnect(uv_handle_t *handle);
|
||||
static void _uv_on_reconnect(uv_handle_t* handle);
|
||||
|
||||
static void _uv_on_closed(uv_handle_t *handle);
|
||||
static void _uv_on_closed(uv_handle_t* handle);
|
||||
|
||||
// static void _uv_on_timer_connect_timeout_closed(uv_handle_t *handle);
|
||||
static void _on_stop_cb(uv_async_t *handle);
|
||||
static void _on_stop_cb(uv_async_t* handle);
|
||||
|
||||
static void _on_stop_handler_closed(uv_handle_t *handle);
|
||||
static void _on_stop_handler_closed(uv_handle_t* handle);
|
||||
|
||||
void _do_close();
|
||||
|
||||
bool _raw_send(const ex_u8 *data, size_t size);
|
||||
bool _raw_send(const ex_u8* data, size_t size);
|
||||
|
||||
private:
|
||||
TelnetSession *m_session;
|
||||
TelnetSession* m_session;
|
||||
bool m_is_server;
|
||||
|
||||
// for debug-info.
|
||||
const char *m_name;
|
||||
const char* m_name;
|
||||
|
||||
uv_tcp_t m_handle;
|
||||
uv_timer_t m_timer_connect_timeout;
|
||||
|
|
|
@ -46,8 +46,8 @@ void TelnetProxy::timer() {
|
|||
m_timer_counter = 0;
|
||||
|
||||
ExThreadSmartLock locker(m_lock);
|
||||
ex_u32 t_now = (ex_u32) time(NULL);
|
||||
ts_telnet_sessions::iterator it = m_sessions.begin();
|
||||
auto t_now = (ex_u32) time(nullptr);
|
||||
auto it = m_sessions.begin();
|
||||
for (; it != m_sessions.end(); ++it) {
|
||||
it->first->save_record();
|
||||
if (0 != m_noop_timeout_sec)
|
||||
|
@ -59,9 +59,9 @@ void TelnetProxy::set_cfg(ex_u32 noop_timeout) {
|
|||
m_noop_timeout_sec = noop_timeout;
|
||||
}
|
||||
|
||||
void TelnetProxy::kill_sessions(const ex_astrs &sessions) {
|
||||
void TelnetProxy::kill_sessions(const ex_astrs& sessions) {
|
||||
ExThreadSmartLock locker(m_lock);
|
||||
ts_telnet_sessions::iterator it = m_sessions.begin();
|
||||
auto it = m_sessions.begin();
|
||||
for (; it != m_sessions.end(); ++it) {
|
||||
for (size_t i = 0; i < sessions.size(); ++i) {
|
||||
if (it->first->sid() == sessions[i]) {
|
||||
|
@ -72,20 +72,20 @@ void TelnetProxy::kill_sessions(const ex_astrs &sessions) {
|
|||
}
|
||||
}
|
||||
|
||||
void TelnetProxy::_thread_loop(void) {
|
||||
void TelnetProxy::_thread_loop() {
|
||||
struct sockaddr_in addr;
|
||||
if (0 != uv_ip4_addr(m_host_ip.c_str(), m_host_port, &addr)) {
|
||||
EXLOGE("[telnet] invalid ip/port for TELNET listener.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (0 != uv_tcp_bind(&m_listener_handle, (const struct sockaddr *) &addr, 0)) {
|
||||
if (0 != uv_tcp_bind(&m_listener_handle, (const struct sockaddr*) &addr, 0)) {
|
||||
EXLOGE("[telnet] can not bind %s:%d.\n", m_host_ip.c_str(), m_host_port);
|
||||
return;
|
||||
}
|
||||
|
||||
// 开始监听,有客户端连接到来时,会回调 _on_client_connect()
|
||||
if (0 != uv_listen((uv_stream_t *) &m_listener_handle, 8, _on_client_connect)) {
|
||||
if (0 != uv_listen((uv_stream_t*) &m_listener_handle, 8, _on_client_connect)) {
|
||||
EXLOGE("[telnet] can not listen on %s:%d.\n", m_host_ip.c_str(), m_host_port);
|
||||
return;
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ void TelnetProxy::_thread_loop(void) {
|
|||
}
|
||||
|
||||
// static
|
||||
void TelnetProxy::_on_stop(void) {
|
||||
void TelnetProxy::_on_stop() {
|
||||
ExThreadBase::_on_stop();
|
||||
|
||||
if (m_is_running) {
|
||||
|
@ -123,19 +123,18 @@ void TelnetProxy::_on_stop(void) {
|
|||
}
|
||||
|
||||
// static
|
||||
void TelnetProxy::_on_listener_closed(uv_handle_t *handle) {
|
||||
TelnetProxy *_this = (TelnetProxy *) handle->data;
|
||||
void TelnetProxy::_on_listener_closed(uv_handle_t* handle) {
|
||||
auto _this = (TelnetProxy*) handle->data;
|
||||
EXLOGV("[telnet] listener close.\n");
|
||||
|
||||
uv_close((uv_handle_t *) &_this->m_stop_handle, _on_stop_handle_closed);
|
||||
// _this->_close_all_sessions();
|
||||
uv_close((uv_handle_t*) &_this->m_stop_handle, _on_stop_handle_closed);
|
||||
}
|
||||
|
||||
void TelnetProxy::clean_session() {
|
||||
uv_async_send(&m_clean_session_handle);
|
||||
}
|
||||
|
||||
void TelnetProxy::_close_all_sessions(void) {
|
||||
void TelnetProxy::_close_all_sessions() {
|
||||
ExThreadSmartLock locker(m_lock);
|
||||
|
||||
if (m_sessions.empty()) {
|
||||
|
@ -143,26 +142,27 @@ void TelnetProxy::_close_all_sessions(void) {
|
|||
return;
|
||||
}
|
||||
|
||||
ts_telnet_sessions::iterator it = m_sessions.begin();
|
||||
auto it = m_sessions.begin();
|
||||
for (; it != m_sessions.end(); ++it) {
|
||||
it->first->close(TP_SESS_STAT_ERR_RESET);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void TelnetProxy::_on_clean_session_cb(uv_async_t *handle) {
|
||||
TelnetProxy *_this = (TelnetProxy *) handle->data;
|
||||
void TelnetProxy::_on_clean_session_cb(uv_async_t* handle) {
|
||||
auto _this = (TelnetProxy*) handle->data;
|
||||
|
||||
// check closed session
|
||||
ExThreadSmartLock locker(_this->m_lock);
|
||||
|
||||
ts_telnet_sessions::iterator it = _this->m_sessions.begin();
|
||||
auto it = _this->m_sessions.begin();
|
||||
for (; it != _this->m_sessions.end();) {
|
||||
if (it->first->is_closed()) {
|
||||
delete it->first;
|
||||
_this->m_sessions.erase(it++);
|
||||
EXLOGD("[telnet] - removed one session.\n");
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
@ -177,29 +177,29 @@ void TelnetProxy::_on_clean_session_cb(uv_async_t *handle) {
|
|||
//}
|
||||
|
||||
//static
|
||||
void TelnetProxy::_on_stop_handle_closed(uv_handle_t *handle) {
|
||||
TelnetProxy *_this = (TelnetProxy *) handle->data;
|
||||
void TelnetProxy::_on_stop_handle_closed(uv_handle_t* handle) {
|
||||
auto _this = (TelnetProxy*) handle->data;
|
||||
_this->_close_all_sessions();
|
||||
}
|
||||
|
||||
//static
|
||||
void TelnetProxy::_on_stop_cb(uv_async_t *handle) {
|
||||
TelnetProxy *_this = (TelnetProxy *) handle->data;
|
||||
uv_close((uv_handle_t *) &_this->m_listener_handle, _on_listener_closed);
|
||||
void TelnetProxy::_on_stop_cb(uv_async_t* handle) {
|
||||
auto _this = (TelnetProxy*) handle->data;
|
||||
uv_close((uv_handle_t*) &_this->m_listener_handle, _on_listener_closed);
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void TelnetProxy::_on_client_connect(uv_stream_t *server, int status) {
|
||||
void TelnetProxy::_on_client_connect(uv_stream_t* server, int status) {
|
||||
if (0 != status)
|
||||
return;
|
||||
|
||||
TelnetProxy *_this = (TelnetProxy *) server->data;
|
||||
auto _this = (TelnetProxy*) server->data;
|
||||
_this->_on_accept(server);
|
||||
}
|
||||
|
||||
bool TelnetProxy::_on_accept(uv_stream_t *server) {
|
||||
TelnetSession *sess = new TelnetSession(this);
|
||||
bool TelnetProxy::_on_accept(uv_stream_t* server) {
|
||||
auto sess = new TelnetSession(this);
|
||||
|
||||
if (0 != uv_accept(server, sess->client()->stream_handle())) {
|
||||
EXLOGE("[telnet] socket accept failed.\n");
|
||||
|
@ -216,7 +216,7 @@ bool TelnetProxy::_on_accept(uv_stream_t *server) {
|
|||
struct sockaddr sock_client;
|
||||
int namelen = sizeof(sock_client);
|
||||
if (0 == uv_tcp_getpeername(sess->client()->tcp_handle(), &sock_client, &namelen)) {
|
||||
sockaddr_in *addrin = (sockaddr_in *) &sock_client;
|
||||
auto addrin = (sockaddr_in*) &sock_client;
|
||||
char ip[17] = {0};
|
||||
if (0 == uv_ip4_name(addrin, ip, sizeof(ip))) {
|
||||
char client_addr[64] = {0};
|
||||
|
@ -238,5 +238,5 @@ bool TelnetProxy::_on_accept(uv_stream_t *server) {
|
|||
}
|
||||
|
||||
void TelnetProxy::_close_clean_session_handle() {
|
||||
uv_close((uv_handle_t *) &m_clean_session_handle, NULL);
|
||||
uv_close((uv_handle_t*) &m_clean_session_handle, nullptr);
|
||||
}
|
||||
|
|
|
@ -27,9 +27,9 @@ public:
|
|||
void clean_session();
|
||||
|
||||
protected:
|
||||
void _thread_loop();
|
||||
void _thread_loop() override;
|
||||
|
||||
void _on_stop();
|
||||
void _on_stop() override;
|
||||
|
||||
void _close_all_sessions();
|
||||
|
||||
|
|
|
@ -1,197 +1,173 @@
|
|||
#include "telnet_recorder.h"
|
||||
|
||||
static ex_u8 TPP_RECORD_MAGIC[4] = { 'T', 'P', 'P', 'R' };
|
||||
static ex_u8 TPP_RECORD_MAGIC[4] = {'T', 'P', 'P', 'R'};
|
||||
|
||||
TppTelnetRec::TppTelnetRec()
|
||||
{
|
||||
m_cmd_cache.reserve(MAX_SIZE_PER_FILE);
|
||||
TppTelnetRec::TppTelnetRec() {
|
||||
m_cmd_cache.reserve(MAX_SIZE_PER_FILE);
|
||||
|
||||
memset(&m_head, 0, sizeof(TS_RECORD_HEADER));
|
||||
memcpy((ex_u8*)(&m_head.info.magic), TPP_RECORD_MAGIC, sizeof(ex_u32));
|
||||
m_head.info.ver = 0x04;
|
||||
m_header_changed = false;
|
||||
m_save_full_header = false;
|
||||
memset(&m_head, 0, sizeof(TS_RECORD_HEADER));
|
||||
memcpy((ex_u8*) (&m_head.info.magic), TPP_RECORD_MAGIC, sizeof(ex_u32));
|
||||
m_head.info.ver = 0x04;
|
||||
m_header_changed = false;
|
||||
m_save_full_header = false;
|
||||
|
||||
m_file_info = NULL;
|
||||
m_file_data = NULL;
|
||||
m_file_cmd = NULL;
|
||||
m_file_info = nullptr;
|
||||
m_file_data = nullptr;
|
||||
m_file_cmd = nullptr;
|
||||
}
|
||||
|
||||
TppTelnetRec::~TppTelnetRec()
|
||||
{
|
||||
end();
|
||||
TppTelnetRec::~TppTelnetRec() {
|
||||
end();
|
||||
}
|
||||
|
||||
bool TppTelnetRec::_on_begin(const TPP_CONNECT_INFO* info)
|
||||
{
|
||||
if (NULL == info)
|
||||
return false;
|
||||
m_head.basic.timestamp = (ex_u64)time(NULL);
|
||||
m_head.basic.protocol_type = (ex_u16)info->protocol_type;
|
||||
m_head.basic.protocol_sub_type = (ex_u16)info->protocol_sub_type;
|
||||
m_head.basic.conn_port = (ex_u16)info->conn_port;
|
||||
bool TppTelnetRec::_on_begin(const TPP_CONNECT_INFO* info) {
|
||||
if (nullptr == info)
|
||||
return false;
|
||||
m_head.basic.timestamp = (ex_u64) time(nullptr);
|
||||
m_head.basic.protocol_type = (ex_u16) info->protocol_type;
|
||||
m_head.basic.protocol_sub_type = (ex_u16) info->protocol_sub_type;
|
||||
m_head.basic.conn_port = (ex_u16) info->conn_port;
|
||||
|
||||
memcpy(m_head.basic.acc_username, info->acc_username, strlen(info->acc_username) >= 63 ? 63 : strlen(info->acc_username));
|
||||
memcpy(m_head.basic.user_username, info->user_username, strlen(info->user_username) >= 63 ? 63 : strlen(info->user_username));
|
||||
memcpy(m_head.basic.host_ip, info->host_ip, strlen(info->host_ip) >= 39 ? 39 : strlen(info->host_ip));
|
||||
memcpy(m_head.basic.conn_ip, info->conn_ip, strlen(info->conn_ip) >= 39 ? 39 : strlen(info->conn_ip));
|
||||
memcpy(m_head.basic.client_ip, info->client_ip, strlen(info->client_ip) >= 39 ? 39 : strlen(info->client_ip));
|
||||
memcpy(m_head.basic.acc_username, info->acc_username, strlen(info->acc_username) >= 63 ? 63 : strlen(info->acc_username));
|
||||
memcpy(m_head.basic.user_username, info->user_username, strlen(info->user_username) >= 63 ? 63 : strlen(info->user_username));
|
||||
memcpy(m_head.basic.host_ip, info->host_ip, strlen(info->host_ip) >= 39 ? 39 : strlen(info->host_ip));
|
||||
memcpy(m_head.basic.conn_ip, info->conn_ip, strlen(info->conn_ip) >= 39 ? 39 : strlen(info->conn_ip));
|
||||
memcpy(m_head.basic.client_ip, info->client_ip, strlen(info->client_ip) >= 39 ? 39 : strlen(info->client_ip));
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TppTelnetRec::_on_end()
|
||||
{
|
||||
// 如果还有剩下未写入的数据,写入文件中。
|
||||
save_record();
|
||||
bool TppTelnetRec::_on_end() {
|
||||
// 如果还有剩下未写入的数据,写入文件中。
|
||||
save_record();
|
||||
|
||||
if (m_file_info != NULL)
|
||||
fclose(m_file_info);
|
||||
if (m_file_data != NULL)
|
||||
fclose(m_file_data);
|
||||
if (m_file_cmd != NULL)
|
||||
fclose(m_file_cmd);
|
||||
if (m_file_info != nullptr)
|
||||
fclose(m_file_info);
|
||||
if (m_file_data != nullptr)
|
||||
fclose(m_file_data);
|
||||
if (m_file_cmd != nullptr)
|
||||
fclose(m_file_cmd);
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void TppTelnetRec::save_record() {
|
||||
_save_to_data_file();
|
||||
_save_to_cmd_file();
|
||||
_save_to_data_file();
|
||||
_save_to_cmd_file();
|
||||
}
|
||||
|
||||
void TppTelnetRec::record(ex_u8 type, const ex_u8* data, size_t size)
|
||||
{
|
||||
if (data == NULL || 0 == size)
|
||||
return;
|
||||
void TppTelnetRec::record(ex_u8 type, const ex_u8* data, size_t size) {
|
||||
if (data == nullptr || 0 == size)
|
||||
return;
|
||||
|
||||
if (sizeof(TS_RECORD_PKG) + size + m_cache.size() > MAX_SIZE_PER_FILE)
|
||||
_save_to_data_file();
|
||||
if (sizeof(TS_RECORD_PKG) + size + m_cache.size() > MAX_SIZE_PER_FILE)
|
||||
_save_to_data_file();
|
||||
|
||||
TS_RECORD_PKG pkg = { 0 };
|
||||
pkg.type = type;
|
||||
pkg.size = (ex_u32)size;
|
||||
TS_RECORD_PKG pkg = {0};
|
||||
pkg.type = type;
|
||||
pkg.size = (ex_u32) size;
|
||||
|
||||
if (m_start_time > 0)
|
||||
{
|
||||
pkg.time_ms = (ex_u32)(ex_get_tick_count() - m_start_time);
|
||||
m_head.info.time_ms = pkg.time_ms;
|
||||
m_header_changed = true;
|
||||
}
|
||||
if (m_start_time > 0) {
|
||||
pkg.time_ms = (ex_u32) (ex_get_tick_count() - m_start_time);
|
||||
m_head.info.time_ms = pkg.time_ms;
|
||||
m_header_changed = true;
|
||||
}
|
||||
|
||||
m_cache.append((ex_u8*)&pkg, sizeof(TS_RECORD_PKG));
|
||||
m_cache.append(data, size);
|
||||
|
||||
// m_head.info.packages++;
|
||||
// m_header_changed = true;
|
||||
m_cache.append((ex_u8*) &pkg, sizeof(TS_RECORD_PKG));
|
||||
m_cache.append(data, size);
|
||||
}
|
||||
|
||||
// void TppTelnetRec::record_win_size(int width, int height)
|
||||
// {
|
||||
// m_head.basic.width = (ex_u16)width;
|
||||
// m_head.basic.height = (ex_u16)height;
|
||||
// m_save_full_header = true;
|
||||
// m_header_changed = true;
|
||||
// }
|
||||
|
||||
void TppTelnetRec::record_win_size_startup(int width, int height)
|
||||
{
|
||||
m_head.basic.width = (ex_u16)width;
|
||||
m_head.basic.height = (ex_u16)height;
|
||||
m_save_full_header = true;
|
||||
void TppTelnetRec::record_win_size_startup(int width, int height) {
|
||||
m_head.basic.width = (ex_u16) width;
|
||||
m_head.basic.height = (ex_u16) height;
|
||||
m_save_full_header = true;
|
||||
}
|
||||
|
||||
void TppTelnetRec::record_win_size_change(int width, int height)
|
||||
{
|
||||
TS_RECORD_WIN_SIZE pkg = { 0 };
|
||||
pkg.width = (ex_u16)width;
|
||||
pkg.height = (ex_u16)height;
|
||||
record(TS_RECORD_TYPE_TELNET_TERM_SIZE, (ex_u8*)&pkg, sizeof(TS_RECORD_WIN_SIZE));
|
||||
void TppTelnetRec::record_win_size_change(int width, int height) {
|
||||
TS_RECORD_WIN_SIZE pkg = {0};
|
||||
pkg.width = (ex_u16) width;
|
||||
pkg.height = (ex_u16) height;
|
||||
record(TS_RECORD_TYPE_TELNET_TERM_SIZE, (ex_u8*) &pkg, sizeof(TS_RECORD_WIN_SIZE));
|
||||
}
|
||||
|
||||
bool TppTelnetRec::_save_to_info_file() {
|
||||
if (!m_header_changed)
|
||||
return true;
|
||||
if (!m_header_changed)
|
||||
return true;
|
||||
|
||||
if (m_file_info == NULL) {
|
||||
ex_wstr fname = m_base_path;
|
||||
ex_path_join(fname, false, m_base_fname.c_str(), NULL);
|
||||
fname += L".tpr";
|
||||
if (m_file_info == nullptr) {
|
||||
ex_wstr fname = m_base_path;
|
||||
ex_path_join(fname, false, m_base_fname.c_str(), nullptr);
|
||||
fname += L".tpr";
|
||||
|
||||
m_file_info = ex_fopen(fname, L"wb");
|
||||
if (NULL == m_file_info)
|
||||
{
|
||||
EXLOGE("[ssh] can not open record info-file for write.\n");
|
||||
return false;
|
||||
}
|
||||
m_file_info = ex_fopen(fname, L"wb");
|
||||
if (nullptr == m_file_info) {
|
||||
EXLOGE("[ssh] can not open record info-file for write.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// first time to save header, write whole header.
|
||||
m_save_full_header = true;
|
||||
}
|
||||
// first time to save header, write whole header.
|
||||
m_save_full_header = true;
|
||||
}
|
||||
|
||||
fseek(m_file_info, 0L, SEEK_SET);
|
||||
if (m_save_full_header) {
|
||||
fwrite(&m_head, ts_record_header_size, 1, m_file_info);
|
||||
fflush(m_file_info);
|
||||
m_save_full_header = false;
|
||||
}
|
||||
else {
|
||||
fwrite(&m_head.info, ts_record_header_info_size, 1, m_file_info);
|
||||
fflush(m_file_info);
|
||||
}
|
||||
fseek(m_file_info, 0L, SEEK_SET);
|
||||
if (m_save_full_header) {
|
||||
fwrite(&m_head, ts_record_header_size, 1, m_file_info);
|
||||
fflush(m_file_info);
|
||||
m_save_full_header = false;
|
||||
}
|
||||
else {
|
||||
fwrite(&m_head.info, ts_record_header_info_size, 1, m_file_info);
|
||||
fflush(m_file_info);
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TppTelnetRec::_save_to_data_file()
|
||||
{
|
||||
if (m_cache.size() == 0)
|
||||
return true;
|
||||
bool TppTelnetRec::_save_to_data_file() {
|
||||
if (m_cache.size() == 0)
|
||||
return true;
|
||||
|
||||
if (m_file_data == NULL) {
|
||||
ex_wstr fname = m_base_path;
|
||||
ex_path_join(fname, false, m_base_fname.c_str(), NULL);
|
||||
fname += L".dat";
|
||||
if (m_file_data == nullptr) {
|
||||
ex_wstr fname = m_base_path;
|
||||
ex_path_join(fname, false, m_base_fname.c_str(), nullptr);
|
||||
fname += L".dat";
|
||||
|
||||
m_file_data = ex_fopen(fname, L"wb");
|
||||
if (NULL == m_file_data)
|
||||
{
|
||||
EXLOGE("[ssh] can not open record data-file for write.\n");
|
||||
return false;
|
||||
}
|
||||
m_file_data = ex_fopen(fname, L"wb");
|
||||
if (nullptr == m_file_data) {
|
||||
EXLOGE("[ssh] can not open record data-file for write.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_header_changed = true;
|
||||
}
|
||||
m_header_changed = true;
|
||||
}
|
||||
|
||||
fwrite(m_cache.data(), m_cache.size(), 1, m_file_data);
|
||||
fflush(m_file_data);
|
||||
m_cache.empty();
|
||||
fwrite(m_cache.data(), m_cache.size(), 1, m_file_data);
|
||||
fflush(m_file_data);
|
||||
m_cache.empty();
|
||||
|
||||
return _save_to_info_file();
|
||||
return _save_to_info_file();
|
||||
}
|
||||
|
||||
bool TppTelnetRec::_save_to_cmd_file()
|
||||
{
|
||||
if (m_cmd_cache.size() == 0)
|
||||
return true;
|
||||
bool TppTelnetRec::_save_to_cmd_file() {
|
||||
if (m_cmd_cache.size() == 0)
|
||||
return true;
|
||||
|
||||
if (NULL == m_file_cmd) {
|
||||
ex_wstr fname = m_base_path;
|
||||
ex_path_join(fname, false, m_base_fname.c_str(), NULL);
|
||||
fname += L"-cmd.txt";
|
||||
m_file_cmd = ex_fopen(fname, L"wb");
|
||||
if (NULL == m_file_cmd)
|
||||
{
|
||||
EXLOGE("[ssh] can not open record cmd-file for write.\n");
|
||||
return false;
|
||||
}
|
||||
if (nullptr == m_file_cmd) {
|
||||
ex_wstr fname = m_base_path;
|
||||
ex_path_join(fname, false, m_base_fname.c_str(), nullptr);
|
||||
fname += L"-cmd.txt";
|
||||
m_file_cmd = ex_fopen(fname, L"wb");
|
||||
if (nullptr == m_file_cmd) {
|
||||
EXLOGE("[ssh] can not open record cmd-file for write.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_header_changed = true;
|
||||
}
|
||||
m_header_changed = true;
|
||||
}
|
||||
|
||||
fwrite(m_cmd_cache.data(), m_cmd_cache.size(), 1, m_file_cmd);
|
||||
fflush(m_file_cmd);
|
||||
m_cmd_cache.empty();
|
||||
fwrite(m_cmd_cache.data(), m_cmd_cache.size(), 1, m_file_cmd);
|
||||
fflush(m_file_cmd);
|
||||
m_cmd_cache.empty();
|
||||
|
||||
return _save_to_info_file();
|
||||
return _save_to_info_file();
|
||||
}
|
||||
|
|
|
@ -1,54 +1,58 @@
|
|||
#ifndef __TELNET_RECORDER_H__
|
||||
#define __TELNET_RECORDER_H__
|
||||
|
||||
#include "../../common/base_record.h"
|
||||
|
||||
#define TS_RECORD_TYPE_TELNET_TERM_SIZE 0x01 // 终端大小(行数与列数)
|
||||
#define TS_RECORD_TYPE_TELNET_DATA 0x02 // 用于展示的数据内容
|
||||
|
||||
#pragma pack(push,1)
|
||||
|
||||
// 记录窗口大小改变的数据包
|
||||
typedef struct TS_RECORD_WIN_SIZE
|
||||
{
|
||||
ex_u16 width;
|
||||
ex_u16 height;
|
||||
}TS_RECORD_WIN_SIZE;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
class TppTelnetRec : public TppRecBase
|
||||
{
|
||||
public:
|
||||
TppTelnetRec();
|
||||
virtual ~TppTelnetRec();
|
||||
|
||||
void record(ex_u8 type, const ex_u8* data, size_t size);
|
||||
// void record_win_size(int width, int height);
|
||||
void record_win_size_startup(int width, int height);
|
||||
void record_win_size_change(int width, int height);
|
||||
|
||||
void save_record();
|
||||
|
||||
protected:
|
||||
bool _on_begin(const TPP_CONNECT_INFO* info);
|
||||
bool _on_end();
|
||||
|
||||
bool _save_to_info_file();
|
||||
bool _save_to_data_file();
|
||||
bool _save_to_cmd_file();
|
||||
|
||||
protected:
|
||||
TS_RECORD_HEADER m_head;
|
||||
bool m_header_changed;
|
||||
|
||||
MemBuffer m_cmd_cache;
|
||||
|
||||
bool m_save_full_header;
|
||||
|
||||
FILE* m_file_info;
|
||||
FILE* m_file_data;
|
||||
FILE* m_file_cmd;
|
||||
};
|
||||
|
||||
#endif // __TELNET_RECORDER_H__
|
||||
#ifndef __TELNET_RECORDER_H__
|
||||
#define __TELNET_RECORDER_H__
|
||||
|
||||
#include "../../common/base_record.h"
|
||||
|
||||
#define TS_RECORD_TYPE_TELNET_TERM_SIZE 0x01 // 终端大小(行数与列数)
|
||||
#define TS_RECORD_TYPE_TELNET_DATA 0x02 // 用于展示的数据内容
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
// 记录窗口大小改变的数据包
|
||||
typedef struct TS_RECORD_WIN_SIZE {
|
||||
ex_u16 width;
|
||||
ex_u16 height;
|
||||
} TS_RECORD_WIN_SIZE;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
class TppTelnetRec : public TppRecBase {
|
||||
public:
|
||||
TppTelnetRec();
|
||||
|
||||
virtual ~TppTelnetRec();
|
||||
|
||||
void record(ex_u8 type, const ex_u8* data, size_t size);
|
||||
|
||||
// void record_win_size(int width, int height);
|
||||
void record_win_size_startup(int width, int height);
|
||||
|
||||
void record_win_size_change(int width, int height);
|
||||
|
||||
void save_record();
|
||||
|
||||
protected:
|
||||
bool _on_begin(const TPP_CONNECT_INFO* info) override;
|
||||
|
||||
bool _on_end() override;
|
||||
|
||||
bool _save_to_info_file();
|
||||
|
||||
bool _save_to_data_file();
|
||||
|
||||
bool _save_to_cmd_file();
|
||||
|
||||
protected:
|
||||
TS_RECORD_HEADER m_head;
|
||||
bool m_header_changed;
|
||||
|
||||
MemBuffer m_cmd_cache;
|
||||
|
||||
bool m_save_full_header;
|
||||
|
||||
FILE* m_file_info;
|
||||
FILE* m_file_data;
|
||||
FILE* m_file_cmd;
|
||||
};
|
||||
|
||||
#endif // __TELNET_RECORDER_H__
|
||||
|
|
|
@ -3,25 +3,25 @@
|
|||
#include "tpp_env.h"
|
||||
#include <teleport_const.h>
|
||||
|
||||
#define TELNET_IAC 0xFF
|
||||
#define TELNET_DONT 0xFE
|
||||
#define TELNET_DO 0xFD
|
||||
#define TELNET_WONT 0xFC
|
||||
#define TELNET_WILL 0xFB
|
||||
#define TELNET_SB 0xFA
|
||||
#define TELNET_SE 0xF0
|
||||
#define TELNET_IAC 0xFF
|
||||
#define TELNET_DONT 0xFE
|
||||
#define TELNET_DO 0xFD
|
||||
#define TELNET_WONT 0xFC
|
||||
#define TELNET_WILL 0xFB
|
||||
#define TELNET_SB 0xFA
|
||||
#define TELNET_SE 0xF0
|
||||
|
||||
|
||||
TelnetSession::TelnetSession(TelnetProxy *proxy) :
|
||||
TelnetSession::TelnetSession(TelnetProxy* proxy) :
|
||||
m_proxy(proxy),
|
||||
m_conn_info(NULL) {
|
||||
m_conn_info(nullptr) {
|
||||
m_state = TP_SESS_STAT_RUNNING;
|
||||
m_startup_win_size_recorded = false;
|
||||
m_db_id = 0;
|
||||
m_is_relay = false;
|
||||
m_is_closed = false;
|
||||
m_first_client_pkg = true;
|
||||
m_last_access_timestamp = (ex_u32) time(NULL);
|
||||
m_last_access_timestamp = (ex_u32) time(nullptr);
|
||||
|
||||
m_win_width = 0;
|
||||
m_win_height = 0;
|
||||
|
@ -43,7 +43,7 @@ TelnetSession::~TelnetSession() {
|
|||
delete m_conn_client;
|
||||
delete m_conn_server;
|
||||
|
||||
if (NULL != m_conn_info) {
|
||||
if (nullptr != m_conn_info) {
|
||||
g_telnet_env.free_connect_info(m_conn_info);
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,7 @@ bool TelnetSession::_on_session_end() {
|
|||
return true;
|
||||
}
|
||||
|
||||
uv_loop_t *TelnetSession::get_loop(void) {
|
||||
uv_loop_t* TelnetSession::get_loop() {
|
||||
return m_proxy->get_loop();
|
||||
}
|
||||
|
||||
|
@ -110,47 +110,47 @@ void TelnetSession::close(int err_code) {
|
|||
_do_close(err_code);
|
||||
}
|
||||
|
||||
void TelnetSession::do_next(TelnetConn *conn, sess_state status) {
|
||||
void TelnetSession::do_next(TelnetConn* conn, sess_state status) {
|
||||
if (m_status < s_close)
|
||||
m_status = status;
|
||||
|
||||
do_next(conn);
|
||||
}
|
||||
|
||||
void TelnetSession::do_next(TelnetConn *conn) {
|
||||
void TelnetSession::do_next(TelnetConn* conn) {
|
||||
sess_state new_status;
|
||||
ASSERT(m_status != s_dead);
|
||||
|
||||
switch (m_status) {
|
||||
case s_noop:
|
||||
return;
|
||||
case s_noop:
|
||||
return;
|
||||
|
||||
case s_client_connect:
|
||||
new_status = _do_client_connect(conn);
|
||||
break;
|
||||
case s_client_connect:
|
||||
new_status = _do_client_connect(conn);
|
||||
break;
|
||||
|
||||
case s_negotiation_with_client:
|
||||
new_status = _do_negotiation_with_client(conn);
|
||||
break;
|
||||
case s_server_connected:
|
||||
new_status = _do_server_connected();
|
||||
break;
|
||||
case s_relay:
|
||||
new_status = _do_relay(conn);
|
||||
break;
|
||||
case s_negotiation_with_client:
|
||||
new_status = _do_negotiation_with_client(conn);
|
||||
break;
|
||||
case s_server_connected:
|
||||
new_status = _do_server_connected();
|
||||
break;
|
||||
case s_relay:
|
||||
new_status = _do_relay(conn);
|
||||
break;
|
||||
|
||||
case s_close:
|
||||
new_status = _do_close(m_state);
|
||||
break;
|
||||
case s_closing:
|
||||
new_status = _do_check_closing();
|
||||
break;
|
||||
case s_all_conn_closed:
|
||||
new_status = s_dead;
|
||||
break;
|
||||
default:
|
||||
//UNREACHABLE();
|
||||
return;
|
||||
case s_close:
|
||||
new_status = _do_close(m_state);
|
||||
break;
|
||||
case s_closing:
|
||||
new_status = _do_check_closing();
|
||||
break;
|
||||
case s_all_conn_closed:
|
||||
new_status = s_dead;
|
||||
break;
|
||||
default:
|
||||
//UNREACHABLE();
|
||||
return;
|
||||
}
|
||||
|
||||
m_status = new_status;
|
||||
|
@ -179,14 +179,16 @@ sess_state TelnetSession::_do_close(int state) {
|
|||
m_state = TP_SESS_STAT_ERR_INTERNAL;
|
||||
else
|
||||
m_state = state;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (!m_is_relay)
|
||||
_session_error(state);
|
||||
m_state = state;
|
||||
}
|
||||
EXLOGV("[telnet] close session.\n");
|
||||
EXLOGD("[telnet] _do_close(), conn_client::state=%d, conn_server:state=%d\n", m_conn_client->state(),
|
||||
m_conn_server->state());
|
||||
EXLOGD(
|
||||
"[telnet] _do_close(), conn_client::state=%d, conn_server:state=%d\n", m_conn_client->state(),
|
||||
m_conn_server->state());
|
||||
|
||||
m_conn_client->close();
|
||||
m_conn_server->close();
|
||||
|
@ -202,21 +204,22 @@ sess_state TelnetSession::_do_check_closing() {
|
|||
}
|
||||
|
||||
void TelnetSession::on_conn_close() {
|
||||
EXLOGD("[telnet] on_conn_close(), conn_client::state=%d, conn_server:state=%d\n", m_conn_client->state(),
|
||||
m_conn_server->state());
|
||||
EXLOGD(
|
||||
"[telnet] on_conn_close(), conn_client::state=%d, conn_server:state=%d\n", m_conn_client->state(),
|
||||
m_conn_server->state());
|
||||
if (m_conn_client->state() == TELNET_CONN_STATE_FREE && m_conn_server->state() == TELNET_CONN_STATE_FREE) {
|
||||
m_status = s_all_conn_closed;
|
||||
do_next(m_conn_client);
|
||||
}
|
||||
}
|
||||
|
||||
sess_state TelnetSession::_do_client_connect(TelnetConn *conn) {
|
||||
sess_state TelnetSession::_do_client_connect(TelnetConn* conn) {
|
||||
// putty会率先发第一个包,SecureCRT会通过脚本发第一个包
|
||||
return _do_negotiation_with_client(conn);
|
||||
}
|
||||
|
||||
sess_state TelnetSession::_do_negotiation_with_client(TelnetConn *conn) {
|
||||
if (NULL == conn)
|
||||
sess_state TelnetSession::_do_negotiation_with_client(TelnetConn* conn) {
|
||||
if (nullptr == conn)
|
||||
return s_negotiation_with_client;
|
||||
|
||||
if (0 == conn->data().size())
|
||||
|
@ -225,7 +228,7 @@ sess_state TelnetSession::_do_negotiation_with_client(TelnetConn *conn) {
|
|||
if (m_first_client_pkg) {
|
||||
m_first_client_pkg = false;
|
||||
|
||||
MemBuffer &mbuf = conn->data();
|
||||
MemBuffer& mbuf = conn->data();
|
||||
|
||||
if (mbuf.size() > 14 && 0 == memcmp(mbuf.data(), "session:", 8)) {
|
||||
m_is_putty_mode = false;
|
||||
|
@ -238,11 +241,12 @@ sess_state TelnetSession::_do_negotiation_with_client(TelnetConn *conn) {
|
|||
break;
|
||||
}
|
||||
|
||||
mbuf.append((ex_u8 *) "\x00", 1);
|
||||
m_sid = (char *) mbuf.data();
|
||||
mbuf.append((ex_u8*) "\x00", 1);
|
||||
m_sid = (char*) mbuf.data();
|
||||
|
||||
return _do_connect_server();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
m_is_putty_mode = true;
|
||||
}
|
||||
}
|
||||
|
@ -287,36 +291,44 @@ sess_state TelnetSession::_do_negotiation_with_client(TelnetConn *conn) {
|
|||
if (s.get_u8() == TELNET_SE) {
|
||||
have_SE = true;
|
||||
break;
|
||||
} else
|
||||
}
|
||||
else
|
||||
return _do_close(TP_SESS_STAT_ERR_BAD_PKG);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
ms_sub.put_u8(ch_sub);
|
||||
}
|
||||
}
|
||||
|
||||
if (!have_SE)
|
||||
return _do_close(TP_SESS_STAT_ERR_BAD_PKG);
|
||||
} else if (ch_cmd == TELNET_DONT) {
|
||||
}
|
||||
else if (ch_cmd == TELNET_DONT) {
|
||||
ms_resp.put_u8(TELNET_IAC);
|
||||
ms_resp.put_u8(TELNET_WONT);
|
||||
ms_resp.put_u8(s.get_u8());
|
||||
} else if (ch_cmd == TELNET_DO) {
|
||||
}
|
||||
else if (ch_cmd == TELNET_DO) {
|
||||
ms_resp.put_u8(TELNET_IAC);
|
||||
ms_resp.put_u8(TELNET_WILL);
|
||||
ms_resp.put_u8(s.get_u8());
|
||||
} else if (ch_cmd == TELNET_WONT) {
|
||||
}
|
||||
else if (ch_cmd == TELNET_WONT) {
|
||||
ms_resp.put_u8(TELNET_IAC);
|
||||
ms_resp.put_u8(TELNET_DONT);
|
||||
ms_resp.put_u8(s.get_u8());
|
||||
} else if (ch_cmd == TELNET_WILL) {
|
||||
}
|
||||
else if (ch_cmd == TELNET_WILL) {
|
||||
ms_resp.put_u8(TELNET_IAC);
|
||||
ms_resp.put_u8(TELNET_DO);
|
||||
ms_resp.put_u8(s.get_u8());
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
s.skip(1);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
ms_msg.put_u8(ch);
|
||||
}
|
||||
}
|
||||
|
@ -350,7 +362,7 @@ sess_state TelnetSession::_do_negotiation_with_client(TelnetConn *conn) {
|
|||
0x03, 0x53, 0x46, 0x55, 0x54, 0x4c, 0x4e, 0x54, 0x56, 0x45, 0x52, 0x03, 0x53, 0x46, 0x55, 0x54,
|
||||
0x4c, 0x4e, 0x54, 0x4d, 0x4f, 0x44, 0x45, 0xff, 0xf0
|
||||
};
|
||||
m_conn_client->send((ex_u8 *) _d, sizeof(_d));
|
||||
m_conn_client->send((ex_u8*) _d, sizeof(_d));
|
||||
return s_negotiation_with_client;
|
||||
}
|
||||
|
||||
|
@ -366,8 +378,8 @@ sess_state TelnetSession::_do_negotiation_with_client(TelnetConn *conn) {
|
|||
break;
|
||||
}
|
||||
|
||||
mbuf_sub.append((ex_u8 *) "\x00", 1);
|
||||
m_sid = (char *) mbuf_sub.data();
|
||||
mbuf_sub.append((ex_u8*) "\x00", 1);
|
||||
m_sid = (char*) mbuf_sub.data();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -384,10 +396,11 @@ sess_state TelnetSession::_do_connect_server() {
|
|||
|
||||
m_conn_info = g_telnet_env.get_connect_info(m_sid.c_str());
|
||||
|
||||
if (NULL == m_conn_info) {
|
||||
if (nullptr == m_conn_info) {
|
||||
EXLOGE("[telnet] no such session: %s\n", m_sid.c_str());
|
||||
return _do_close(TP_SESS_STAT_ERR_SESSION);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
m_conn_ip = m_conn_info->conn_ip;
|
||||
m_conn_port = m_conn_info->conn_port;
|
||||
m_acc_name = m_conn_info->acc_username;
|
||||
|
@ -454,7 +467,7 @@ sess_state TelnetSession::_do_server_connected() {
|
|||
|
||||
char buf[512] = {0};
|
||||
|
||||
const char *auth_mode = NULL;
|
||||
const char* auth_mode = nullptr;
|
||||
if (m_conn_info->auth_type == TP_AUTH_TYPE_PASSWORD)
|
||||
auth_mode = "password";
|
||||
else if (m_conn_info->auth_type == TP_AUTH_TYPE_NONE)
|
||||
|
@ -464,29 +477,30 @@ sess_state TelnetSession::_do_server_connected() {
|
|||
|
||||
ex_astr line(w, '=');
|
||||
|
||||
snprintf(buf, sizeof(buf),
|
||||
"\r\n"\
|
||||
snprintf(
|
||||
buf, sizeof(buf),
|
||||
"\r\n"\
|
||||
"%s\r\n"\
|
||||
"Teleport TELNET Bastion Server...\r\n"\
|
||||
" - teleport to %s:%d\r\n"\
|
||||
" - authroized by %s\r\n"\
|
||||
"%s\r\n"\
|
||||
"\r\n\r\n",
|
||||
line.c_str(),
|
||||
m_conn_ip.c_str(),
|
||||
m_conn_port, auth_mode,
|
||||
line.c_str()
|
||||
line.c_str(),
|
||||
m_conn_ip.c_str(),
|
||||
m_conn_port, auth_mode,
|
||||
line.c_str()
|
||||
);
|
||||
|
||||
m_conn_client->send((ex_u8 *) buf, strlen(buf));
|
||||
m_conn_client->send((ex_u8*) buf, strlen(buf));
|
||||
|
||||
if (m_is_putty_mode) {
|
||||
if (m_conn_info->auth_type != TP_AUTH_TYPE_NONE) {
|
||||
ex_astr login_info = "login: ";
|
||||
login_info += m_conn_info->acc_username;
|
||||
login_info += "\r\n";
|
||||
m_conn_client->send((ex_u8 *) login_info.c_str(), login_info.length());
|
||||
m_rec.record(TS_RECORD_TYPE_TELNET_DATA, (ex_u8 *) login_info.c_str(), login_info.length());
|
||||
m_conn_client->send((ex_u8*) login_info.c_str(), login_info.length());
|
||||
m_rec.record(TS_RECORD_TYPE_TELNET_DATA, (ex_u8*) login_info.c_str(), login_info.length());
|
||||
}
|
||||
|
||||
ex_u8 _d[] = "\xff\xfb\x1f\xff\xfb\x20\xff\xfb\x18\xff\xfb\x27\xff\xfd\x01\xff\xfb\x03\xff\xfd\x03";
|
||||
|
@ -496,10 +510,10 @@ sess_state TelnetSession::_do_server_connected() {
|
|||
return s_relay;
|
||||
}
|
||||
|
||||
sess_state TelnetSession::_do_relay(TelnetConn *conn) {
|
||||
m_last_access_timestamp = (ex_u32) time(NULL);
|
||||
sess_state TelnetSession::_do_relay(TelnetConn* conn) {
|
||||
m_last_access_timestamp = (ex_u32) time(nullptr);
|
||||
|
||||
TelnetSession *_this = conn->session();
|
||||
TelnetSession* _this = conn->session();
|
||||
bool is_processed = false;
|
||||
|
||||
if (conn->is_server_side()) {
|
||||
|
@ -528,7 +542,8 @@ sess_state TelnetSession::_do_relay(TelnetConn *conn) {
|
|||
|
||||
m_conn_server->send(m_conn_client->data().data(), m_conn_client->data().size());
|
||||
m_conn_client->data().empty();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// EXLOG_BIN(m_conn_server->data().data(), m_conn_server->data().size(), "--> server:");
|
||||
|
||||
// 收到了服务端返回的数据
|
||||
|
@ -536,15 +551,17 @@ sess_state TelnetSession::_do_relay(TelnetConn *conn) {
|
|||
m_rec.record(TS_RECORD_TYPE_TELNET_DATA, m_conn_server->data().data(), m_conn_server->data().size());
|
||||
|
||||
if (!_this->m_username_sent && _this->m_acc_name.length() > 0) {
|
||||
if (_this->_parse_find_and_send(m_conn_server, m_conn_client, _this->m_username_prompt.c_str(),
|
||||
_this->m_acc_name.c_str())) {
|
||||
if (_this->_parse_find_and_send(
|
||||
m_conn_server, m_conn_client, _this->m_username_prompt.c_str(),
|
||||
_this->m_acc_name.c_str())) {
|
||||
// _this->m_username_sent = true;
|
||||
is_processed = true;
|
||||
}
|
||||
}
|
||||
if (!_this->m_password_sent && _this->m_password_prompt.length() > 0) {
|
||||
if (_this->_parse_find_and_send(m_conn_server, m_conn_client, _this->m_password_prompt.c_str(),
|
||||
_this->m_acc_secret.c_str())) {
|
||||
if (_this->_parse_find_and_send(
|
||||
m_conn_server, m_conn_client, _this->m_password_prompt.c_str(),
|
||||
_this->m_acc_secret.c_str())) {
|
||||
_this->m_username_sent = true;
|
||||
_this->m_password_sent = true;
|
||||
_this->m_username_sent = true;
|
||||
|
@ -564,8 +581,10 @@ sess_state TelnetSession::_do_relay(TelnetConn *conn) {
|
|||
return s_relay;
|
||||
}
|
||||
|
||||
bool TelnetSession::_parse_find_and_send(TelnetConn *conn_recv, TelnetConn *conn_remote, const char *find,
|
||||
const char *send) {
|
||||
bool TelnetSession::_parse_find_and_send(
|
||||
TelnetConn* conn_recv, TelnetConn* conn_remote, const char* find,
|
||||
const char* send
|
||||
) {
|
||||
// EXLOGV("find prompt and send: [%s] => [%s]\n", find, send);
|
||||
// EXLOG_BIN(conn_recv->data().data(), conn_recv->data().size(), "find prompt in data:");
|
||||
|
||||
|
@ -583,8 +602,8 @@ bool TelnetSession::_parse_find_and_send(TelnetConn *conn_recv, TelnetConn *conn
|
|||
|
||||
MemBuffer mbuf_msg;
|
||||
mbuf_msg.reserve(128);
|
||||
mbuf_msg.append((ex_u8 *) send, send_len);
|
||||
mbuf_msg.append((ex_u8 *) "\x0d\x0a", 2);
|
||||
mbuf_msg.append((ex_u8*) send, send_len);
|
||||
mbuf_msg.append((ex_u8*) "\x0d\x0a", 2);
|
||||
// EXLOG_BIN(mbuf_msg.data(), mbuf_msg.size(), "find prompt and send:");
|
||||
conn_recv->send(mbuf_msg.data(), mbuf_msg.size());
|
||||
return true;
|
||||
|
@ -668,7 +687,7 @@ bool TelnetSession::_parse_find_and_send(TelnetConn *conn_recv, TelnetConn *conn
|
|||
return false;
|
||||
}
|
||||
|
||||
bool TelnetSession::_putty_replace_username(TelnetConn *conn_recv, TelnetConn *conn_remote) {
|
||||
bool TelnetSession::_putty_replace_username(TelnetConn* conn_recv, TelnetConn* conn_remote) {
|
||||
bool replaced = false;
|
||||
|
||||
MemBuffer mbuf_msg;
|
||||
|
@ -701,7 +720,8 @@ bool TelnetSession::_putty_replace_username(TelnetConn *conn_recv, TelnetConn *c
|
|||
if (s.get_u8() == TELNET_SE) {
|
||||
have_SE = true;
|
||||
break;
|
||||
} else
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -724,20 +744,22 @@ bool TelnetSession::_putty_replace_username(TelnetConn *conn_recv, TelnetConn *c
|
|||
|
||||
ms_msg.put_u8(TELNET_IAC);
|
||||
ms_msg.put_u8(TELNET_SB);
|
||||
ms_msg.put_bin((ex_u8 *) "\x27\x00\x00\x55\x53\x45\x52\x01", 8);
|
||||
ms_msg.put_bin((ex_u8*) "\x27\x00\x00\x55\x53\x45\x52\x01", 8);
|
||||
|
||||
ms_msg.put_bin((ex_u8 *) m_acc_name.c_str(), m_acc_name.length());
|
||||
ms_msg.put_bin((ex_u8*) m_acc_name.c_str(), m_acc_name.length());
|
||||
|
||||
ms_msg.put_u8(TELNET_IAC);
|
||||
ms_msg.put_u8(TELNET_SE);
|
||||
|
||||
replaced = true;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
ms_msg.put_u8(ch);
|
||||
ms_msg.put_u8(ch_cmd);
|
||||
ms_msg.put_u8(s.get_u8());
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
ms_msg.put_u8(ch);
|
||||
}
|
||||
}
|
||||
|
@ -750,7 +772,7 @@ bool TelnetSession::_putty_replace_username(TelnetConn *conn_recv, TelnetConn *c
|
|||
return false;
|
||||
}
|
||||
|
||||
bool TelnetSession::_parse_win_size(TelnetConn *conn) {
|
||||
bool TelnetSession::_parse_win_size(TelnetConn* conn) {
|
||||
if (conn->data().size() < 9)
|
||||
return false;
|
||||
if (conn->data().data()[0] != TELNET_IAC)
|
||||
|
@ -777,7 +799,8 @@ bool TelnetSession::_parse_win_size(TelnetConn *conn) {
|
|||
if (s.get_u8() == TELNET_SE) {
|
||||
have_SE = true;
|
||||
break;
|
||||
} else
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,115 +7,134 @@
|
|||
#include "telnet_conn.h"
|
||||
|
||||
enum sess_state {
|
||||
s_noop, // 什么都不做,等特定状态满足
|
||||
s_noop, // 什么都不做,等特定状态满足
|
||||
|
||||
s_client_connect, // 客户端连接
|
||||
s_negotiation_with_client, // 与客户端进行握手,直到得到客户端发来的登录用户名(其实是SessionID)
|
||||
s_client_connect, // 客户端连接
|
||||
s_negotiation_with_client, // 与客户端进行握手,直到得到客户端发来的登录用户名(其实是SessionID)
|
||||
|
||||
s_server_connected, // 成功连接上服务器了
|
||||
s_server_connected, // 成功连接上服务器了
|
||||
|
||||
s_relay, // 正常转发数据
|
||||
s_relay, // 正常转发数据
|
||||
|
||||
s_close, // 关闭会话
|
||||
s_closing, // 正在关闭双方连接
|
||||
s_all_conn_closed, // 两端均已关闭
|
||||
s_close, // 关闭会话
|
||||
s_closing, // 正在关闭双方连接
|
||||
s_all_conn_closed, // 两端均已关闭
|
||||
|
||||
s_dead // 可以销毁此会话了
|
||||
s_dead // 可以销毁此会话了
|
||||
};
|
||||
|
||||
class TelnetProxy;
|
||||
|
||||
class TelnetSession
|
||||
{
|
||||
class TelnetSession {
|
||||
public:
|
||||
TelnetSession(TelnetProxy* proxy);
|
||||
virtual ~TelnetSession();
|
||||
TelnetSession(TelnetProxy* proxy);
|
||||
|
||||
TelnetProxy* get_proxy() { return m_proxy; }
|
||||
virtual ~TelnetSession();
|
||||
|
||||
TelnetConn* client() { return m_conn_client; }
|
||||
TelnetConn* server() { return m_conn_server; }
|
||||
uv_loop_t* get_loop();
|
||||
TelnetProxy* get_proxy() { return m_proxy; }
|
||||
|
||||
void set_state(int state) { m_state = state; }
|
||||
void close(int err_code);
|
||||
void on_conn_close();
|
||||
TelnetConn* client() { return m_conn_client; }
|
||||
|
||||
void do_next(TelnetConn* conn);
|
||||
void do_next(TelnetConn* conn, sess_state status);
|
||||
TelnetConn* server() { return m_conn_server; }
|
||||
|
||||
// save record cache into file. be called per 5 seconds.
|
||||
void save_record();
|
||||
void record(ex_u8 type, const ex_u8* data, size_t size) {
|
||||
m_rec.record(type, data, size);
|
||||
}
|
||||
//
|
||||
void check_noop_timeout(ex_u32 t_now, ex_u32 timeout);
|
||||
const ex_astr& sid() { return m_sid; }
|
||||
uv_loop_t* get_loop();
|
||||
|
||||
void client_addr(const char* addr) { m_client_addr = addr; }
|
||||
const char* client_addr() const { return m_client_addr.c_str(); }
|
||||
void set_state(int state) { m_state = state; }
|
||||
|
||||
bool is_relay() { return m_is_relay; }
|
||||
bool is_closed() { return m_is_closed; }
|
||||
void close(int err_code);
|
||||
|
||||
void on_conn_close();
|
||||
|
||||
void do_next(TelnetConn* conn);
|
||||
|
||||
void do_next(TelnetConn* conn, sess_state status);
|
||||
|
||||
// save record cache into file. be called per 5 seconds.
|
||||
void save_record();
|
||||
|
||||
void record(ex_u8 type, const ex_u8* data, size_t size) {
|
||||
m_rec.record(type, data, size);
|
||||
}
|
||||
|
||||
//
|
||||
void check_noop_timeout(ex_u32 t_now, ex_u32 timeout);
|
||||
|
||||
const ex_astr& sid() { return m_sid; }
|
||||
|
||||
void client_addr(const char* addr) { m_client_addr = addr; }
|
||||
|
||||
const char* client_addr() const { return m_client_addr.c_str(); }
|
||||
|
||||
bool is_relay() const { return m_is_relay; }
|
||||
|
||||
bool is_closed() const { return m_is_closed; }
|
||||
|
||||
protected:
|
||||
// 继承自 TppSessionBase
|
||||
bool _on_session_begin();
|
||||
bool _on_session_end();
|
||||
void _session_error(int err_code);
|
||||
// 继承自 TppSessionBase
|
||||
bool _on_session_begin();
|
||||
|
||||
bool _on_session_end();
|
||||
|
||||
void _session_error(int err_code);
|
||||
|
||||
private:
|
||||
sess_state _do_client_connect(TelnetConn* conn);
|
||||
sess_state _do_negotiation_with_client(TelnetConn* conn);
|
||||
sess_state _do_connect_server();
|
||||
sess_state _do_server_connected();
|
||||
sess_state _do_relay(TelnetConn* conn);
|
||||
sess_state _do_close(int err_code);
|
||||
sess_state _do_check_closing();
|
||||
sess_state _do_client_connect(TelnetConn* conn);
|
||||
|
||||
bool _parse_find_and_send(TelnetConn* conn_recv, TelnetConn* conn_remote, const char* find, const char* send);
|
||||
bool _putty_replace_username(TelnetConn* conn_recv, TelnetConn* conn_remote);
|
||||
bool _parse_win_size(TelnetConn* conn);
|
||||
sess_state _do_negotiation_with_client(TelnetConn* conn);
|
||||
|
||||
sess_state _do_connect_server();
|
||||
|
||||
sess_state _do_server_connected();
|
||||
|
||||
sess_state _do_relay(TelnetConn* conn);
|
||||
|
||||
sess_state _do_close(int err_code);
|
||||
|
||||
sess_state _do_check_closing();
|
||||
|
||||
bool _parse_find_and_send(TelnetConn* conn_recv, TelnetConn* conn_remote, const char* find, const char* send);
|
||||
|
||||
bool _putty_replace_username(TelnetConn* conn_recv, TelnetConn* conn_remote);
|
||||
|
||||
bool _parse_win_size(TelnetConn* conn);
|
||||
|
||||
private:
|
||||
int m_state;
|
||||
int m_state;
|
||||
|
||||
TPP_CONNECT_INFO* m_conn_info;
|
||||
bool m_startup_win_size_recorded;
|
||||
int m_db_id;
|
||||
TPP_CONNECT_INFO* m_conn_info;
|
||||
bool m_startup_win_size_recorded;
|
||||
int m_db_id;
|
||||
|
||||
bool m_first_client_pkg;
|
||||
bool m_is_relay; // 是否进入relay模式了(只有进入relay模式才会有录像存在)
|
||||
bool m_is_closed;
|
||||
ex_u32 m_last_access_timestamp;
|
||||
bool m_first_client_pkg;
|
||||
bool m_is_relay; // 是否进入relay模式了(只有进入relay模式才会有录像存在)
|
||||
bool m_is_closed;
|
||||
ex_u32 m_last_access_timestamp;
|
||||
|
||||
TppTelnetRec m_rec;
|
||||
int m_win_width;
|
||||
int m_win_height;
|
||||
TppTelnetRec m_rec;
|
||||
int m_win_width;
|
||||
int m_win_height;
|
||||
|
||||
TelnetProxy* m_proxy;
|
||||
TelnetConn* m_conn_client; // 与真正客户端通讯的连接(自身作为服务端)
|
||||
TelnetConn* m_conn_server; // 与真正服务端通讯的连接(自身作为客户端)
|
||||
TelnetProxy* m_proxy;
|
||||
TelnetConn* m_conn_client; // 与真正客户端通讯的连接(自身作为服务端)
|
||||
TelnetConn* m_conn_server; // 与真正服务端通讯的连接(自身作为客户端)
|
||||
|
||||
ExThreadLock m_lock;
|
||||
ExThreadLock m_lock;
|
||||
|
||||
ex_astr m_sid;
|
||||
ex_astr m_conn_ip;
|
||||
ex_u16 m_conn_port;
|
||||
ex_astr m_acc_name;
|
||||
ex_astr m_acc_secret;
|
||||
ex_astr m_username_prompt;
|
||||
ex_astr m_password_prompt;
|
||||
ex_astr m_sid;
|
||||
ex_astr m_conn_ip;
|
||||
ex_u16 m_conn_port;
|
||||
ex_astr m_acc_name;
|
||||
ex_astr m_acc_secret;
|
||||
ex_astr m_username_prompt;
|
||||
ex_astr m_password_prompt;
|
||||
|
||||
sess_state m_status;
|
||||
ex_astr m_client_addr;
|
||||
sess_state m_status;
|
||||
ex_astr m_client_addr;
|
||||
|
||||
bool m_is_putty_mode;
|
||||
//bool m_is_putty_eat_username;
|
||||
bool m_is_putty_mode;
|
||||
|
||||
bool m_username_sent;
|
||||
bool m_password_sent;
|
||||
bool m_username_sent;
|
||||
bool m_password_sent;
|
||||
};
|
||||
|
||||
#endif // __TELNET_SESSION_H__
|
||||
|
|
|
@ -2,32 +2,30 @@
|
|||
|
||||
TppTelnetEnv g_telnet_env;
|
||||
|
||||
TppTelnetEnv::TppTelnetEnv()
|
||||
{}
|
||||
TppTelnetEnv::TppTelnetEnv() = default;
|
||||
|
||||
TppTelnetEnv::~TppTelnetEnv()
|
||||
{}
|
||||
TppTelnetEnv::~TppTelnetEnv() = default;
|
||||
|
||||
bool TppTelnetEnv::_on_init(TPP_INIT_ARGS* args) {
|
||||
ex_path_join(replay_path, false, L"telnet", NULL);
|
||||
ex_path_join(replay_path, false, L"telnet", nullptr);
|
||||
|
||||
ExIniSection* ps = args->cfg->GetSection(L"protocol-telnet");
|
||||
if (NULL == ps) {
|
||||
EXLOGE("[telnet] invalid config(2).\n");
|
||||
return false;
|
||||
}
|
||||
ExIniSection* ps = args->cfg->GetSection(L"protocol-telnet");
|
||||
if (nullptr == ps) {
|
||||
EXLOGE("[telnet] invalid config(2).\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ex_wstr tmp;
|
||||
if (!ps->GetStr(L"bind-ip", tmp)) {
|
||||
bind_ip = TS_TELNET_PROXY_HOST;
|
||||
}
|
||||
else {
|
||||
ex_wstr2astr(tmp, bind_ip);
|
||||
}
|
||||
ex_wstr tmp;
|
||||
if (!ps->GetStr(L"bind-ip", tmp)) {
|
||||
bind_ip = TS_TELNET_PROXY_HOST;
|
||||
}
|
||||
else {
|
||||
ex_wstr2astr(tmp, bind_ip);
|
||||
}
|
||||
|
||||
if (!ps->GetInt(L"bind-port", bind_port)) {
|
||||
bind_port = TS_TELNET_PROXY_PORT;
|
||||
}
|
||||
if (!ps->GetInt(L"bind-port", bind_port)) {
|
||||
bind_port = TS_TELNET_PROXY_PORT;
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -7,14 +7,14 @@ class TppTelnetEnv : public TppEnvBase
|
|||
{
|
||||
public:
|
||||
TppTelnetEnv();
|
||||
~TppTelnetEnv();
|
||||
virtual ~TppTelnetEnv();
|
||||
|
||||
public:
|
||||
ex_astr bind_ip;
|
||||
int bind_port;
|
||||
|
||||
private:
|
||||
bool _on_init(TPP_INIT_ARGS* args);
|
||||
bool _on_init(TPP_INIT_ARGS* args) override;
|
||||
};
|
||||
|
||||
extern TppTelnetEnv g_telnet_env;
|
||||
|
|
|
@ -33,17 +33,7 @@ TPP_API void tpp_timer(void) {
|
|||
g_telnet_proxy.timer();
|
||||
}
|
||||
|
||||
|
||||
// TPP_API void tpp_set_cfg(TPP_SET_CFG_ARGS* cfg_args) {
|
||||
// g_telnet_proxy.set_cfg(cfg_args);
|
||||
// }
|
||||
|
||||
|
||||
static ex_rv _set_runtime_config(const char* param) {
|
||||
// Json::Value jp;
|
||||
// Json::Reader jreader;
|
||||
//
|
||||
// if (!jreader.parse(param, jp))
|
||||
static ex_rv tpp_cmd_set_runtime_config(const char* param) {
|
||||
Json::CharReaderBuilder jcrb;
|
||||
std::unique_ptr<Json::CharReader> const jreader(jcrb.newCharReader());
|
||||
|
||||
|
@ -67,11 +57,7 @@ static ex_rv _set_runtime_config(const char* param) {
|
|||
return TPE_PARAM;
|
||||
}
|
||||
|
||||
static ex_rv _kill_sessions(const char* param) {
|
||||
// Json::Value jp;
|
||||
// Json::Reader jreader;
|
||||
//
|
||||
// if (!jreader.parse(param, jp))
|
||||
static ex_rv tpp_cmd_kill_sessions(const char* param) {
|
||||
Json::CharReaderBuilder jcrb;
|
||||
std::unique_ptr<Json::CharReader> const jreader(jcrb.newCharReader());
|
||||
|
||||
|
@ -102,16 +88,14 @@ static ex_rv _kill_sessions(const char* param) {
|
|||
TPP_API ex_rv tpp_command(ex_u32 cmd, const char* param) {
|
||||
switch (cmd) {
|
||||
case TPP_CMD_SET_RUNTIME_CFG:
|
||||
if (param == NULL || strlen(param) == 0)
|
||||
if (param == nullptr || strlen(param) == 0)
|
||||
return TPE_PARAM;
|
||||
return tpp_cmd_set_runtime_config(param);
|
||||
case TPP_CMD_KILL_SESSIONS:
|
||||
if (param == NULL || strlen(param) == 0)
|
||||
if (param == nullptr || strlen(param) == 0)
|
||||
return TPE_PARAM;
|
||||
return tpp_cmd_kill_sessions(param);
|
||||
default:
|
||||
return TPE_UNKNOWN_CMD;
|
||||
}
|
||||
|
||||
return TPE_NOT_IMPLEMENT;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue