From e7635e77561a6a57b39cc741b9c96ee88dbd551c Mon Sep 17 00:00:00 2001 From: Apex Liu Date: Fri, 19 Jun 2020 02:22:26 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E8=BF=9B=EF=BC=9ATP=E6=A0=B8=E5=BF=83?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E6=AF=8F60=E7=A7=92=E5=90=91=E5=B7=B2?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E7=9A=84=E5=AE=A2=E6=88=B7=E7=AB=AF=E5=92=8C?= =?UTF-8?q?=E8=BF=9C=E7=A8=8B=E4=B8=BB=E6=9C=BA=E5=8F=91=E9=80=81keep-aliv?= =?UTF-8?q?e=E6=B6=88=E6=81=AF=EF=BC=8C=E9=98=B2=E6=AD=A2=E8=BF=9E?= =?UTF-8?q?=E6=8E=A5=E4=B8=AD=E6=96=AD=E3=80=82=E4=BD=86=E4=BB=8D=E4=BF=9D?= =?UTF-8?q?=E7=95=99=E6=97=A0=E6=93=8D=E4=BD=9C=E8=B6=85=E6=97=B6=E5=B0=B1?= =?UTF-8?q?=E6=96=AD=E5=BC=80=E7=9A=84=E9=99=90=E5=88=B6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/tp_core/protocol/ssh/ssh_proxy.cpp | 39 ++- server/tp_core/protocol/ssh/ssh_proxy.h | 3 +- server/tp_core/protocol/ssh/ssh_session.cpp | 11 +- server/tp_core/protocol/ssh/ssh_session.h | 313 ++++++++++---------- 4 files changed, 195 insertions(+), 171 deletions(-) diff --git a/server/tp_core/protocol/ssh/ssh_proxy.cpp b/server/tp_core/protocol/ssh/ssh_proxy.cpp index 0129b5e..dddb0e6 100644 --- a/server/tp_core/protocol/ssh/ssh_proxy.cpp +++ b/server/tp_core/protocol/ssh/ssh_proxy.cpp @@ -6,7 +6,8 @@ SshProxy g_ssh_proxy; SshProxy::SshProxy() : ExThreadBase("ssh-proxy-thread"), m_bind(NULL) { - m_timer_counter = 0; + m_timer_counter_check_noop = 0; + m_timer_counter_send_keep_alive= 0; m_noop_timeout_sec = 900; // default to 15 minutes. m_listener_running = false; } @@ -59,21 +60,33 @@ bool SshProxy::init() { } void SshProxy::timer() { - // timer() will be called per one second, and I will do my job per 5 seconds. - m_timer_counter++; - if (m_timer_counter < 5) - return; + // timer() will be called per one second + m_timer_counter_check_noop++; + m_timer_counter_send_keep_alive++; - m_timer_counter = 0; + // check no-op per 5 seconds. + if (m_timer_counter_check_noop >= 5) { + m_timer_counter_check_noop = 0; - ExThreadSmartLock locker(m_lock); - ex_u32 t_now = (ex_u32) time(NULL); + ExThreadSmartLock locker(m_lock); + ex_u32 t_now = (ex_u32)time(NULL); - ts_ssh_sessions::iterator it; - for (it = m_sessions.begin(); it != m_sessions.end(); ++it) { - it->first->save_record(); - if (0 != m_noop_timeout_sec) - it->first->check_noop_timeout(t_now, m_noop_timeout_sec); + ts_ssh_sessions::iterator it; + for (it = m_sessions.begin(); it != m_sessions.end(); ++it) { + it->first->save_record(); + if (0 != m_noop_timeout_sec) + it->first->check_noop_timeout(t_now, m_noop_timeout_sec); + } + } + + // send keep-alive every 60 seconds + if (m_timer_counter_send_keep_alive >= 60) { + m_timer_counter_send_keep_alive = 0; + ExThreadSmartLock locker(m_lock); + ts_ssh_sessions::iterator it; + for (it = m_sessions.begin(); it != m_sessions.end(); ++it) { + it->first->send_keep_alive(); + } } } diff --git a/server/tp_core/protocol/ssh/ssh_proxy.h b/server/tp_core/protocol/ssh/ssh_proxy.h index 5f9f397..87dc0c4 100644 --- a/server/tp_core/protocol/ssh/ssh_proxy.h +++ b/server/tp_core/protocol/ssh/ssh_proxy.h @@ -26,7 +26,8 @@ protected: private: ssh_bind m_bind; - int m_timer_counter; + int m_timer_counter_check_noop; + int m_timer_counter_send_keep_alive; ExThreadLock m_lock; bool m_listener_running; diff --git a/server/tp_core/protocol/ssh/ssh_session.cpp b/server/tp_core/protocol/ssh/ssh_session.cpp index d333f90..44584d9 100644 --- a/server/tp_core/protocol/ssh/ssh_session.cpp +++ b/server/tp_core/protocol/ssh/ssh_session.cpp @@ -399,7 +399,7 @@ void SshSession::save_record() { } void SshSession::check_noop_timeout(ex_u32 t_now, ex_u32 timeout) { - ExThreadSmartLock locker(m_lock); + // ExThreadSmartLock locker(m_lock); tp_channels::iterator it = m_channels.begin(); for (; it != m_channels.end(); ++it) { if ((*it)->need_close) @@ -415,6 +415,15 @@ void SshSession::check_noop_timeout(ex_u32 t_now, ex_u32 timeout) { } } +void SshSession::send_keep_alive() { + EXLOGD("[ssh] send keep-alive.\n"); + if(m_srv_session) + ssh_send_keepalive(m_srv_session); + if (m_cli_session) + ssh_send_keepalive(m_cli_session); +} + + int SshSession::_on_auth_password_request(ssh_session session, const char *user, const char *password, void *userdata) { // here, `user` is the session-id we need. SshSession *_this = (SshSession *) userdata; diff --git a/server/tp_core/protocol/ssh/ssh_session.h b/server/tp_core/protocol/ssh/ssh_session.h index 7e83df2..f262068 100644 --- a/server/tp_core/protocol/ssh/ssh_session.h +++ b/server/tp_core/protocol/ssh/ssh_session.h @@ -1,156 +1,157 @@ -#ifndef __SSH_SESSION_H__ -#define __SSH_SESSION_H__ - -#include "ssh_recorder.h" - -#include - -#include -#include -#include -#include - -#include -#include - -#define TS_SSH_CHANNEL_TYPE_UNKNOWN 0 -#define TS_SSH_CHANNEL_TYPE_SHELL 1 -#define TS_SSH_CHANNEL_TYPE_SFTP 2 - -#define TP_SSH_CLIENT_SIDE 1 -#define TP_SSH_SERVER_SIDE 2 - -class SshProxy; -class SshSession; - -class TP_SSH_CHANNEL_PAIR { - - friend class SshSession; - -public: - TP_SSH_CHANNEL_PAIR(); - -private: - int type; // TS_SSH_CHANNEL_TYPE_SHELL or TS_SSH_CHANNEL_TYPE_SFTP - - ssh_channel cli_channel; - ssh_channel srv_channel; - - TppSshRec rec; - ex_u32 last_access_timestamp; - - int state; - int db_id; - int channel_id; // for debug only. - - int win_width; // window width, in char count. - - bool is_first_server_data; - bool need_close; - - // for ssh command record cache. - bool server_ready; - bool maybe_cmd; - bool process_srv; - bool client_single_char; - std::list cmd_char_list; - std::list::iterator cmd_char_pos; -}; - -typedef std::list tp_channels; - -class SshSession : public ExThreadBase -{ -public: - SshSession(SshProxy* proxy, ssh_session sess_client); - virtual ~SshSession(); - - SshProxy* get_proxy(void) { return m_proxy; } - - TP_SSH_CHANNEL_PAIR* _get_channel_pair(int channel_side, ssh_channel channel); - - void client_ip(const char* ip) { m_client_ip = ip; } - const char* client_ip(void) const { return m_client_ip.c_str(); } - void client_port(ex_u16 port) { m_client_port = port; } - ex_u16 client_port(void) const { return m_client_port; } - - // save record cache into file. be called per 5 seconds. - void save_record(); - // - void check_noop_timeout(ex_u32 t_now, ex_u32 timeout); - - const ex_astr& sid() { return m_sid; } - -protected: - void _thread_loop(); - void _on_stop(); - void _on_stopped(); - - // record an error when session connecting or auth-ing. - void _session_error(int err_code); - // when client<->server channel created, start to record. - bool _record_begin(TP_SSH_CHANNEL_PAIR* cp); - // stop record because channel closed. - void _record_end(TP_SSH_CHANNEL_PAIR* cp); - - void _process_ssh_command(TP_SSH_CHANNEL_PAIR* cp, int from, const ex_u8* data, int len); - void _process_sftp_command(TP_SSH_CHANNEL_PAIR* cp, const ex_u8* data, int len); - -private: - void _run(void); - - void _close_channels(void); - void _check_channels(void); - - static int _on_auth_password_request(ssh_session session, const char *user, const char *password, void *userdata); - static ssh_channel _on_new_channel_request(ssh_session session, void *userdata); - static int _on_client_pty_request(ssh_session session, ssh_channel channel, const char *term, int x, int y, int px, int py, void *userdata); - static int _on_client_shell_request(ssh_session session, ssh_channel channel, void *userdata); - static void _on_client_channel_close(ssh_session session, ssh_channel channel, void* userdata); - static int _on_client_channel_data(ssh_session session, ssh_channel channel, void *data, unsigned int len, int is_stderr, void *userdata); - static int _on_client_pty_win_change(ssh_session session, ssh_channel channel, int width, int height, int pxwidth, int pwheight, void *userdata); - - static int _on_client_channel_subsystem_request(ssh_session session, ssh_channel channel, const char *subsystem, void *userdata); - static int _on_client_channel_exec_request(ssh_session session, ssh_channel channel, const char *command, void *userdata); - - static int _on_server_channel_data(ssh_session session, ssh_channel channel, void *data, unsigned int len, int is_stderr, void *userdata); - static void _on_server_channel_close(ssh_session session, ssh_channel channel, void* userdata); - -private: - SshProxy* m_proxy; - ssh_session m_cli_session; - ssh_session m_srv_session; - - ExThreadLock m_lock; - - ex_astr m_client_ip; - ex_u16 m_client_port; - - TPP_CONNECT_INFO* m_conn_info; - - 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_u32 m_flags; - int m_auth_type; - - bool m_is_logon; - - int m_ssh_ver; - - // 一个ssh_session中可以打开多个ssh_channel - tp_channels m_channels; - - bool m_have_error; - - bool m_recving_from_srv; // 是否正在从服务器接收数据? - bool m_recving_from_cli; // 是否正在从客户端接收数据? - - struct ssh_server_callbacks_struct m_srv_cb; - struct ssh_channel_callbacks_struct m_cli_channel_cb; - struct ssh_channel_callbacks_struct m_srv_channel_cb; -}; - -#endif // __SSH_SESSION_H__ +锘#ifndef __SSH_SESSION_H__ +#define __SSH_SESSION_H__ + +#include "ssh_recorder.h" + +#include + +#include +#include +#include +#include + +#include +#include + +#define TS_SSH_CHANNEL_TYPE_UNKNOWN 0 +#define TS_SSH_CHANNEL_TYPE_SHELL 1 +#define TS_SSH_CHANNEL_TYPE_SFTP 2 + +#define TP_SSH_CLIENT_SIDE 1 +#define TP_SSH_SERVER_SIDE 2 + +class SshProxy; +class SshSession; + +class TP_SSH_CHANNEL_PAIR { + + friend class SshSession; + +public: + TP_SSH_CHANNEL_PAIR(); + +private: + int type; // TS_SSH_CHANNEL_TYPE_SHELL or TS_SSH_CHANNEL_TYPE_SFTP + + ssh_channel cli_channel; + ssh_channel srv_channel; + + TppSshRec rec; + ex_u32 last_access_timestamp; + + int state; + int db_id; + int channel_id; // for debug only. + + int win_width; // window width, in char count. + + bool is_first_server_data; + bool need_close; + + // for ssh command record cache. + bool server_ready; + bool maybe_cmd; + bool process_srv; + bool client_single_char; + std::list cmd_char_list; + std::list::iterator cmd_char_pos; +}; + +typedef std::list tp_channels; + +class SshSession : public ExThreadBase +{ +public: + SshSession(SshProxy* proxy, ssh_session sess_client); + virtual ~SshSession(); + + SshProxy* get_proxy(void) { return m_proxy; } + + TP_SSH_CHANNEL_PAIR* _get_channel_pair(int channel_side, ssh_channel channel); + + void client_ip(const char* ip) { m_client_ip = ip; } + const char* client_ip(void) const { return m_client_ip.c_str(); } + void client_port(ex_u16 port) { m_client_port = port; } + ex_u16 client_port(void) const { return m_client_port; } + + // save record cache into file. be called per 5 seconds. + void save_record(); + // + void check_noop_timeout(ex_u32 t_now, ex_u32 timeout); + void send_keep_alive(); + + const ex_astr& sid() { return m_sid; } + +protected: + void _thread_loop(); + void _on_stop(); + void _on_stopped(); + + // record an error when session connecting or auth-ing. + void _session_error(int err_code); + // when client<->server channel created, start to record. + bool _record_begin(TP_SSH_CHANNEL_PAIR* cp); + // stop record because channel closed. + void _record_end(TP_SSH_CHANNEL_PAIR* cp); + + void _process_ssh_command(TP_SSH_CHANNEL_PAIR* cp, int from, const ex_u8* data, int len); + void _process_sftp_command(TP_SSH_CHANNEL_PAIR* cp, const ex_u8* data, int len); + +private: + void _run(void); + + void _close_channels(void); + void _check_channels(void); + + static int _on_auth_password_request(ssh_session session, const char *user, const char *password, void *userdata); + static ssh_channel _on_new_channel_request(ssh_session session, void *userdata); + static int _on_client_pty_request(ssh_session session, ssh_channel channel, const char *term, int x, int y, int px, int py, void *userdata); + static int _on_client_shell_request(ssh_session session, ssh_channel channel, void *userdata); + static void _on_client_channel_close(ssh_session session, ssh_channel channel, void* userdata); + static int _on_client_channel_data(ssh_session session, ssh_channel channel, void *data, unsigned int len, int is_stderr, void *userdata); + static int _on_client_pty_win_change(ssh_session session, ssh_channel channel, int width, int height, int pxwidth, int pwheight, void *userdata); + + static int _on_client_channel_subsystem_request(ssh_session session, ssh_channel channel, const char *subsystem, void *userdata); + static int _on_client_channel_exec_request(ssh_session session, ssh_channel channel, const char *command, void *userdata); + + static int _on_server_channel_data(ssh_session session, ssh_channel channel, void *data, unsigned int len, int is_stderr, void *userdata); + static void _on_server_channel_close(ssh_session session, ssh_channel channel, void* userdata); + +private: + SshProxy* m_proxy; + ssh_session m_cli_session; + ssh_session m_srv_session; + + ExThreadLock m_lock; + + ex_astr m_client_ip; + ex_u16 m_client_port; + + TPP_CONNECT_INFO* m_conn_info; + + 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_u32 m_flags; + int m_auth_type; + + bool m_is_logon; + + int m_ssh_ver; + + // 涓涓猻sh_session涓彲浠ユ墦寮澶氫釜ssh_channel + tp_channels m_channels; + + bool m_have_error; + + bool m_recving_from_srv; // 鏄惁姝e湪浠庢湇鍔″櫒鎺ユ敹鏁版嵁锛 + bool m_recving_from_cli; // 鏄惁姝e湪浠庡鎴风鎺ユ敹鏁版嵁锛 + + struct ssh_server_callbacks_struct m_srv_cb; + struct ssh_channel_callbacks_struct m_cli_channel_cb; + struct ssh_channel_callbacks_struct m_srv_channel_cb; +}; + +#endif // __SSH_SESSION_H__