diff --git a/common/libex/include/ex/ex_thread.h b/common/libex/include/ex/ex_thread.h
index 9c66e35..f3d4170 100644
--- a/common/libex/include/ex/ex_thread.h
+++ b/common/libex/include/ex/ex_thread.h
@@ -31,10 +31,12 @@ public:
bool terminate(void);
protected:
- // 线程循环
+ // main loop of this thread.
virtual void _thread_loop(void) = 0;
- // 设置停止标志,让线程能够正常结束
- virtual void _set_stop_flag(void) = 0;
+ // called by another thread when thread ready to stop.
+ virtual void _on_stop(void) {};
+ // called inside thread when thread fully stopped.
+ virtual void _on_stopped(void) {};
#ifdef EX_OS_WIN32
static unsigned int WINAPI _thread_func(LPVOID lpParam);
@@ -46,7 +48,7 @@ protected:
ex_astr m_thread_name;
EX_THREAD_HANDLE m_handle;
bool m_is_running;
- bool m_stop_flag;
+ bool m_need_stop;
};
diff --git a/common/libex/src/ex_thread.cpp b/common/libex/src/ex_thread.cpp
index 3641a92..e3a8089 100644
--- a/common/libex/src/ex_thread.cpp
+++ b/common/libex/src/ex_thread.cpp
@@ -9,90 +9,91 @@
#ifdef EX_OS_WIN32
unsigned int WINAPI ExThreadBase::_thread_func(LPVOID pParam)
#else
-void* ExThreadBase::_thread_func(void* pParam)
+
+void *ExThreadBase::_thread_func(void *pParam)
#endif
{
- ExThreadBase* p = (ExThreadBase*)pParam;
- ex_astr thread_name = p->m_thread_name;
- p->m_is_running = true;
- p->_thread_loop();
- p->m_is_running = false;
-// if(!p->m_stop_by_request)
-// p->m_thread_manager->_remove_thread(p);
+ ExThreadBase *_this = (ExThreadBase *) pParam;
- EXLOGV(" # thread [%s] end.\n", thread_name.c_str());
+ _this->m_is_running = true;
+ _this->_thread_loop();
+ _this->m_is_running = false;
+ _this->m_handle = 0;
- return 0;
+ _this->_on_stopped();
+
+ EXLOGV(" # thread [%s] exit.\n", _this->m_thread_name.c_str());
+ return 0;
}
-ExThreadBase::ExThreadBase(const char* thread_name) :
- m_handle(0),
- m_is_running(false),
- m_stop_flag(false)
-{
- m_thread_name = thread_name;
+ExThreadBase::ExThreadBase(const char *thread_name) :
+ m_handle(0),
+ m_is_running(false),
+ m_need_stop(false) {
+ m_thread_name = thread_name;
}
-ExThreadBase::~ExThreadBase()
-{
+ExThreadBase::~ExThreadBase() {
+ if(m_is_running) {
+ EXLOGE(" # thread [%s] not stop before destroy.\n", m_thread_name.c_str());
+ }
}
-bool ExThreadBase::start(void)
-{
- EXLOGV(" . thread [%s] starting.\n", m_thread_name.c_str());
+bool ExThreadBase::start(void) {
+ m_need_stop = false;
+ EXLOGV(" . thread [%s] starting.\n", m_thread_name.c_str());
#ifdef WIN32
- HANDLE h = (HANDLE)_beginthreadex(NULL, 0, _thread_func, (void*)this, 0, NULL);
+ HANDLE h = (HANDLE)_beginthreadex(NULL, 0, _thread_func, (void*)this, 0, NULL);
- if (NULL == h)
- {
- return false;
- }
- m_handle = h;
+ if (NULL == h)
+ {
+ return false;
+ }
+ m_listener_handle = h;
#else
- pthread_t ptid = 0;
- int ret = pthread_create(&ptid, NULL, _thread_func, (void*)this);
- if (ret != 0)
- {
- return false;
- }
- m_handle = ptid;
+ pthread_t ptid = 0;
+ int ret = pthread_create(&ptid, NULL, _thread_func, (void *) this);
+ if (ret != 0) {
+ return false;
+ }
+ m_handle = ptid;
#endif
- return true;
+ return true;
}
-bool ExThreadBase::stop(void)
-{
- EXLOGV("[thread] try to stop thread [%s].\n", m_thread_name.c_str());
- _set_stop_flag();
+bool ExThreadBase::stop(void) {
+ if (m_handle == 0) {
+ EXLOGW("[thread] thread [%s] already stopped.\n", m_thread_name.c_str());
+ return true;
+ }
- EXLOGV("[thread] wait thread [%s] end.\n", m_thread_name.c_str());
+ EXLOGV("[thread] try to stop thread [%s].\n", m_thread_name.c_str());
+ m_need_stop = true;
+ _on_stop();
- if(m_handle == 0)
- return true;
+ EXLOGV("[thread] wait thread [%s] exit.\n", m_thread_name.c_str());
#ifdef EX_OS_WIN32
- if (WaitForSingleObject(m_handle, INFINITE) != WAIT_OBJECT_0)
- {
- return false;
- }
+ if (WaitForSingleObject(m_listener_handle, INFINITE) != WAIT_OBJECT_0)
+ {
+ return false;
+ }
#else
- if (pthread_join(m_handle, NULL) != 0)
- {
- return false;
- }
+ if (pthread_join(m_handle, NULL) != 0) {
+ return false;
+ }
#endif
- return true;
+ return true;
}
-bool ExThreadBase::terminate(void)
-{
+bool ExThreadBase::terminate(void) {
#ifdef EX_OS_WIN32
- return TerminateThread(m_handle, 1) ? true : false;
+ return (TerminateThread(m_listener_handle, 1) == TRUE);
#else
- return pthread_cancel(m_handle) == 0 ? true : false;
+ return (pthread_cancel(m_handle) == 0);
#endif
}
@@ -100,105 +101,89 @@ bool ExThreadBase::terminate(void)
//
//=========================================================
-ExThreadManager::ExThreadManager()
-{}
+ExThreadManager::ExThreadManager() {}
-ExThreadManager::~ExThreadManager()
-{
- if (m_threads.size() > 0)
- {
- EXLOGE("when destroy thread manager, there are %d thread not exit.\n", m_threads.size());
- stop_all();
- }
+ExThreadManager::~ExThreadManager() {
+ if (!m_threads.empty()) {
+ EXLOGE("when destroy thread manager, there are %d thread not exit.\n", m_threads.size());
+ stop_all();
+ }
}
-void ExThreadManager::stop_all(void)
-{
- ExThreadSmartLock locker(m_lock);
+void ExThreadManager::stop_all(void) {
+ ExThreadSmartLock locker(m_lock);
- ex_threads::iterator it = m_threads.begin();
- for (; it != m_threads.end(); ++it)
- {
- (*it)->stop();
- }
- m_threads.clear();
+ ex_threads::iterator it = m_threads.begin();
+ for (; it != m_threads.end(); ++it) {
+ (*it)->stop();
+ }
+ m_threads.clear();
}
-void ExThreadManager::add(ExThreadBase* tb)
-{
- ExThreadSmartLock locker(m_lock);
+void ExThreadManager::add(ExThreadBase *tb) {
+ ExThreadSmartLock locker(m_lock);
- ex_threads::iterator it = m_threads.begin();
- for (; it != m_threads.end(); ++it)
- {
- if ((*it) == tb)
- {
- EXLOGE("when add thread to manager, it already exist.\n");
- return;
- }
- }
+ ex_threads::iterator it = m_threads.begin();
+ for (; it != m_threads.end(); ++it) {
+ if ((*it) == tb) {
+ EXLOGE("when add thread to manager, it already exist.\n");
+ return;
+ }
+ }
- m_threads.push_back(tb);
+ m_threads.push_back(tb);
}
-void ExThreadManager::remove(ExThreadBase* tb)
-{
- ExThreadSmartLock locker(m_lock);
+void ExThreadManager::remove(ExThreadBase *tb) {
+ ExThreadSmartLock locker(m_lock);
- ex_threads::iterator it = m_threads.begin();
- for (; it != m_threads.end(); ++it)
- {
- if ((*it) == tb)
- {
- //delete (*it);
- m_threads.erase(it);
- return;
- }
- }
- EXLOGE("when remove thread from manager, it not exist.\n");
+ ex_threads::iterator it = m_threads.begin();
+ for (; it != m_threads.end(); ++it) {
+ if ((*it) == tb) {
+ m_threads.erase(it);
+ return;
+ }
+ }
+ EXLOGE("thread not hold by thread-manager while remove it.\n");
}
//=========================================================
//
//=========================================================
-ExThreadLock::ExThreadLock()
-{
+ExThreadLock::ExThreadLock() {
#ifdef EX_OS_WIN32
- InitializeCriticalSection(&m_locker);
+ InitializeCriticalSection(&m_locker);
#else
- pthread_mutexattr_t attr;
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
- pthread_mutex_init(&m_locker, &attr);
- pthread_mutexattr_destroy(&attr);
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(&m_locker, &attr);
+ pthread_mutexattr_destroy(&attr);
#endif
}
-ExThreadLock::~ExThreadLock()
-{
+ExThreadLock::~ExThreadLock() {
#ifdef EX_OS_WIN32
- DeleteCriticalSection(&m_locker);
+ DeleteCriticalSection(&m_locker);
#else
- pthread_mutex_destroy(&m_locker);
+ pthread_mutex_destroy(&m_locker);
#endif
}
-void ExThreadLock::lock(void)
-{
+void ExThreadLock::lock(void) {
#ifdef EX_OS_WIN32
- EnterCriticalSection(&m_locker);
+ EnterCriticalSection(&m_locker);
#else
- pthread_mutex_lock(&m_locker);
+ pthread_mutex_lock(&m_locker);
#endif
}
-void ExThreadLock::unlock(void)
-{
+void ExThreadLock::unlock(void) {
#ifdef EX_OS_WIN32
- LeaveCriticalSection(&m_locker);
+ LeaveCriticalSection(&m_locker);
#else
- pthread_mutex_unlock(&m_locker);
+ pthread_mutex_unlock(&m_locker);
#endif
}
@@ -206,39 +191,35 @@ void ExThreadLock::unlock(void)
//
//=========================================================
-int ex_atomic_add(volatile int* pt, int t)
-{
+int ex_atomic_add(volatile int *pt, int t) {
#ifdef EX_OS_WIN32
- return (int)InterlockedExchangeAdd((long*)pt, (long)t);
+ return (int)InterlockedExchangeAdd((long*)pt, (long)t);
#else
- return __sync_add_and_fetch(pt, t);
+ return __sync_add_and_fetch(pt, t);
#endif
}
-int ex_atomic_inc(volatile int* pt)
-{
+int ex_atomic_inc(volatile int *pt) {
#ifdef EX_OS_WIN32
- return (int)InterlockedIncrement((long*)pt);
+ return (int)InterlockedIncrement((long*)pt);
#else
- return __sync_add_and_fetch(pt, 1);
+ return __sync_add_and_fetch(pt, 1);
#endif
}
-int ex_atomic_dec(volatile int* pt)
-{
+int ex_atomic_dec(volatile int *pt) {
#ifdef EX_OS_WIN32
- return (int)InterlockedDecrement((long*)pt);
+ return (int)InterlockedDecrement((long*)pt);
#else
- return __sync_add_and_fetch(pt, -1);
+ return __sync_add_and_fetch(pt, -1);
#endif
}
-ex_u64 ex_get_thread_id(void)
-{
+ex_u64 ex_get_thread_id(void) {
#ifdef EX_OS_WIN32
- return GetCurrentThreadId();
+ return GetCurrentThreadId();
#else
- return (ex_u64)pthread_self();
+ return (ex_u64) pthread_self();
#endif
}
diff --git a/server/.idea/encodings.xml b/server/.idea/encodings.xml
index 6230eb5..de095c5 100644
--- a/server/.idea/encodings.xml
+++ b/server/.idea/encodings.xml
@@ -31,11 +31,9 @@
-
-
-
+
@@ -43,7 +41,10 @@
+
+
+
diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt
index 92b3a9e..5b06ff7 100644
--- a/server/CMakeLists.txt
+++ b/server/CMakeLists.txt
@@ -4,7 +4,8 @@ project(teleport)
MESSAGE(STATUS "operation system is ${CMAKE_SYSTEM}")
MESSAGE(STATUS "current source directory is ${CMAKE_CURRENT_SOURCE_DIR}")
-set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${teleport_SOURCE_DIR}/../out/server/x64/bin")
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../out/server/x64/bin")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../out/server/x64/bin")
set(CMAKE_CONFIGURATION_TYPES Debug Release)
@@ -13,13 +14,13 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
MESSAGE(STATUS "build on macOS...")
set(OS_MACOS 1)
set(OS_POSIX 1)
- set(TP_EXTERNAL_RELEASE_DIR "${teleport_SOURCE_DIR}/../external/macos/release")
+ set(TP_EXTERNAL_RELEASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../external/macos/release")
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
set(OS_LINUX 1)
set(OS_POSIX 1)
MESSAGE(STATUS "build on Linux...")
add_subdirectory(tp_web/src)
- set(TP_EXTERNAL_RELEASE_DIR "${teleport_SOURCE_DIR}/../external/linux/release")
+ set(TP_EXTERNAL_RELEASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../external/linux/release")
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
MESSAGE(FATAL_ERROR "unsupported platform: Windows")
else()
diff --git a/server/tp_core/core/main.cpp b/server/tp_core/core/main.cpp
index 5e89d56..acc8ea7 100644
--- a/server/tp_core/core/main.cpp
+++ b/server/tp_core/core/main.cpp
@@ -359,9 +359,8 @@ void _sig_handler(int signum, siginfo_t* info, void* ptr)
{
if (signum == SIGINT || signum == SIGTERM)
{
- EXLOGW("[core] received signal SIGINT, exit now.\n");
+ EXLOGW("\n[core] received signal SIGINT, exit now.\n");
g_exit_flag = true;
- // exit(1);
}
}
diff --git a/server/tp_core/core/ts_http_rpc.cpp b/server/tp_core/core/ts_http_rpc.cpp
index 7ab2264..91ae096 100644
--- a/server/tp_core/core/ts_http_rpc.cpp
+++ b/server/tp_core/core/ts_http_rpc.cpp
@@ -62,7 +62,7 @@ void TsHttpRpc::_thread_loop(void)
{
EXLOGI("[core] TeleportServer-RPC ready on %s:%d\n", m_host_ip.c_str(), m_host_port);
- while (!m_stop_flag)
+ while (!m_need_stop)
{
mg_mgr_poll(&m_mg_mgr, 500);
}
@@ -70,10 +70,6 @@ void TsHttpRpc::_thread_loop(void)
EXLOGV("[core] rpc main loop end.\n");
}
-void TsHttpRpc::_set_stop_flag(void)
-{
- m_stop_flag = true;
-}
bool TsHttpRpc::init(void)
{
diff --git a/server/tp_core/core/ts_http_rpc.h b/server/tp_core/core/ts_http_rpc.h
index c99c241..fc19d2e 100644
--- a/server/tp_core/core/ts_http_rpc.h
+++ b/server/tp_core/core/ts_http_rpc.h
@@ -20,7 +20,6 @@ public:
protected:
void _thread_loop(void);
- void _set_stop_flag(void);
private:
ex_rv _parse_request(struct http_message* req, ex_astr& func_cmd, Json::Value& json_param);
diff --git a/server/tp_core/core/ts_main.cpp b/server/tp_core/core/ts_main.cpp
index e8dfb44..1d7e8b6 100644
--- a/server/tp_core/core/ts_main.cpp
+++ b/server/tp_core/core/ts_main.cpp
@@ -10,96 +10,93 @@
bool g_exit_flag = false;
-TPP_CONNECT_INFO* tpp_get_connect_info(const char* sid)
-{
- TS_CONNECT_INFO sinfo;
- bool ret = g_session_mgr.get_connect_info(sid, sinfo);
- if (!ret)
- return NULL;
+TPP_CONNECT_INFO *tpp_get_connect_info(const char *sid) {
+ TS_CONNECT_INFO sinfo;
+ bool ret = g_session_mgr.get_connect_info(sid, sinfo);
+ if (!ret)
+ return NULL;
- TPP_CONNECT_INFO* info = (TPP_CONNECT_INFO*)calloc(1, sizeof(TPP_CONNECT_INFO));
-
- info->sid = (char*)calloc(1, sinfo.sid.length() + 1);
- ex_strcpy(info->sid, sinfo.sid.length() + 1, sinfo.sid.c_str());
- info->user_username = (char*)calloc(1, sinfo.user_username.length() + 1);
- ex_strcpy(info->user_username, sinfo.user_username.length() + 1, sinfo.user_username.c_str());
- info->host_ip = (char*)calloc(1, sinfo.host_ip.length() + 1);
- ex_strcpy(info->host_ip, sinfo.host_ip.length() + 1, sinfo.host_ip.c_str());
- info->conn_ip = (char*)calloc(1, sinfo.conn_ip.length() + 1);
- ex_strcpy(info->conn_ip, sinfo.conn_ip.length() + 1, sinfo.conn_ip.c_str());
- info->client_ip = (char*)calloc(1, sinfo.client_ip.length() + 1);
- ex_strcpy(info->client_ip, sinfo.client_ip.length() + 1, sinfo.client_ip.c_str());
- info->acc_username = (char*)calloc(1, sinfo.acc_username.length() + 1);
- ex_strcpy(info->acc_username, sinfo.acc_username.length() + 1, sinfo.acc_username.c_str());
- info->acc_secret = (char*)calloc(1, sinfo.acc_secret.length() + 1);
- ex_strcpy(info->acc_secret, sinfo.acc_secret.length() + 1, sinfo.acc_secret.c_str());
- info->username_prompt = (char*)calloc(1, sinfo.username_prompt.length() + 1);
- ex_strcpy(info->username_prompt, sinfo.username_prompt.length() + 1, sinfo.username_prompt.c_str());
- info->password_prompt = (char*)calloc(1, sinfo.password_prompt.length() + 1);
- ex_strcpy(info->password_prompt, sinfo.password_prompt.length() + 1, sinfo.password_prompt.c_str());
+ TPP_CONNECT_INFO *info = (TPP_CONNECT_INFO *) calloc(1, sizeof(TPP_CONNECT_INFO));
- info->user_id = sinfo.user_id;
- info->host_id = sinfo.host_id;
- info->acc_id = sinfo.acc_id;
- info->conn_port = sinfo.conn_port;
- info->protocol_type = sinfo.protocol_type;
- info->protocol_sub_type = sinfo.protocol_sub_type;
- info->protocol_flag = sinfo.protocol_flag;
- info->record_flag = sinfo.record_flag;
- info->auth_type= sinfo.auth_type;
+ info->sid = (char *) calloc(1, sinfo.sid.length() + 1);
+ ex_strcpy(info->sid, sinfo.sid.length() + 1, sinfo.sid.c_str());
+ info->user_username = (char *) calloc(1, sinfo.user_username.length() + 1);
+ ex_strcpy(info->user_username, sinfo.user_username.length() + 1, sinfo.user_username.c_str());
+ info->host_ip = (char *) calloc(1, sinfo.host_ip.length() + 1);
+ ex_strcpy(info->host_ip, sinfo.host_ip.length() + 1, sinfo.host_ip.c_str());
+ info->conn_ip = (char *) calloc(1, sinfo.conn_ip.length() + 1);
+ ex_strcpy(info->conn_ip, sinfo.conn_ip.length() + 1, sinfo.conn_ip.c_str());
+ info->client_ip = (char *) calloc(1, sinfo.client_ip.length() + 1);
+ ex_strcpy(info->client_ip, sinfo.client_ip.length() + 1, sinfo.client_ip.c_str());
+ info->acc_username = (char *) calloc(1, sinfo.acc_username.length() + 1);
+ ex_strcpy(info->acc_username, sinfo.acc_username.length() + 1, sinfo.acc_username.c_str());
+ info->acc_secret = (char *) calloc(1, sinfo.acc_secret.length() + 1);
+ ex_strcpy(info->acc_secret, sinfo.acc_secret.length() + 1, sinfo.acc_secret.c_str());
+ info->username_prompt = (char *) calloc(1, sinfo.username_prompt.length() + 1);
+ ex_strcpy(info->username_prompt, sinfo.username_prompt.length() + 1, sinfo.username_prompt.c_str());
+ info->password_prompt = (char *) calloc(1, sinfo.password_prompt.length() + 1);
+ ex_strcpy(info->password_prompt, sinfo.password_prompt.length() + 1, sinfo.password_prompt.c_str());
- return info;
+ info->user_id = sinfo.user_id;
+ info->host_id = sinfo.host_id;
+ info->acc_id = sinfo.acc_id;
+ info->conn_port = sinfo.conn_port;
+ info->protocol_type = sinfo.protocol_type;
+ info->protocol_sub_type = sinfo.protocol_sub_type;
+ info->protocol_flag = sinfo.protocol_flag;
+ info->record_flag = sinfo.record_flag;
+ info->auth_type = sinfo.auth_type;
+
+ return info;
}
-void tpp_free_connect_info(TPP_CONNECT_INFO* info)
-{
- if (NULL == info)
- return;
+void tpp_free_connect_info(TPP_CONNECT_INFO *info) {
+ if (NULL == info)
+ return;
- g_session_mgr.free_connect_info(info->sid);
+ g_session_mgr.free_connect_info(info->sid);
- free(info->sid);
- free(info->user_username);
- free(info->host_ip);
- free(info->conn_ip);
- free(info->client_ip);
- free(info->acc_username);
- free(info->acc_secret);
- free(info->username_prompt);
- free(info->password_prompt);
- free(info);
+ free(info->sid);
+ free(info->user_username);
+ free(info->host_ip);
+ free(info->conn_ip);
+ free(info->client_ip);
+ free(info->acc_username);
+ free(info->acc_secret);
+ free(info->username_prompt);
+ free(info->password_prompt);
+ free(info);
}
-bool tpp_session_begin(const TPP_CONNECT_INFO* info, int* db_id)
-{
- if (NULL == info || NULL == db_id)
- return false;
+bool tpp_session_begin(const TPP_CONNECT_INFO *info, int *db_id) {
+ if (NULL == info || NULL == db_id)
+ return false;
- TS_CONNECT_INFO sinfo;
- sinfo.sid = info->sid;
- sinfo.user_id = info->user_id;
- sinfo.host_id = info->host_id;
- sinfo.acc_id = info->acc_id;
- sinfo.user_username = info->user_username;
- sinfo.host_ip = info->host_ip;
- sinfo.conn_ip = info->conn_ip;
- sinfo.client_ip = info->client_ip;
- sinfo.acc_username = info->acc_username;
+ TS_CONNECT_INFO sinfo;
+ sinfo.sid = info->sid;
+ sinfo.user_id = info->user_id;
+ sinfo.host_id = info->host_id;
+ sinfo.acc_id = info->acc_id;
+ sinfo.user_username = info->user_username;
+ sinfo.host_ip = info->host_ip;
+ sinfo.conn_ip = info->conn_ip;
+ sinfo.client_ip = info->client_ip;
+ sinfo.acc_username = info->acc_username;
- sinfo.conn_port = info->conn_port;
- sinfo.protocol_type = info->protocol_type;
- sinfo.protocol_sub_type = info->protocol_sub_type;
- sinfo.auth_type = info->auth_type;
+ sinfo.conn_port = info->conn_port;
+ sinfo.protocol_type = info->protocol_type;
+ sinfo.protocol_sub_type = info->protocol_sub_type;
+ sinfo.auth_type = info->auth_type;
- return ts_web_rpc_session_begin(sinfo, *db_id);
+ return ts_web_rpc_session_begin(sinfo, *db_id);
}
bool tpp_session_update(int db_id, int protocol_sub_type, int state) {
- return ts_web_rpc_session_update(db_id, protocol_sub_type, state);
+ return ts_web_rpc_session_update(db_id, protocol_sub_type, state);
}
-bool tpp_session_end(const char* sid, int db_id, int ret) {
- return ts_web_rpc_session_end(sid, db_id, ret);
+bool tpp_session_end(const char *sid, int db_id, int ret) {
+ return ts_web_rpc_session_end(sid, db_id, ret);
}
// typedef struct TPP_LIB
@@ -246,87 +243,78 @@ bool tpp_session_end(const char* sid, int db_id, int ret) {
// }
// }
-int ts_main(void)
-{
- ExIniFile& ini = g_env.get_ini();
+int ts_main(void) {
+ ExIniFile &ini = g_env.get_ini();
- EXLOGI(L"\n");
- EXLOGI(L"###############################################################\n");
- EXLOGI(L"Load config file: %ls.\n", ini.get_filename().c_str());
- EXLOGI(L"Teleport Core Server starting ...\n");
+ EXLOGI(L"\n");
+ EXLOGI(L"###############################################################\n");
+ EXLOGI(L"Load config file: %ls.\n", ini.get_filename().c_str());
+ EXLOGI(L"Teleport Core Server starting ...\n");
- ex_ini_sections& secs = ini.GetAllSections();
- TsHttpRpc rpc;
+ ex_ini_sections &secs = ini.GetAllSections();
+ TsHttpRpc rpc;
- // 枚举配置文件中的[protocol-xxx]小节,加载对应的协议动态库
- bool all_ok = true;
+ // 枚举配置文件中的[protocol-xxx]小节,加载对应的协议动态库
+ bool all_ok = true;
- do {
- if (!g_session_mgr.start())
- {
- EXLOGE(L"[core] failed to start session-id manager.\n");
- all_ok = false;
- break;
- }
+ do {
+ if (!g_session_mgr.start()) {
+ EXLOGE(L"[core] failed to start session-id manager.\n");
+ all_ok = false;
+ break;
+ }
- if (!rpc.init() || !rpc.start())
- {
- EXLOGE(L"[core] rpc init/start failed.\n");
- all_ok = false;
- break;
- }
+ if (!rpc.init() || !rpc.start()) {
+ EXLOGE(L"[core] rpc init/start failed.\n");
+ all_ok = false;
+ break;
+ }
- ex_ini_sections::iterator it = secs.begin();
- for (; it != secs.end(); ++it)
- {
- if (it->first.length() > 9 && 0 == wcsncmp(it->first.c_str(), L"protocol-", 9))
- {
- ex_wstr libname;
- if (!it->second->GetStr(L"lib", libname))
- continue;
+ ex_ini_sections::iterator it = secs.begin();
+ for (; it != secs.end(); ++it) {
+ if (it->first.length() > 9 && 0 == wcsncmp(it->first.c_str(), L"protocol-", 9)) {
+ ex_wstr libname;
+ if (!it->second->GetStr(L"lib", libname))
+ continue;
- bool enabled = false;
- it->second->GetBool(L"enabled", enabled, false);
- if (!enabled)
- {
- EXLOGV(L"[core] `%ls` not enabled.\n", libname.c_str());
- continue;
- }
+ bool enabled = false;
+ it->second->GetBool(L"enabled", enabled, false);
+ if (!enabled) {
+ EXLOGV(L"[core] `%ls` not enabled.\n", libname.c_str());
+ continue;
+ }
- if (!g_tpp_mgr.load_tpp(libname))
- {
- all_ok = false;
- break;
- }
- }
- }
+ if (!g_tpp_mgr.load_tpp(libname)) {
+ all_ok = false;
+ break;
+ }
+ }
+ }
- } while (0);
+ } while (0);
- if (0 == g_tpp_mgr.count())
- {
- all_ok = false;
- }
+ if (0 == g_tpp_mgr.count()) {
+ all_ok = false;
+ }
- if (!all_ok)
- {
- g_exit_flag = true;
- }
+ if (!all_ok) {
+ g_exit_flag = true;
+ }
- if (!g_exit_flag) {
- ts_web_rpc_register_core();
+ if (!g_exit_flag) {
+ ts_web_rpc_register_core();
- EXLOGV("[core] ---- initialized, ready for service ----\n");
- while (!g_exit_flag)
- {
- ex_sleep_ms(1000);
- g_tpp_mgr.timer();
- }
- }
+ EXLOGV("[core] ---- initialized, ready for service ----\n");
+ while (!g_exit_flag) {
+ ex_sleep_ms(1000);
+ g_tpp_mgr.timer();
+ }
+ }
- g_tpp_mgr.stop_all();
- rpc.stop();
- g_session_mgr.stop();
+ EXLOGW("[core] try to stop all thread and exit.\n");
+ g_tpp_mgr.stop_all();
+ rpc.stop();
+ g_session_mgr.stop();
- return 0;
+ return 0;
}
diff --git a/server/tp_core/core/ts_session.cpp b/server/tp_core/core/ts_session.cpp
index a708e1b..deee94f 100644
--- a/server/tp_core/core/ts_session.cpp
+++ b/server/tp_core/core/ts_session.cpp
@@ -7,188 +7,166 @@
TsSessionManager g_session_mgr;
TsSessionManager::TsSessionManager() :
- ExThreadBase("sid-mgr-thread")
-{
+ ExThreadBase("sid-mgr-thread") {
}
-TsSessionManager::~TsSessionManager()
-{
- ts_connections::iterator it_conn = m_connections.begin();
- for (; it_conn != m_connections.end(); ++it_conn)
- {
- delete it_conn->second;
- }
- m_connections.clear();
+TsSessionManager::~TsSessionManager() {
+ ts_connections::iterator it_conn = m_connections.begin();
+ for (; it_conn != m_connections.end(); ++it_conn) {
+ delete it_conn->second;
+ }
+ m_connections.clear();
}
-void TsSessionManager::_thread_loop(void)
-{
- for (;;)
- {
- ex_sleep_ms(1000);
- if (m_stop_flag)
- return;
- _remove_expired_connect_info();
- }
+void TsSessionManager::_thread_loop(void) {
+ for (;;) {
+ ex_sleep_ms(1000);
+ if (m_need_stop)
+ return;
+ _remove_expired_connect_info();
+ }
}
-void TsSessionManager::_set_stop_flag(void)
-{
- m_stop_flag = true;
+void TsSessionManager::_remove_expired_connect_info(void) {
+ // 超过15秒未进行连接的connect-info会被移除
+
+ ExThreadSmartLock locker(m_lock);
+
+ ex_u64 _now = ex_get_tick_count();
+ ts_connections::iterator it = m_connections.begin();
+ for (; it != m_connections.end();) {
+ //EXLOGD("[core] check expired connect info: [%s] %d, %d %d %d\n", it->first.c_str(), it->second->ref_count, int(_now), int(it->second->ticket_start), int(_now - it->second->ticket_start));
+ if (it->second->ref_count == 0 && _now - 15000 > it->second->ticket_start) {
+ EXLOGD("[core] remove connection info, because timeout: %s\n", it->first.c_str());
+ delete it->second;
+ m_connections.erase(it++);
+ EXLOGD("[core] there are %d connection info exists.\n", m_connections.size());
+ } else {
+ ++it;
+ }
+ }
}
+bool TsSessionManager::get_connect_info(const ex_astr &sid, TS_CONNECT_INFO &info) {
+ ExThreadSmartLock locker(m_lock);
-void TsSessionManager::_remove_expired_connect_info(void)
-{
- // 超过15秒未进行连接的connect-info会被移除
+ ts_connections::iterator it = m_connections.find(sid);
+ if (it == m_connections.end())
+ return false;
- ExThreadSmartLock locker(m_lock);
+ info.sid = it->second->sid;
+ info.user_id = it->second->user_id;
+ info.host_id = it->second->host_id;
+ info.acc_id = it->second->acc_id;
+ info.user_username = it->second->user_username;
+ info.host_ip = it->second->host_ip;
+ info.conn_ip = it->second->conn_ip;
+ info.conn_port = it->second->conn_port;
+ info.client_ip = it->second->client_ip;
+ info.acc_username = it->second->acc_username;
+ info.acc_secret = it->second->acc_secret;
+ info.username_prompt = it->second->username_prompt;
+ info.password_prompt = it->second->password_prompt;
+ info.protocol_type = it->second->protocol_type;
+ info.protocol_sub_type = it->second->protocol_sub_type;
+ info.protocol_flag = it->second->protocol_flag;
+ info.record_flag = it->second->record_flag;
+ info.auth_type = it->second->auth_type;
- ex_u64 _now = ex_get_tick_count();
- ts_connections::iterator it = m_connections.begin();
- for (; it != m_connections.end(); )
- {
- //EXLOGD("[core] check expired connect info: [%s] %d, %d %d %d\n", it->first.c_str(), it->second->ref_count, int(_now), int(it->second->ticket_start), int(_now - it->second->ticket_start));
- if (it->second->ref_count == 0 && _now - 15000 > it->second->ticket_start)
- {
- EXLOGD("[core] remove connection info, because timeout: %s\n", it->first.c_str());
- delete it->second;
- m_connections.erase(it++);
- EXLOGD("[core] there are %d connection info exists.\n", m_connections.size());
- }
- else
- {
- ++it;
- }
- }
+ it->second->ref_count++;
+
+ return true;
}
-bool TsSessionManager::get_connect_info(const ex_astr& sid, TS_CONNECT_INFO& info)
-{
- ExThreadSmartLock locker(m_lock);
+bool TsSessionManager::free_connect_info(const ex_astr &sid) {
+ ExThreadSmartLock locker(m_lock);
- ts_connections::iterator it = m_connections.find(sid);
- if (it == m_connections.end())
- return false;
+ ts_connections::iterator it = m_connections.find(sid);
+ if (it == m_connections.end())
+ return false;
- info.sid = it->second->sid;
- info.user_id = it->second->user_id;
- info.host_id = it->second->host_id;
- info.acc_id = it->second->acc_id;
- info.user_username = it->second->user_username;
- info.host_ip = it->second->host_ip;
- info.conn_ip = it->second->conn_ip;
- info.conn_port = it->second->conn_port;
- info.client_ip = it->second->client_ip;
- info.acc_username = it->second->acc_username;
- info.acc_secret = it->second->acc_secret;
- info.username_prompt = it->second->username_prompt;
- info.password_prompt = it->second->password_prompt;
- info.protocol_type = it->second->protocol_type;
- info.protocol_sub_type = it->second->protocol_sub_type;
- info.protocol_flag = it->second->protocol_flag;
- info.record_flag = it->second->record_flag;
- info.auth_type = it->second->auth_type;
+ it->second->ref_count--;
- it->second->ref_count++;
+ // 对于RDP来说,此时不要移除连接信息,系统自带RDP客户端在第一次连接时进行协议协商,然后马上会断开,之后立即重新连接一次(第二次连接之前可能会提示证书信息,如果用户长时间不操作,可能会导致超时)。
+ // 因此,我们将其引用计数减低,并更新一下最后访问时间,让定时器来移除它。
+ if (it->second->protocol_type != TP_PROTOCOL_TYPE_RDP) {
+ if (it->second->ref_count <= 0) {
+ EXLOGD("[core] remove connection info, because all connections closed: %s\n", it->first.c_str());
+ delete it->second;
+ m_connections.erase(it);
+ EXLOGD("[core] there are %d connection info exists.\n", m_connections.size());
+ }
+ } else {
+ if (it->second->ref_count == 1)
+ it->second->ref_count = 0;
+ it->second->ticket_start = ex_get_tick_count() + 45000; // 我们将时间向后移动45秒,这样如果没有发生RDP的第二次连接,这个连接信息就会在一分钟后被清除。
+ }
- return true;
+
+ return true;
}
-bool TsSessionManager::free_connect_info(const ex_astr& sid) {
- ExThreadSmartLock locker(m_lock);
+bool TsSessionManager::request_session(ex_astr &sid, TS_CONNECT_INFO *info) {
+ ExThreadSmartLock locker(m_lock);
- ts_connections::iterator it = m_connections.find(sid);
- if (it == m_connections.end())
- return false;
+ EXLOGD("[core] request session: account: [%s], protocol: [%d], auth-mode: [%d]\n", info->acc_username.c_str(),
+ info->protocol_type, info->auth_type);
- it->second->ref_count--;
+ ex_astr _sid;
+ int retried = 0;
+ ts_connections::iterator it;
+ for (;;) {
+ _gen_session_id(_sid, info, 6);
+ it = m_connections.find(_sid);
+ if (it == m_connections.end())
+ break;
- // 对于RDP来说,此时不要移除连接信息,系统自带RDP客户端在第一次连接时进行协议协商,然后马上会断开,之后立即重新连接一次(第二次连接之前可能会提示证书信息,如果用户长时间不操作,可能会导致超时)。
- // 因此,我们将其引用计数减低,并更新一下最后访问时间,让定时器来移除它。
- if (it->second->protocol_type != TP_PROTOCOL_TYPE_RDP) {
- if (it->second->ref_count <= 0) {
- EXLOGD("[core] remove connection info, because all connections closed: %s\n", it->first.c_str());
- delete it->second;
- m_connections.erase(it);
- EXLOGD("[core] there are %d connection info exists.\n", m_connections.size());
- }
- }
- else {
- if (it->second->ref_count == 1)
- it->second->ref_count = 0;
- it->second->ticket_start = ex_get_tick_count() + 45000; // 我们将时间向后移动45秒,这样如果没有发生RDP的第二次连接,这个连接信息就会在一分钟后被清除。
- }
+ retried++;
+ if (retried > 50)
+ return false;
+ }
+ info->sid = _sid;
+ info->ref_count = 0;
+ info->ticket_start = ex_get_tick_count();
+ m_connections.insert(std::make_pair(_sid, info));
- return true;
+ sid = _sid;
+ if (info->protocol_type == TP_PROTOCOL_TYPE_RDP) {
+ info->ref_count = 1; // 因为RDP连接之前可能会有很长时间用于确认是否连接、是否信任证书,所以很容易超时,我们认为将引用计数+1,防止因超时被清除。
+ char szTmp[8] = {0};
+ snprintf(szTmp, 8, "%02X", (unsigned char) (info->acc_username.length() + info->acc_secret.length()));
+ sid += szTmp;
+ }
+
+ return true;
}
-bool TsSessionManager::request_session(ex_astr& sid, TS_CONNECT_INFO* info)
-{
- ExThreadSmartLock locker(m_lock);
+void TsSessionManager::_gen_session_id(ex_astr &sid, const TS_CONNECT_INFO *info, int len) {
+ mbedtls_sha1_context sha;
+ ex_u8 sha_digist[20] = {0};
- EXLOGD("[core] request session: account: [%s], protocol: [%d], auth-mode: [%d]\n", info->acc_username.c_str(), info->protocol_type, info->auth_type);
+ ex_u64 _tick = ex_get_tick_count();
+ ex_u64 _tid = ex_get_thread_id();
- ex_astr _sid;
- int retried = 0;
- ts_connections::iterator it;
- for (;;)
- {
- _gen_session_id(_sid, info, 6);
- it = m_connections.find(_sid);
- if (it == m_connections.end())
- break;
+ mbedtls_sha1_init(&sha);
+ mbedtls_sha1_starts(&sha);
+ mbedtls_sha1_update(&sha, (const unsigned char *) &_tick, sizeof(ex_u64));
+ mbedtls_sha1_update(&sha, (const unsigned char *) &_tid, sizeof(ex_u64));
+ mbedtls_sha1_update(&sha, (const unsigned char *) info->conn_ip.c_str(), info->conn_ip.length());
+ mbedtls_sha1_update(&sha, (const unsigned char *) info->client_ip.c_str(), info->client_ip.length());
+ mbedtls_sha1_update(&sha, (const unsigned char *) info->acc_username.c_str(), info->acc_username.length());
+ mbedtls_sha1_finish(&sha, sha_digist);
+ mbedtls_sha1_free(&sha);
- retried++;
- if (retried > 50)
- return false;
- }
+ char szTmp[64] = {0};
+ int _len = len / 2 + 1;
+ int i = 0;
+ int offset = 0;
+ for (i = 0; i < _len; ++i) {
+ snprintf(szTmp + offset, 64 - offset, "%02X", sha_digist[i]);
+ offset += 2;
+ }
- info->sid = _sid;
- info->ref_count = 0;
- info->ticket_start = ex_get_tick_count();
- m_connections.insert(std::make_pair(_sid, info));
-
- sid = _sid;
- if (info->protocol_type == TP_PROTOCOL_TYPE_RDP)
- {
- info->ref_count = 1; // 因为RDP连接之前可能会有很长时间用于确认是否连接、是否信任证书,所以很容易超时,我们认为将引用计数+1,防止因超时被清除。
- char szTmp[8] = { 0 };
- snprintf(szTmp, 8, "%02X", (unsigned char)(info->acc_username.length() + info->acc_secret.length()));
- sid += szTmp;
- }
-
- return true;
-}
-
-void TsSessionManager::_gen_session_id(ex_astr& sid, const TS_CONNECT_INFO* info, int len)
-{
- mbedtls_sha1_context sha;
- ex_u8 sha_digist[20] = { 0 };
-
- ex_u64 _tick = ex_get_tick_count();
- ex_u64 _tid = ex_get_thread_id();
-
- mbedtls_sha1_init(&sha);
- mbedtls_sha1_starts(&sha);
- mbedtls_sha1_update(&sha, (const unsigned char*)&_tick, sizeof(ex_u64));
- mbedtls_sha1_update(&sha, (const unsigned char*)&_tid, sizeof(ex_u64));
- mbedtls_sha1_update(&sha, (const unsigned char*)info->conn_ip.c_str(), info->conn_ip.length());
- mbedtls_sha1_update(&sha, (const unsigned char*)info->client_ip.c_str(), info->client_ip.length());
- mbedtls_sha1_update(&sha, (const unsigned char*)info->acc_username.c_str(), info->acc_username.length());
- mbedtls_sha1_finish(&sha, sha_digist);
- mbedtls_sha1_free(&sha);
-
- char szTmp[64] = { 0 };
- int _len = len / 2 + 1;
- int i = 0;
- int offset = 0;
- for (i = 0; i < _len; ++i)
- {
- snprintf(szTmp + offset, 64 - offset, "%02X", sha_digist[i]);
- offset += 2;
- }
-
- sid.assign(szTmp, len);
+ sid.assign(szTmp, len);
}
diff --git a/server/tp_core/core/ts_session.h b/server/tp_core/core/ts_session.h
index 23271de..e227351 100644
--- a/server/tp_core/core/ts_session.h
+++ b/server/tp_core/core/ts_session.h
@@ -57,10 +57,7 @@ public:
bool free_connect_info(const ex_astr& sid);
protected:
- // 线程循环
void _thread_loop(void);
- // 设置停止标志,让线程能够正常结束
- void _set_stop_flag(void);
private:
void _gen_session_id(ex_astr& sid, const TS_CONNECT_INFO* info, int len);
diff --git a/server/tp_core/protocol/telnet/CMakeLists.txt b/server/tp_core/protocol/telnet/CMakeLists.txt
index 7e781d6..fafe24d 100644
--- a/server/tp_core/protocol/telnet/CMakeLists.txt
+++ b/server/tp_core/protocol/telnet/CMakeLists.txt
@@ -19,19 +19,19 @@ list(REMOVE_ITEM DIR_TELNET_SRCS "./stdafx.cpp")
include_directories(
../../../../common/libex/include
- ../../../../common/teleport
- ../../../../external/jsoncpp/include
+ ../../../../common/teleport
+ ../../../../external/jsoncpp/include
)
include_directories(
- ${TP_EXTERNAL_RELEASE_DIR}/include
+ ${TP_EXTERNAL_RELEASE_DIR}/include
)
link_directories(${TP_EXTERNAL_RELEASE_DIR}/lib)
add_library(tptelnet SHARED ${DIR_TELNET_SRCS})
if (OS_LINUX)
- target_link_libraries(tptelnet uv dl pthread rt util)
+ target_link_libraries(tptelnet uv dl pthread rt util)
elseif (OS_MACOS)
- target_link_libraries(tptelnet uv dl pthread util)
-endif()
+ target_link_libraries(tptelnet uv dl pthread util)
+endif ()
diff --git a/server/tp_core/protocol/telnet/telnet_conn.cpp b/server/tp_core/protocol/telnet/telnet_conn.cpp
index 0d08d78..45ae854 100644
--- a/server/tp_core/protocol/telnet/telnet_conn.cpp
+++ b/server/tp_core/protocol/telnet/telnet_conn.cpp
@@ -4,72 +4,90 @@
#include "../../common/ts_const.h"
#include
-ex_astr _uv_str_error(int retcode)
-{
- ex_astr err;
- err = uv_err_name(retcode);
- err += ":";
- err += uv_strerror(retcode);
- return err;
+ex_astr _uv_str_error(int retcode) {
+ ex_astr err;
+ err = uv_err_name(retcode);
+ err += ":";
+ err += uv_strerror(retcode);
+ return err;
}
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 {
- m_name = "tp<->srv";
- m_state = TELNET_CONN_STATE_FREE;
+ m_name = "cli<->tp";
+ m_state = TELNET_CONN_STATE_CONNECTED;
+ } else {
+ m_name = "tp<->srv";
+ m_state = TELNET_CONN_STATE_FREE;
}
- m_timer_running = false;
+ m_timer_running = false;
uv_tcp_init(sess->get_loop(), &m_handle);
m_handle.data = this;
+ uv_async_init(sess->get_loop(), &m_stop_handle, _on_stop_cb);
+ m_stop_handle.data = this;
}
TelnetConn::~TelnetConn() {
}
bool TelnetConn::start_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);
- return false;
- }
+ 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);
+ return false;
+ }
- return true;
+ return true;
}
void TelnetConn::close() {
- if (m_state == TELNET_CONN_STATE_FREE || m_state == TELNET_CONN_STATE_CLOSING)
- return;
+ if (m_state == TELNET_CONN_STATE_FREE || m_state == TELNET_CONN_STATE_CLOSING)
+ return;
+ uv_async_send(&m_stop_handle);
+}
- if (m_timer_running) {
- m_timer_running = false;
- uv_timer_stop(&m_timer_connect_timeout);
+void TelnetConn::_do_close() {
+ if (m_state == TELNET_CONN_STATE_FREE || m_state == TELNET_CONN_STATE_CLOSING)
+ return;
- EXLOGW("[telnet] [%s] try to close while it connecting.\n", m_name);
- m_state = TELNET_CONN_STATE_CLOSING;
- uv_close(handle(), NULL);
+ if (m_timer_running) {
+ m_timer_running = false;
+ uv_timer_stop(&m_timer_connect_timeout);
- return;
- }
+ EXLOGW("[telnet] [%s] try to close while it connecting.\n", m_name);
+ m_state = TELNET_CONN_STATE_CLOSING;
+ uv_close(handle(), NULL);
- uv_read_stop((uv_stream_t*)&m_handle);
- uv_close(handle() , _uv_on_closed);
+ return;
+ }
+
+ 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);
+}
+
+//static
+void TelnetConn::_on_stop_handler_closed(uv_handle_t *handle) {
+ TelnetConn *_this = (TelnetConn *) handle->data;
+ _this->_do_close();
}
void TelnetConn::_uv_on_closed(uv_handle_t *handle) {
- TelnetConn *_this = (TelnetConn *)handle->data;
- _this->m_state = TELNET_CONN_STATE_FREE;
- _this->m_session->on_conn_close();
+ TelnetConn *_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;
+// TelnetConn *_this = (TelnetConn *) handle->data;
buf->base = (char *) calloc(1, suggested_size);
buf->len = suggested_size;
}
@@ -80,16 +98,15 @@ void TelnetConn::_on_recv(uv_stream_t *handle, ssize_t nread, const uv_buf_t *bu
if (nread == 0) {
free(buf->base);
return;
- }
- else if (nread < 0) {
+ } else if (nread < 0) {
free(buf->base);
- if (nread == UV_EOF)
- EXLOGD("[telnet] [%s] [recv] disconnected.\n", _this->m_name);
- else if(nread == UV_ECONNRESET)
- EXLOGD("[telnet] [%s] [recv] connection reset by peer.\n", _this->m_name);
- else
- EXLOGD("[telnet] [%s] [recv] %s.\n", _this->m_name, _uv_str_error(nread).c_str());
+ if (nread == UV_EOF)
+ EXLOGD("[telnet] [%s] [recv] disconnected.\n", _this->m_name);
+ else if (nread == UV_ECONNRESET)
+ EXLOGD("[telnet] [%s] [recv] connection reset by peer.\n", _this->m_name);
+ else
+ EXLOGD("[telnet] [%s] [recv] %s.\n", _this->m_name, _uv_str_error(nread).c_str());
// if (nread == -4077)
@@ -101,13 +118,12 @@ 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);
free(buf->base);
@@ -129,7 +145,7 @@ bool TelnetConn::_raw_send(const ex_u8 *data, size_t size) {
// 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));
+ uv_write_t *w = (uv_write_t *) calloc(1, sizeof(uv_write_t));
ex_u8 *_data = (ex_u8 *) calloc(1, size);
if (NULL == _data) {
@@ -170,13 +186,14 @@ void TelnetConn::connect(const char *server_ip, ex_u16 server_port) {
if (m_state == TELNET_CONN_STATE_CONNECTED) {
// 当前已经连接上了服务器了,断开重连
- EXLOGV("[telnet] [%s] [%s] try to disconnect. %s:%d\n", m_name, m_session->client_addr(), server_ip, server_port);
- m_state = TELNET_CONN_STATE_CLOSING;
+ 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);
return;
- }
- else {
- EXLOGV("[telnet] [%s] [%s] try to connect to real TELNET server at %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;
@@ -185,53 +202,51 @@ void TelnetConn::connect(const char *server_ip, ex_u16 server_port) {
uv_connect_t *conn_req = (uv_connect_t *) calloc(1, sizeof(uv_connect_t));
conn_req->data = this;
- // 设置一个超时回调,如果超时发生时连接尚未完成,就报错
- uv_timer_init(m_session->get_loop(), &m_timer_connect_timeout);
- m_timer_connect_timeout.data = this;
+ // 设置一个超时回调,如果超时发生时连接尚未完成,就报错
+ uv_timer_init(m_session->get_loop(), &m_timer_connect_timeout);
+ m_timer_connect_timeout.data = this;
#ifdef EX_DEBUG
- uv_timer_start(&m_timer_connect_timeout, _uv_on_connect_timeout, 5000, 0);
+ uv_timer_start(&m_timer_connect_timeout, _uv_on_connect_timeout, 5000, 0);
#else
- uv_timer_start(&m_timer_connect_timeout, _uv_on_connect_timeout, 10000, 0);
+ uv_timer_start(&m_timer_connect_timeout, _uv_on_connect_timeout, 10000, 0);
#endif
- m_timer_running = true;
+ m_timer_running = true;
- //m_is_connecting = true;
- m_state = TELNET_CONN_STATE_CONNECTING;
+ 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) {
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, _uv_on_timer_connect_timeout_closed);
+ m_timer_running = false;
+ uv_timer_stop(&m_timer_connect_timeout);
+ uv_close((uv_handle_t *) &m_timer_connect_timeout, NULL);
- m_state = TELNET_CONN_STATE_FREE;
+ 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) {
+ TelnetConn *_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, _this->_uv_on_timer_connect_timeout_closed);
- }
+ 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);
+ }
- // 如果在连接成功之前就超时了,则关闭连接
- EXLOGE("[telnet] [%s] timeout when connect to real TELNET server, cancel connection.\n", _this->m_name);
- _this->m_state = TELNET_CONN_STATE_CLOSING;
- uv_close(_this->handle(), _uv_on_closed);
+ // 如果在连接成功之前就超时了,则关闭连接
+ EXLOGE("[telnet] [%s] timeout when connect to real TELNET server.\n", _this->m_name);
+ _this->m_state = TELNET_CONN_STATE_CLOSING;
+ uv_close(_this->handle(), _uv_on_closed);
}
void TelnetConn::_uv_on_reconnect(uv_handle_t *handle) {
- TelnetConn *_this = (TelnetConn *)handle->data;
- _this->m_state = TELNET_CONN_STATE_FREE;
+ TelnetConn *_this = (TelnetConn *) handle->data;
+ _this->m_state = TELNET_CONN_STATE_FREE;
uv_tcp_init(_this->m_session->get_loop(), &_this->m_handle);
_this->m_handle.data = _this;
@@ -240,33 +255,33 @@ void TelnetConn::_uv_on_reconnect(uv_handle_t *handle) {
}
void TelnetConn::_uv_on_connected(uv_connect_t *req, int status) {
- TelnetConn *_this = (TelnetConn *)req->data;
+ TelnetConn *_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, _this->_uv_on_timer_connect_timeout_closed);
- }
+ 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);
+ }
- if (status != 0) {
- EXLOGE("[telnet] [%s] cannot connect to real TELNET server. %s\n", _this->m_name, uv_strerror(status));
- _this->m_state = TELNET_CONN_STATE_FREE;
- _this->m_session->close(TP_SESS_STAT_ERR_CONNECT);
- return;
- }
+ if (status != 0) {
+ EXLOGE("[telnet] [%s] cannot connect to real TELNET server. %s\n", _this->m_name, uv_strerror(status));
+ _this->m_state = TELNET_CONN_STATE_FREE;
+ _this->m_session->close(TP_SESS_STAT_ERR_CONNECT);
+ return;
+ }
- EXLOGW("[telnet] [%s] real TELNET server connected.\n", _this->m_session->client_addr());
- _this->m_state = TELNET_CONN_STATE_CONNECTED;
+ EXLOGW("[telnet] [%s] real TELNET server connected.\n", _this->m_session->client_addr());
+ _this->m_state = TELNET_CONN_STATE_CONNECTED;
- if (!_this->start_recv()) {
- _this->m_session->close(TP_SESS_STAT_ERR_IO);
- return;
- }
+ if (!_this->start_recv()) {
+ _this->m_session->close(TP_SESS_STAT_ERR_IO);
+ return;
+ }
_this->m_session->do_next(_this, s_server_connected);
}
//static
-void TelnetConn::_uv_on_timer_connect_timeout_closed(uv_handle_t *handle) {
-}
+//void TelnetConn::_uv_on_timer_connect_timeout_closed(uv_handle_t *handle) {
+//}
diff --git a/server/tp_core/protocol/telnet/telnet_conn.h b/server/tp_core/protocol/telnet/telnet_conn.h
index 653deee..4eebd1c 100644
--- a/server/tp_core/protocol/telnet/telnet_conn.h
+++ b/server/tp_core/protocol/telnet/telnet_conn.h
@@ -8,10 +8,10 @@
//#define LOG_DATA
-#define TELNET_CONN_STATE_FREE 0 // not connected yet or closed
-#define TELNET_CONN_STATE_CONNECTING 1 // connecting
-#define TELNET_CONN_STATE_CONNECTED 2 // connected.
-#define TELNET_CONN_STATE_CLOSING 3 // closing.
+#define TELNET_CONN_STATE_FREE 0 // not connected yet or closed
+#define TELNET_CONN_STATE_CONNECTING 1 // connecting
+#define TELNET_CONN_STATE_CONNECTED 2 // connected.
+#define TELNET_CONN_STATE_CLOSING 3 // closing.
class TelnetSession;
@@ -19,40 +19,59 @@ class TelnetSession;
class TelnetConn {
public:
TelnetConn(TelnetSession *sess, bool is_server_side);
+
~TelnetConn();
TelnetSession *session() { return m_session; }
- // just for debug-info
+ // just for debug-info
const char *name() const { return m_name; }
- bool is_server_side() const { return m_is_server; }
- ex_u8 state() const { return m_state; }
+ 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_tcp_t *tcp_handle() { return &m_handle; }
+
uv_stream_t *stream_handle() { return (uv_stream_t *) &m_handle; }
MemBuffer &data() { return m_buf_data; }
bool send(MemBuffer &mbuf);
+
bool send(const ex_u8 *data, size_t size);
- // connect to real server, for proxy-client-side only.
+ // connect to real server, for proxy-client-side only.
void connect(const char *server_ip, ex_u16 server_port = 3389);
- // try to close this connection. return current TELNET_CONN_STATE_XXXX.
- void close();
- bool start_recv();
+
+ // try to close this connection. return current TELNET_CONN_STATE_XXXX.
+ void close();
+
+ bool start_recv();
private:
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_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_reconnect(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 _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_handler_closed(uv_handle_t *handle);
+
+ void _do_close();
bool _raw_send(const ex_u8 *data, size_t size);
@@ -60,14 +79,15 @@ private:
TelnetSession *m_session;
bool m_is_server;
- // for debug-info.
+ // for debug-info.
const char *m_name;
uv_tcp_t m_handle;
- uv_timer_t m_timer_connect_timeout;
- bool m_timer_running; // does m_timer_connect_timeout initialized and started.
+ uv_timer_t m_timer_connect_timeout;
+ bool m_timer_running; // does m_timer_connect_timeout initialized and started.
+ uv_async_t m_stop_handle; // event for stop whole listener handler.
- ex_u8 m_state; // TELNET_CONN_STATE_XXXX
+ ex_u8 m_state; // TELNET_CONN_STATE_XXXX
// 作为client需要的数据(远程主机信息)
std::string m_server_ip;
diff --git a/server/tp_core/protocol/telnet/telnet_proxy.cpp b/server/tp_core/protocol/telnet/telnet_proxy.cpp
index 0dcb040..969e365 100644
--- a/server/tp_core/protocol/telnet/telnet_proxy.cpp
+++ b/server/tp_core/protocol/telnet/telnet_proxy.cpp
@@ -4,228 +4,239 @@
TelnetProxy g_telnet_proxy;
-TelnetProxy::TelnetProxy() : ExThreadBase("telnet-proxy-thread")
-{
- memset(&m_loop, 0, sizeof(uv_loop_t));
- m_timer_counter = 0;
- m_noop_timeout_sec = 900;
+TelnetProxy::TelnetProxy() : ExThreadBase("telnet-proxy-thread") {
+ memset(&m_loop, 0, sizeof(uv_loop_t));
+ m_timer_counter = 0;
+ m_noop_timeout_sec = 900;
}
-TelnetProxy::~TelnetProxy()
-{
- if (m_sessions.size() > 0)
- EXLOGE("[telnet] not all session stopped.\n");
+TelnetProxy::~TelnetProxy() {
+ if (!m_sessions.empty())
+ EXLOGE("[telnet] not all session stopped.\n");
}
-bool TelnetProxy::init()
-{
- if (0 != uv_loop_init(&m_loop))
- return false;
+bool TelnetProxy::init() {
+ if (0 != uv_loop_init(&m_loop))
+ return false;
- if (0 != uv_async_init(&m_loop, &m_clean_session_handle, _on_clean_session_cb))
- return false;
- m_clean_session_handle.data = this;
+ if (0 != uv_async_init(&m_loop, &m_clean_session_handle, _on_clean_session_cb))
+ return false;
+ m_clean_session_handle.data = this;
- m_host_ip = g_telnet_env.bind_ip;
- m_host_port = g_telnet_env.bind_port;
+ if (0 != uv_async_init(&m_loop, &m_stop_handle, _on_stop_cb))
+ return false;
+ m_stop_handle.data = this;
- if (0 != uv_tcp_init(&m_loop, &m_handle))
- return false;
- m_handle.data = this;
+ m_host_ip = g_telnet_env.bind_ip;
+ m_host_port = g_telnet_env.bind_port;
- return true;
+ if (0 != uv_tcp_init(&m_loop, &m_listener_handle))
+ return false;
+ m_listener_handle.data = this;
+
+ return true;
}
void TelnetProxy::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, and I will do my job per 5 seconds.
+ m_timer_counter++;
+ if (m_timer_counter < 5)
+ return;
- m_timer_counter = 0;
+ m_timer_counter = 0;
- ExThreadSmartLock locker(m_lock);
- ex_u32 t_now = (ex_u32)time(NULL);
- ts_telnet_sessions::iterator it = m_sessions.begin();
- for (; 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);
- }
+ ExThreadSmartLock locker(m_lock);
+ ex_u32 t_now = (ex_u32) time(NULL);
+ ts_telnet_sessions::iterator it = m_sessions.begin();
+ for (; 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);
+ }
}
void TelnetProxy::set_cfg(ex_u32 noop_timeout) {
- m_noop_timeout_sec = noop_timeout;
+ m_noop_timeout_sec = noop_timeout;
}
-void TelnetProxy::kill_sessions(const ex_astrs& sessions) {
- ExThreadSmartLock locker(m_lock);
- ts_telnet_sessions::iterator 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]) {
- EXLOGW("[telnet] try to kill %s\n", sessions[i].c_str());
- it->first->check_noop_timeout(0, 0); // 立即结束
- }
- }
- }
+void TelnetProxy::kill_sessions(const ex_astrs &sessions) {
+ ExThreadSmartLock locker(m_lock);
+ ts_telnet_sessions::iterator 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]) {
+ EXLOGW("[telnet] try to kill %s\n", sessions[i].c_str());
+ it->first->check_noop_timeout(0, 0); // 立即结束
+ }
+ }
+ }
}
-void TelnetProxy::_thread_loop(void)
-{
- 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;
- }
+void TelnetProxy::_thread_loop(void) {
+ 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_handle, (const struct sockaddr*) &addr, 0)) {
- EXLOGE("[telnet] can not bind %s:%d.\n", m_host_ip.c_str(), m_host_port);
- return;
- }
+ 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_handle, 8, _on_client_connect)) {
- EXLOGE("[telnet] can not listen on %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)) {
+ EXLOGE("[telnet] can not listen on %s:%d.\n", m_host_ip.c_str(), m_host_port);
+ return;
+ }
- EXLOGI("[telnet] TeleportServer-TELNET ready on %s:%d\n", m_host_ip.c_str(), m_host_port);
+ EXLOGI("[telnet] TeleportServer-TELNET ready on %s:%d\n", m_host_ip.c_str(), m_host_port);
- int err = 0;
- if ((err = uv_run(&m_loop, UV_RUN_DEFAULT)) != 0) {
- EXLOGE("[telnet] main-loop end. %s\n", uv_strerror(err));
- }
+ int err = 0;
+ if ((err = uv_run(&m_loop, UV_RUN_DEFAULT)) != 0) {
+ EXLOGE("[telnet] main-loop end. %s\n", uv_strerror(err));
+ }
- // 注意,如果在 uv_loop_close() 内部崩溃,可能某个uv的handle未关闭。
- uv_loop_close(&m_loop);
+ // https://github.com/libuv/libuv/issues/709
+ //
+ // uv_close is not thread safe (see the docs here. That means you cannot call it from outside of the loop thread.
+ // http://docs.libuv.org/en/v1.x/design.html#the-i-o-loop
+ //
+ // The usual way to approach this when the loop is running in another thread is to use a uv_async_t handle,
+ // because uv_async_send is thread safe. You could have one such handle and call uv_stop in its callback.
+ // Then, after uv_run returns you can use uv_walk to close all handles and run the loop one last time so
+ // that close callbacks are called.
- EXLOGV("[telnet] main-loop end.\n");
-}
+ // 注意,如果在 uv_loop_close() 内部崩溃,可能某个uv的handle未关闭。
+ uv_loop_close(&m_loop);
-void TelnetProxy::_set_stop_flag(void) {
- m_stop_flag = true;
-
- if (m_is_running) {
- uv_close((uv_handle_t*)&m_handle, _on_listener_closed);
- }
+ EXLOGV("[telnet] main-loop end.\n");
}
// static
-void TelnetProxy::_on_listener_closed(uv_handle_t* handle)
-{
- TelnetProxy* _this = (TelnetProxy*)handle->data;
- EXLOGV("[telnet] listener close.\n");
+void TelnetProxy::_on_stop(void) {
+ ExThreadBase::_on_stop();
- _this->_close_all_sessions();
+ if (m_is_running) {
+ uv_async_send(&m_stop_handle);
+ }
+}
+
+// static
+void TelnetProxy::_on_listener_closed(uv_handle_t *handle) {
+ TelnetProxy *_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();
}
void TelnetProxy::clean_session() {
- uv_async_send(&m_clean_session_handle);
+ uv_async_send(&m_clean_session_handle);
}
-void TelnetProxy::_close_all_sessions(void)
-{
- ExThreadSmartLock locker(m_lock);
+void TelnetProxy::_close_all_sessions(void) {
+ ExThreadSmartLock locker(m_lock);
- if (m_sessions.size() == 0) {
- _close_clean_session_handle();
- return;
- }
+ if (m_sessions.empty()) {
+ _close_clean_session_handle();
+ return;
+ }
- ts_telnet_sessions::iterator it = m_sessions.begin();
- for (; it != m_sessions.end(); ++it)
- {
- it->first->close(TP_SESS_STAT_ERR_RESET);
- }
+ ts_telnet_sessions::iterator 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) {
+ TelnetProxy *_this = (TelnetProxy *) handle->data;
- // check closed session
- ExThreadSmartLock locker(_this->m_lock);
+ // check closed session
+ ExThreadSmartLock locker(_this->m_lock);
- ts_telnet_sessions::iterator 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 {
- it++;
- }
- }
+ ts_telnet_sessions::iterator 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 {
+ it++;
+ }
+ }
- if (_this->m_stop_flag && _this->m_sessions.size() == 0) {
- _this->_close_clean_session_handle();
- }
+ if (_this->m_need_stop && _this->m_sessions.empty()) {
+ _this->_close_clean_session_handle();
+ }
+}
+
+////static
+//void TelnetProxy::_on_clean_session_handle_closed(uv_handle_t *handle) {
+//}
+
+//static
+void TelnetProxy::_on_stop_handle_closed(uv_handle_t *handle) {
+ TelnetProxy *_this = (TelnetProxy *) handle->data;
+ _this->_close_all_sessions();
}
//static
-void TelnetProxy::_on_clean_session_handle_closed(uv_handle_t *handle) {
+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);
}
// static
-void TelnetProxy::_on_client_connect(uv_stream_t* server, int status)
-{
- if (0 != status)
- return;
+void TelnetProxy::_on_client_connect(uv_stream_t *server, int status) {
+ if (0 != status)
+ return;
- TelnetProxy* _this = (TelnetProxy*)server->data;
- _this->_on_accept(server);
+ TelnetProxy *_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) {
+ TelnetSession *sess = new TelnetSession(this);
- if (0 != uv_accept(server, sess->client()->stream_handle()))
- {
- EXLOGE("[telnet] socket accept failed.\n");
- delete sess;
- return false;
- }
+ if (0 != uv_accept(server, sess->client()->stream_handle())) {
+ EXLOGE("[telnet] socket accept failed.\n");
+ delete sess;
+ return false;
+ }
- if (m_stop_flag)
- {
- delete sess;
- return false;
- }
+ if (m_need_stop) {
+ delete sess;
+ return false;
+ }
- // 获取客户端IP地址和端口号
- 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;
- char ip[17] = { 0 };
- if (0 == uv_ip4_name(addrin, ip, sizeof(ip)))
- {
- char client_addr[64] = { 0 };
- snprintf(client_addr, 64, "%s:%d", ip, addrin->sin_port);
- sess->client_addr(client_addr);
- }
- }
+ // 获取客户端IP地址和端口号
+ 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;
+ char ip[17] = {0};
+ if (0 == uv_ip4_name(addrin, ip, sizeof(ip))) {
+ char client_addr[64] = {0};
+ snprintf(client_addr, 64, "%s:%d", ip, addrin->sin_port);
+ sess->client_addr(client_addr);
+ }
+ }
- EXLOGV("\n=================== NEW TELNET CLIENT [%s] ============\n", sess->client_addr());
+ EXLOGV("\n=================== NEW TELNET CLIENT [%s] ============\n", sess->client_addr());
- {
- ExThreadSmartLock locker(m_lock);
- m_sessions.insert(std::make_pair(sess, 0));
- }
+ {
+ ExThreadSmartLock locker(m_lock);
+ m_sessions.insert(std::make_pair(sess, 0));
+ }
- sess->client()->start_recv();
+ sess->client()->start_recv();
- return true;
+ return true;
}
void TelnetProxy::_close_clean_session_handle() {
- uv_close((uv_handle_t*)&m_clean_session_handle, _on_clean_session_handle_closed);
+ uv_close((uv_handle_t *) &m_clean_session_handle, NULL);
}
diff --git a/server/tp_core/protocol/telnet/telnet_proxy.h b/server/tp_core/protocol/telnet/telnet_proxy.h
index bfd3f2c..5b1a14a 100644
--- a/server/tp_core/protocol/telnet/telnet_proxy.h
+++ b/server/tp_core/protocol/telnet/telnet_proxy.h
@@ -6,53 +6,65 @@
#include "telnet_session.h"
-typedef std::map ts_telnet_sessions;
+typedef std::map ts_telnet_sessions;
-class TelnetProxy : public ExThreadBase
-{
+class TelnetProxy : public ExThreadBase {
public:
- TelnetProxy();
- ~TelnetProxy();
+ TelnetProxy();
- bool init();
- void timer();
- void set_cfg(ex_u32 noop_timeout);
- void kill_sessions(const ex_astrs& sessions);
+ ~TelnetProxy();
- uv_loop_t* get_loop() { return &m_loop; }
+ bool init();
- void clean_session();
+ void timer();
+
+ void set_cfg(ex_u32 noop_timeout);
+
+ void kill_sessions(const ex_astrs &sessions);
+
+ uv_loop_t *get_loop() { return &m_loop; }
+
+ void clean_session();
protected:
- void _thread_loop();
- void _set_stop_flag();
- void _close_all_sessions();
- void _close_clean_session_handle();
+ void _thread_loop();
+
+ void _on_stop();
+
+ void _close_all_sessions();
+
+ void _close_clean_session_handle();
private:
- static void _on_client_connect(uv_stream_t* server, int status);
- static void _on_listener_closed(uv_handle_t* handle);
- static void _on_clean_session_cb(uv_async_t* handle);
- static void _on_clean_session_handle_closed(uv_handle_t *handle);
+ static void _on_client_connect(uv_stream_t *server, int status);
- bool _on_accept(uv_stream_t* server);
+ static void _on_listener_closed(uv_handle_t *handle);
+
+ static void _on_clean_session_cb(uv_async_t *handle);
+
+// static void _on_clean_session_handle_closed(uv_handle_t *handle);
+
+ static void _on_stop_cb(uv_async_t *handle);
+
+ static void _on_stop_handle_closed(uv_handle_t *handle);
+
+ bool _on_accept(uv_stream_t *server);
private:
- bool m_stop_flag;
- int m_timer_counter;
- //
- ex_u32 m_noop_timeout_sec;
+ int m_timer_counter;
+ ex_u32 m_noop_timeout_sec;
- uv_loop_t m_loop;
- uv_tcp_t m_handle;
- uv_async_t m_clean_session_handle;
+ uv_loop_t m_loop;
+ uv_tcp_t m_listener_handle;
+ uv_async_t m_clean_session_handle;
+ uv_async_t m_stop_handle; // event for stop whole listener handler.
- ExThreadLock m_lock;
+ ExThreadLock m_lock;
- ex_astr m_host_ip;
- int m_host_port;
+ ex_astr m_host_ip;
+ int m_host_port;
- ts_telnet_sessions m_sessions;
+ ts_telnet_sessions m_sessions;
};
extern TelnetProxy g_telnet_proxy;
diff --git a/server/tp_core/protocol/telnet/telnet_session.cpp b/server/tp_core/protocol/telnet/telnet_session.cpp
index 242222e..56349cd 100644
--- a/server/tp_core/protocol/telnet/telnet_session.cpp
+++ b/server/tp_core/protocol/telnet/telnet_session.cpp
@@ -3,168 +3,164 @@
#include "tpp_env.h"
#include
-#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) :
- m_proxy(proxy),
- m_conn_info(NULL)
-{
- 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_proxy(proxy),
+ m_conn_info(NULL) {
+ 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_win_width = 0;
- m_win_height = 0;
+ m_win_width = 0;
+ m_win_height = 0;
- m_is_putty_mode = false;
+ m_is_putty_mode = false;
- m_username_sent = false;
- m_password_sent = false;
+ m_username_sent = false;
+ m_password_sent = false;
- m_conn_server = new TelnetConn(this, false);
- m_conn_client = new TelnetConn(this, true);
+ m_conn_server = new TelnetConn(this, false);
+ m_conn_client = new TelnetConn(this, true);
- m_status = s_client_connect;
+ m_status = s_client_connect;
- m_client_addr = "unknown-ip";
+ m_client_addr = "unknown-ip";
}
TelnetSession::~TelnetSession() {
- delete m_conn_client;
- delete m_conn_server;
+ delete m_conn_client;
+ delete m_conn_server;
- if (NULL != m_conn_info) {
- g_telnet_env.free_connect_info(m_conn_info);
- }
+ if (NULL != m_conn_info) {
+ g_telnet_env.free_connect_info(m_conn_info);
+ }
- EXLOGD("[telnet] session destroy.\n");
+ EXLOGD("[telnet] session destroy.\n");
}
void TelnetSession::save_record() {
- m_rec.save_record();
+ m_rec.save_record();
}
void TelnetSession::check_noop_timeout(ex_u32 t_now, ex_u32 timeout) {
- if (t_now == 0)
- EXLOGW("[telnet] try close session by kill.\n");
- else if (t_now - m_last_access_timestamp > timeout)
- EXLOGW("[telnet] try close session by timeout.\n");
- if (t_now == 0 || t_now - m_last_access_timestamp > timeout)
- _do_close(TP_SESS_STAT_END);
+ if (t_now == 0)
+ EXLOGW("[telnet] try close session by kill.\n");
+ else if (t_now - m_last_access_timestamp > timeout)
+ EXLOGW("[telnet] try close session by timeout.\n");
+ if (t_now == 0 || t_now - m_last_access_timestamp > timeout)
+ _do_close(TP_SESS_STAT_END);
}
void TelnetSession::_session_error(int err_code) {
- int db_id = 0;
- if (!g_telnet_env.session_begin(m_conn_info, &db_id) || db_id == 0)
- {
- EXLOGE("[telnet] can not write session error to database.\n");
- return;
- }
+ int db_id = 0;
+ if (!g_telnet_env.session_begin(m_conn_info, &db_id) || db_id == 0) {
+ EXLOGE("[telnet] can not write session error to database.\n");
+ return;
+ }
- g_telnet_env.session_end(m_sid.c_str(), db_id, err_code);
+ g_telnet_env.session_end(m_sid.c_str(), db_id, err_code);
}
bool TelnetSession::_on_session_begin() {
- if (!g_telnet_env.session_begin(m_conn_info, &m_db_id)) {
- EXLOGE("[telnet] can not save to database, session begin failed.\n");
- return false;
- }
+ if (!g_telnet_env.session_begin(m_conn_info, &m_db_id)) {
+ EXLOGE("[telnet] can not save to database, session begin failed.\n");
+ return false;
+ }
- if (!g_telnet_env.session_update(m_db_id, m_conn_info->protocol_sub_type, TP_SESS_STAT_STARTED)) {
- EXLOGE("[telnet] can not update state, session begin failed.\n");
- return false;
- }
+ if (!g_telnet_env.session_update(m_db_id, m_conn_info->protocol_sub_type, TP_SESS_STAT_STARTED)) {
+ EXLOGE("[telnet] can not update state, session begin failed.\n");
+ return false;
+ }
- m_rec.begin(g_telnet_env.replay_path.c_str(), L"tp-telnet", m_db_id, m_conn_info);
+ m_rec.begin(g_telnet_env.replay_path.c_str(), L"tp-telnet", m_db_id, m_conn_info);
- return true;
+ return true;
}
-bool TelnetSession::_on_session_end()
-{
- if (m_db_id > 0)
- {
- // 如果会话过程中没有发生错误,则将其状态改为结束,否则记录下错误值
- if (m_state == TP_SESS_STAT_RUNNING || m_state == TP_SESS_STAT_STARTED)
- m_state = TP_SESS_STAT_END;
+bool TelnetSession::_on_session_end() {
+ if (m_db_id > 0) {
+ // 如果会话过程中没有发生错误,则将其状态改为结束,否则记录下错误值
+ if (m_state == TP_SESS_STAT_RUNNING || m_state == TP_SESS_STAT_STARTED)
+ m_state = TP_SESS_STAT_END;
- EXLOGD("[telnet] session end with code: %d\n", m_state);
- g_telnet_env.session_end(m_sid.c_str(), m_db_id, m_state);
- }
+ EXLOGD("[telnet] session end with code: %d\n", m_state);
+ g_telnet_env.session_end(m_sid.c_str(), m_db_id, m_state);
+ }
- return true;
+ return true;
}
uv_loop_t *TelnetSession::get_loop(void) {
- return m_proxy->get_loop();
+ return m_proxy->get_loop();
}
void TelnetSession::close(int err_code) {
- _do_close(err_code);
+ _do_close(err_code);
}
void TelnetSession::do_next(TelnetConn *conn, sess_state status) {
- if (m_status < s_close)
- m_status = status;
+ if (m_status < s_close)
+ m_status = status;
- do_next(conn);
+ do_next(conn);
}
void TelnetSession::do_next(TelnetConn *conn) {
- sess_state new_status;
- ASSERT(m_status != s_dead);
+ sess_state new_status;
+ ASSERT(m_status != s_dead);
- switch (m_status) {
- case s_noop:
- return;
+ switch (m_status) {
+ 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;
+ m_status = new_status;
- if (m_status == s_dead) {
- EXLOGW("[telnet] try to remove session.\n");
- _on_session_end();
- m_is_closed = true;
- m_proxy->clean_session();
- }
+ if (m_status == s_dead) {
+ EXLOGW("[telnet] try to remove session.\n");
+ _on_session_end();
+ m_is_closed = true;
+ m_proxy->clean_session();
+ }
}
/*
@@ -174,276 +170,248 @@ void TelnetSession::do_next(TelnetConn *conn) {
*/
sess_state TelnetSession::_do_close(int state) {
- EXLOGD("[telnet] _do_close(). m_status=%d\n", m_status);
- if (m_status >= s_close)
- return m_status;
+ EXLOGD("[telnet] _do_close(). m_status=%d\n", m_status);
+ if (m_status >= s_close)
+ return m_status;
- if (state == TP_SESS_STAT_END) {
- if (!m_is_relay)
- m_state = TP_SESS_STAT_ERR_INTERNAL;
- else
- m_state = state;
- }
- 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());
+ if (state == TP_SESS_STAT_END) {
+ if (!m_is_relay)
+ m_state = TP_SESS_STAT_ERR_INTERNAL;
+ else
+ m_state = state;
+ } 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());
- m_conn_client->close();
- m_conn_server->close();
- m_status = s_closing;
- return m_status;
+ m_conn_client->close();
+ m_conn_server->close();
+ m_status = s_closing;
+ return m_status;
}
sess_state TelnetSession::_do_check_closing() {
- if (m_conn_client->state() == TELNET_CONN_STATE_FREE && m_conn_server->state() == TELNET_CONN_STATE_FREE)
- return s_all_conn_closed;
- else
- return s_closing;
+ if (m_conn_client->state() == TELNET_CONN_STATE_FREE && m_conn_server->state() == TELNET_CONN_STATE_FREE)
+ return s_all_conn_closed;
+ else
+ return s_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());
- 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);
- }
+ 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) {
- // putty会率先发第一个包,SecureCRT会通过脚本发第一个包
- return _do_negotiation_with_client(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)
- return s_negotiation_with_client;
+sess_state TelnetSession::_do_negotiation_with_client(TelnetConn *conn) {
+ if (NULL == conn)
+ return s_negotiation_with_client;
- if (0 == conn->data().size())
- return s_negotiation_with_client;
+ if (0 == conn->data().size())
+ return s_negotiation_with_client;
- if (m_first_client_pkg) {
- m_first_client_pkg = false;
+ 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;
+ if (mbuf.size() > 14 && 0 == memcmp(mbuf.data(), "session:", 8)) {
+ m_is_putty_mode = false;
- mbuf.pop(8);
- for (; mbuf.size() > 0; ) {
- if (mbuf.data()[mbuf.size() - 1] == 0x0a || mbuf.data()[mbuf.size() - 1] == 0x0d)
- mbuf.size(mbuf.size() - 1);
- else
- break;
- }
+ mbuf.pop(8);
+ for (; mbuf.size() > 0;) {
+ if (mbuf.data()[mbuf.size() - 1] == 0x0a || mbuf.data()[mbuf.size() - 1] == 0x0d)
+ mbuf.size(mbuf.size() - 1);
+ else
+ 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 {
- m_is_putty_mode = true;
- }
- }
+ return _do_connect_server();
+ } else {
+ m_is_putty_mode = true;
+ }
+ }
- MemBuffer mbuf_msg;
- mbuf_msg.reserve(128);
- MemStream ms_msg(mbuf_msg);
+ MemBuffer mbuf_msg;
+ mbuf_msg.reserve(128);
+ MemStream ms_msg(mbuf_msg);
- MemBuffer mbuf_resp;
- mbuf_resp.reserve(conn->data().size());
- MemStream ms_resp(mbuf_resp);
+ MemBuffer mbuf_resp;
+ mbuf_resp.reserve(conn->data().size());
+ MemStream ms_resp(mbuf_resp);
- MemBuffer mbuf_sub;
- mbuf_sub.reserve(128);
- MemStream ms_sub(mbuf_sub);
+ MemBuffer mbuf_sub;
+ mbuf_sub.reserve(128);
+ MemStream ms_sub(mbuf_sub);
- MemStream s(conn->data());
- ex_u8 ch = 0;
- ex_u8 ch_cmd = 0;
- for (; s.left() > 0;)
- {
- ch = s.get_u8();
- if (ch == TELNET_IAC)
- {
- if (s.left() < 2)
- return _do_close(TP_SESS_STAT_ERR_BAD_PKG);
+ MemStream s(conn->data());
+ ex_u8 ch = 0;
+ ex_u8 ch_cmd = 0;
+ for (; s.left() > 0;) {
+ ch = s.get_u8();
+ if (ch == TELNET_IAC) {
+ if (s.left() < 2)
+ return _do_close(TP_SESS_STAT_ERR_BAD_PKG);
- if (mbuf_sub.size() > 0)
- {
- // 已经得到一个sub negotiation,在处理新的数据前,先处理掉旧的
- EXLOG_BIN(mbuf_sub.data(), mbuf_sub.size(), "-=-=-=-=-=");
- ms_sub.reset();
- }
+ if (mbuf_sub.size() > 0) {
+ // 已经得到一个sub negotiation,在处理新的数据前,先处理掉旧的
+ EXLOG_BIN(mbuf_sub.data(), mbuf_sub.size(), "-=-=-=-=-=");
+ ms_sub.reset();
+ }
- ch_cmd = s.get_u8();
- if (ch_cmd == TELNET_SB)
- {
- // SUB NEGOTIATION,变长数据,以 FF F0 结束
- bool have_SE = false;
- ex_u8 ch_sub = 0;
- for (; s.left() > 0;)
- {
- ch_sub = s.get_u8();
- if (ch_sub == TELNET_IAC)
- {
- if (s.left() > 0)
- {
- if (s.get_u8() == TELNET_SE)
- {
- have_SE = true;
- break;
- }
- else
- return _do_close(TP_SESS_STAT_ERR_BAD_PKG);
- }
- }
- else
- {
- ms_sub.put_u8(ch_sub);
- }
- }
+ ch_cmd = s.get_u8();
+ if (ch_cmd == TELNET_SB) {
+ // SUB NEGOTIATION,变长数据,以 FF F0 结束
+ bool have_SE = false;
+ ex_u8 ch_sub = 0;
+ for (; s.left() > 0;) {
+ ch_sub = s.get_u8();
+ if (ch_sub == TELNET_IAC) {
+ if (s.left() > 0) {
+ if (s.get_u8() == TELNET_SE) {
+ have_SE = true;
+ break;
+ } else
+ return _do_close(TP_SESS_STAT_ERR_BAD_PKG);
+ }
+ } 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)
- {
- 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)
- {
- 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)
- {
- 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)
- {
- ms_resp.put_u8(TELNET_IAC);
- ms_resp.put_u8(TELNET_DO);
- ms_resp.put_u8(s.get_u8());
- }
- else
- {
- s.skip(1);
- }
- }
- else
- {
- ms_msg.put_u8(ch);
- }
- }
+ if (!have_SE)
+ return _do_close(TP_SESS_STAT_ERR_BAD_PKG);
+ } 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) {
+ 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) {
+ 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) {
+ ms_resp.put_u8(TELNET_IAC);
+ ms_resp.put_u8(TELNET_DO);
+ ms_resp.put_u8(s.get_u8());
+ } else {
+ s.skip(1);
+ }
+ } else {
+ ms_msg.put_u8(ch);
+ }
+ }
- conn->data().empty();
+ conn->data().empty();
- if (mbuf_resp.size() > 0)
- {
- conn->send(mbuf_resp.data(), mbuf_resp.size());
- }
+ if (mbuf_resp.size() > 0) {
+ conn->send(mbuf_resp.data(), mbuf_resp.size());
+ }
- if (mbuf_sub.size() == 5)
- {
- // 客户端窗口大小
- if (0x1f == mbuf_sub.data()[0]) {
- ms_sub.rewind();
- ms_sub.skip(1);
- m_win_width = ms_sub.get_u16_be();
- m_win_height = ms_sub.get_u16_be();
+ if (mbuf_sub.size() == 5) {
+ // 客户端窗口大小
+ if (0x1f == mbuf_sub.data()[0]) {
+ ms_sub.rewind();
+ ms_sub.skip(1);
+ m_win_width = ms_sub.get_u16_be();
+ m_win_height = ms_sub.get_u16_be();
- ms_resp.reset();
- ms_resp.put_u8(TELNET_IAC);
- ms_resp.put_u8(TELNET_SB);
- ms_resp.put_bin(mbuf_sub.data(), 5);
- ms_resp.put_u8(TELNET_IAC);
- ms_resp.put_u8(TELNET_SE);
- conn->send(mbuf_resp.data(), mbuf_resp.size());
- }
+ ms_resp.reset();
+ ms_resp.put_u8(TELNET_IAC);
+ ms_resp.put_u8(TELNET_SB);
+ ms_resp.put_bin(mbuf_sub.data(), 5);
+ ms_resp.put_u8(TELNET_IAC);
+ ms_resp.put_u8(TELNET_SE);
+ conn->send(mbuf_resp.data(), mbuf_resp.size());
+ }
- // 发送下列指令,putty才会将登陆用户名发过来(也就是SID)
- ex_u8 _d[] = {
- 0xff, 0xfa, 0x27, 0x01,
- 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));
- return s_negotiation_with_client;
- }
+ // 发送下列指令,putty才会将登陆用户名发过来(也就是SID)
+ ex_u8 _d[] = {
+ 0xff, 0xfa, 0x27, 0x01,
+ 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));
+ return s_negotiation_with_client;
+ }
- if (mbuf_sub.size() > 8)
- {
- // 可能含有putty的登录用户名信息(就是SID啦)
- if (0 == memcmp(mbuf_sub.data(), "\x27\x00\x00\x55\x53\x45\x52\x01", 8)) // '...USER.
- {
- mbuf_sub.pop(8);
- for (; mbuf_sub.size() > 0;)
- {
- if (mbuf_sub.data()[mbuf_sub.size() - 1] == 0x0a || mbuf_sub.data()[mbuf_sub.size() - 1] == 0x0d)
- mbuf_sub.size(mbuf_sub.size() - 1);
- else
- break;
- }
+ if (mbuf_sub.size() > 8) {
+ // 可能含有putty的登录用户名信息(就是SID啦)
+ if (0 == memcmp(mbuf_sub.data(), "\x27\x00\x00\x55\x53\x45\x52\x01", 8)) // '...USER.
+ {
+ mbuf_sub.pop(8);
+ for (; mbuf_sub.size() > 0;) {
+ if (mbuf_sub.data()[mbuf_sub.size() - 1] == 0x0a || mbuf_sub.data()[mbuf_sub.size() - 1] == 0x0d)
+ mbuf_sub.size(mbuf_sub.size() - 1);
+ else
+ 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();
+ }
+ }
- if (m_sid.length() > 0)
- {
- return _do_connect_server();
- }
+ if (m_sid.length() > 0) {
+ return _do_connect_server();
+ }
- return s_negotiation_with_client;
+ return s_negotiation_with_client;
}
sess_state TelnetSession::_do_connect_server() {
- EXLOGW("[telnet] session-id: [%s]\n", m_sid.c_str());
+ EXLOGW("[telnet] session-id: [%s]\n", m_sid.c_str());
- m_conn_info = g_telnet_env.get_connect_info(m_sid.c_str());
+ m_conn_info = g_telnet_env.get_connect_info(m_sid.c_str());
- if (NULL == m_conn_info) {
- EXLOGE("[telnet] no such session: %s\n", m_sid.c_str());
- return _do_close(TP_SESS_STAT_ERR_SESSION);
- }
- 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;
- m_acc_secret = m_conn_info->acc_secret;
- m_username_prompt = m_conn_info->username_prompt;
- m_password_prompt = m_conn_info->password_prompt;
+ if (NULL == m_conn_info) {
+ EXLOGE("[telnet] no such session: %s\n", m_sid.c_str());
+ return _do_close(TP_SESS_STAT_ERR_SESSION);
+ } 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;
+ m_acc_secret = m_conn_info->acc_secret;
+ m_username_prompt = m_conn_info->username_prompt;
+ m_password_prompt = m_conn_info->password_prompt;
- if (m_conn_info->protocol_type != TP_PROTOCOL_TYPE_TELNET) {
- EXLOGE("[telnet] session '%s' is not for TELNET.\n", m_sid.c_str());
- return _do_close(TP_SESS_STAT_ERR_SESSION);
- }
+ if (m_conn_info->protocol_type != TP_PROTOCOL_TYPE_TELNET) {
+ EXLOGE("[telnet] session '%s' is not for TELNET.\n", m_sid.c_str());
+ return _do_close(TP_SESS_STAT_ERR_SESSION);
+ }
- if (m_conn_info->auth_type != TP_AUTH_TYPE_NONE) {
- if (m_acc_name.length() == 0 || m_username_prompt.length() == 0 || m_acc_secret.length() == 0 || m_password_prompt.length() == 0) {
- EXLOGE("[telnet] invalid connection param.\n");
- return _do_close(TP_SESS_STAT_ERR_SESSION);
- }
- }
+ if (m_conn_info->auth_type != TP_AUTH_TYPE_NONE) {
+ if (m_acc_name.length() == 0 || m_username_prompt.length() == 0 || m_acc_secret.length() == 0 ||
+ m_password_prompt.length() == 0) {
+ EXLOGE("[telnet] invalid connection param.\n");
+ return _do_close(TP_SESS_STAT_ERR_SESSION);
+ }
+ }
- }
+ }
- // try to connect to real server.
- m_conn_server->connect(m_conn_ip.c_str(), m_conn_port);
+ // try to connect to real server.
+ m_conn_server->connect(m_conn_ip.c_str(), m_conn_port);
// ex_astr szmsg = "Connect to ";
// szmsg += m_conn_ip;
@@ -451,184 +419,172 @@ sess_state TelnetSession::_do_connect_server() {
// m_conn_client->send((ex_u8*)szmsg.c_str(), szmsg.length());
- return s_noop;
+ return s_noop;
}
sess_state TelnetSession::_do_server_connected() {
- m_conn_client->data().empty();
- m_conn_server->data().empty();
+ m_conn_client->data().empty();
+ m_conn_server->data().empty();
- m_status = s_relay;
+ m_status = s_relay;
- // 如果没有设置用户名/密码,则无需登录
- if (m_conn_info->auth_type == TP_AUTH_TYPE_NONE) {
- m_username_sent = true;
- m_password_sent = true;
- }
+ // 如果没有设置用户名/密码,则无需登录
+ if (m_conn_info->auth_type == TP_AUTH_TYPE_NONE) {
+ m_username_sent = true;
+ m_password_sent = true;
+ }
- m_is_relay = true;
- EXLOGW("[telnet] enter relay mode.\n");
+ m_is_relay = true;
+ EXLOGW("[telnet] enter relay mode.\n");
- if (!_on_session_begin()) {
- return _do_close(TP_SESS_STAT_ERR_INTERNAL);
- }
+ if (!_on_session_begin()) {
+ return _do_close(TP_SESS_STAT_ERR_INTERNAL);
+ }
- int w = 50;
- if (m_win_width != 0) {
+ int w = 50;
+ if (m_win_width != 0) {
#ifdef EX_OS_WIN32
- int w = min(m_win_width, 128);
+ int w = min(m_win_width, 128);
#else
- int w = std::min(m_win_width, 128);
+ int w = std::min(m_win_width, 128);
#endif
- m_startup_win_size_recorded = true;
- m_rec.record_win_size_startup(m_win_width, m_win_height);
- }
+ m_startup_win_size_recorded = true;
+ m_rec.record_win_size_startup(m_win_width, m_win_height);
+ }
- char buf[512] = { 0 };
+ char buf[512] = {0};
- const char *auth_mode = NULL;
- if (m_conn_info->auth_type == TP_AUTH_TYPE_PASSWORD)
- auth_mode = "password";
- else if (m_conn_info->auth_type == TP_AUTH_TYPE_NONE)
- auth_mode = "nothing";
- else
- auth_mode = "unknown";
+ const char *auth_mode = NULL;
+ if (m_conn_info->auth_type == TP_AUTH_TYPE_PASSWORD)
+ auth_mode = "password";
+ else if (m_conn_info->auth_type == TP_AUTH_TYPE_NONE)
+ auth_mode = "nothing";
+ else
+ auth_mode = "unknown";
- ex_astr line(w, '=');
+ ex_astr line(w, '=');
- 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()
- );
+ 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()
+ );
- 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());
- }
+ 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());
+ }
- ex_u8 _d[] = "\xff\xfb\x1f\xff\xfb\x20\xff\xfb\x18\xff\xfb\x27\xff\xfd\x01\xff\xfb\x03\xff\xfd\x03";
- m_conn_server->send(_d, sizeof(_d) - 1);
- }
+ ex_u8 _d[] = "\xff\xfb\x1f\xff\xfb\x20\xff\xfb\x18\xff\xfb\x27\xff\xfd\x01\xff\xfb\x03\xff\xfd\x03";
+ m_conn_server->send(_d, sizeof(_d) - 1);
+ }
- return s_relay;
+ return s_relay;
}
sess_state TelnetSession::_do_relay(TelnetConn *conn) {
- m_last_access_timestamp = (ex_u32)time(NULL);
+ m_last_access_timestamp = (ex_u32) time(NULL);
- TelnetSession* _this = conn->session();
- bool is_processed = false;
+ TelnetSession *_this = conn->session();
+ bool is_processed = false;
- if (conn->is_server_side())
- {
+ if (conn->is_server_side()) {
// EXLOG_BIN(m_conn_client->data().data(), m_conn_client->data().size(), "<-- client:");
- // 收到了客户端发来的数据
- if (_this->m_is_putty_mode && !_this->m_username_sent)
- {
- if (_this->_putty_replace_username(m_conn_client, m_conn_server))
- {
- //_this->m_username_sent = true;
- is_processed = true;
- }
- }
+ // 收到了客户端发来的数据
+ if (_this->m_is_putty_mode && !_this->m_username_sent) {
+ if (_this->_putty_replace_username(m_conn_client, m_conn_server)) {
+ //_this->m_username_sent = true;
+ is_processed = true;
+ }
+ }
- if (is_processed)
- {
- m_conn_client->data().empty();
- return s_relay;
- }
+ if (is_processed) {
+ m_conn_client->data().empty();
+ return s_relay;
+ }
- if (_this->_parse_win_size(m_conn_client)) {
- if (!m_startup_win_size_recorded) {
- m_rec.record_win_size_startup(m_win_width, m_win_height);
- m_startup_win_size_recorded = true;
- }
- m_rec.record_win_size_change(m_win_width, m_win_height);
- }
+ if (_this->_parse_win_size(m_conn_client)) {
+ if (!m_startup_win_size_recorded) {
+ m_rec.record_win_size_startup(m_win_width, m_win_height);
+ m_startup_win_size_recorded = true;
+ }
+ m_rec.record_win_size_change(m_win_width, m_win_height);
+ }
- m_conn_server->send(m_conn_client->data().data(), m_conn_client->data().size());
- m_conn_client->data().empty();
- }
- else
- {
+ m_conn_server->send(m_conn_client->data().data(), m_conn_client->data().size());
+ m_conn_client->data().empty();
+ } else {
// EXLOG_BIN(m_conn_server->data().data(), m_conn_server->data().size(), "--> server:");
-
- // 收到了服务端返回的数据
- if (m_conn_server->data().data()[0] != TELNET_IAC)
- 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 (m_conn_server->data().data()[0] != TELNET_IAC)
+ 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())) {
// _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()))
- {
+ 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())) {
_this->m_username_sent = true;
_this->m_password_sent = true;
_this->m_username_sent = true;
- is_processed = true;
- }
- }
+ is_processed = true;
+ }
+ }
- if (is_processed)
- {
- m_conn_server->data().empty();
- return s_relay;
- }
+ if (is_processed) {
+ m_conn_server->data().empty();
+ return s_relay;
+ }
- m_conn_client->send(m_conn_server->data().data(), m_conn_server->data().size());
- m_conn_server->data().empty();
- }
+ m_conn_client->send(m_conn_server->data().data(), m_conn_server->data().size());
+ m_conn_server->data().empty();
+ }
- return s_relay;
+ 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:");
- size_t find_len = strlen(find);
- size_t send_len = strlen(send);
+ size_t find_len = strlen(find);
+ size_t send_len = strlen(send);
if (0 == find_len || 0 == send_len || conn_recv->data().size() < find_len) {
return false;
}
int find_range = conn_recv->data().size() - find_len;
- for (int i = 0; i <= find_range; ++i)
- {
- if (0 == memcmp(conn_recv->data().data() + i, find, find_len))
- {
+ for (int i = 0; i <= find_range; ++i) {
+ if (0 == memcmp(conn_recv->data().data() + i, find, find_len)) {
conn_remote->send(conn_recv->data().data(), conn_recv->data().size());
conn_recv->data().empty();
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;
@@ -636,233 +592,210 @@ bool TelnetSession::_parse_find_and_send(TelnetConn* conn_recv, TelnetConn* conn
}
#if 0
- MemBuffer mbuf_msg;
- mbuf_msg.reserve(128);
- MemStream ms_msg(mbuf_msg);
+ MemBuffer mbuf_msg;
+ mbuf_msg.reserve(128);
+ MemStream ms_msg(mbuf_msg);
- MemStream s(conn_recv->data());
- ex_u8 ch = 0;
- ex_u8 ch_cmd = 0;
- for (; s.left() > 0;)
- {
- ch = s.get_u8();
- if (ch == TELNET_IAC)
- {
- if (s.left() < 2)
- return false;
+ MemStream s(conn_recv->data());
+ ex_u8 ch = 0;
+ ex_u8 ch_cmd = 0;
+ for (; s.left() > 0;)
+ {
+ ch = s.get_u8();
+ if (ch == TELNET_IAC)
+ {
+ if (s.left() < 2)
+ return false;
- ch_cmd = s.get_u8();
- if (ch_cmd == TELNET_SB)
- {
- // SUB NEGOTIATION,变长数据,以 FF F0 结束
- bool have_SE = false;
- ex_u8 ch_sub = 0;
- for (; s.left() > 0;)
- {
- ch_sub = s.get_u8();
- if (ch_sub == TELNET_IAC)
- {
- if (s.left() > 0)
- {
- if (s.get_u8() == TELNET_SE)
- {
- have_SE = true;
- break;
- }
- else
- return false;
- }
- }
- }
+ ch_cmd = s.get_u8();
+ if (ch_cmd == TELNET_SB)
+ {
+ // SUB NEGOTIATION,变长数据,以 FF F0 结束
+ bool have_SE = false;
+ ex_u8 ch_sub = 0;
+ for (; s.left() > 0;)
+ {
+ ch_sub = s.get_u8();
+ if (ch_sub == TELNET_IAC)
+ {
+ if (s.left() > 0)
+ {
+ if (s.get_u8() == TELNET_SE)
+ {
+ have_SE = true;
+ break;
+ }
+ else
+ return false;
+ }
+ }
+ }
- if (!have_SE)
- return false;
- }
- else
- {
- s.skip(1);
- }
- }
- else
- {
- ms_msg.put_u8(ch);
- }
- }
+ if (!have_SE)
+ return false;
+ }
+ else
+ {
+ s.skip(1);
+ }
+ }
+ else
+ {
+ ms_msg.put_u8(ch);
+ }
+ }
- if (mbuf_msg.size() < find_len)
- return false;
+ if (mbuf_msg.size() < find_len)
+ return false;
- int find_range = mbuf_msg.size() - find_len;
- for (int i = 0; i < find_range; ++i)
- {
- if (0 == memcmp(mbuf_msg.data() + i, find, find_len))
- {
- conn_remote->send(conn_recv->data().data(), conn_recv->data().size());
- conn_recv->data().empty();
+ int find_range = mbuf_msg.size() - find_len;
+ for (int i = 0; i < find_range; ++i)
+ {
+ if (0 == memcmp(mbuf_msg.data() + i, find, find_len))
+ {
+ conn_remote->send(conn_recv->data().data(), conn_recv->data().size());
+ conn_recv->data().empty();
- mbuf_msg.empty();
- mbuf_msg.append((ex_u8*)send, send_len);
- mbuf_msg.append((ex_u8*)"\x0d\x0a", 2);
- conn_recv->send(mbuf_msg.data(), mbuf_msg.size());
- return true;
- }
- }
+ mbuf_msg.empty();
+ mbuf_msg.append((ex_u8*)send, send_len);
+ mbuf_msg.append((ex_u8*)"\x0d\x0a", 2);
+ conn_recv->send(mbuf_msg.data(), mbuf_msg.size());
+ return true;
+ }
+ }
#endif
- return false;
+ return false;
}
-bool TelnetSession::_putty_replace_username(TelnetConn* conn_recv, TelnetConn* conn_remote)
-{
- bool replaced = false;
+bool TelnetSession::_putty_replace_username(TelnetConn *conn_recv, TelnetConn *conn_remote) {
+ bool replaced = false;
- MemBuffer mbuf_msg;
- mbuf_msg.reserve(128);
- MemStream ms_msg(mbuf_msg);
+ MemBuffer mbuf_msg;
+ mbuf_msg.reserve(128);
+ MemStream ms_msg(mbuf_msg);
- MemStream s(conn_recv->data());
- ex_u8 ch = 0;
- ex_u8 ch_cmd = 0;
- for (; s.left() > 0;)
- {
- ch = s.get_u8();
- if (ch == TELNET_IAC)
- {
- if (s.left() < 2)
- return false;
+ MemStream s(conn_recv->data());
+ ex_u8 ch = 0;
+ ex_u8 ch_cmd = 0;
+ for (; s.left() > 0;) {
+ ch = s.get_u8();
+ if (ch == TELNET_IAC) {
+ if (s.left() < 2)
+ return false;
- ch_cmd = s.get_u8();
- if (ch_cmd == TELNET_SB)
- {
- size_t _begin = s.offset();
- size_t _end = 0;
+ ch_cmd = s.get_u8();
+ if (ch_cmd == TELNET_SB) {
+ size_t _begin = s.offset();
+ size_t _end = 0;
- // SUB NEGOTIATION,变长数据,以 FF F0 结束
- bool have_SE = false;
- ex_u8 ch_sub = 0;
- for (; s.left() > 0;)
- {
- _end = s.offset();
- ch_sub = s.get_u8();
- if (ch_sub == TELNET_IAC)
- {
- if (s.left() > 0)
- {
- if (s.get_u8() == TELNET_SE)
- {
- have_SE = true;
- break;
- }
- else
- return false;
- }
- }
- }
+ // SUB NEGOTIATION,变长数据,以 FF F0 结束
+ bool have_SE = false;
+ ex_u8 ch_sub = 0;
+ for (; s.left() > 0;) {
+ _end = s.offset();
+ ch_sub = s.get_u8();
+ if (ch_sub == TELNET_IAC) {
+ if (s.left() > 0) {
+ if (s.get_u8() == TELNET_SE) {
+ have_SE = true;
+ break;
+ } else
+ return false;
+ }
+ }
+ }
- if (!have_SE)
- return false;
+ if (!have_SE)
+ return false;
- size_t len = _end - _begin;
- if (len <= 8 || 0 != memcmp("\x27\x00\x00\x55\x53\x45\x52\x01", conn_recv->data().data() + _begin, 8))
- {
- ms_msg.put_u8(TELNET_IAC);
- ms_msg.put_u8(TELNET_SB);
- ms_msg.put_bin(conn_recv->data().data() + _begin, len);
- ms_msg.put_u8(TELNET_IAC);
- ms_msg.put_u8(TELNET_SE);
- continue;
- }
+ size_t len = _end - _begin;
+ if (len <= 8 || 0 != memcmp("\x27\x00\x00\x55\x53\x45\x52\x01", conn_recv->data().data() + _begin, 8)) {
+ ms_msg.put_u8(TELNET_IAC);
+ ms_msg.put_u8(TELNET_SB);
+ ms_msg.put_bin(conn_recv->data().data() + _begin, len);
+ ms_msg.put_u8(TELNET_IAC);
+ ms_msg.put_u8(TELNET_SE);
+ continue;
+ }
- // 到这里就找到了客户端发来的用户名,我们将其替换为真实的远程账号。
+ // 到这里就找到了客户端发来的用户名,我们将其替换为真实的远程账号。
- 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_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*)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);
+ ms_msg.put_u8(TELNET_IAC);
+ ms_msg.put_u8(TELNET_SE);
- replaced = true;
- }
- else
- {
- ms_msg.put_u8(ch);
- ms_msg.put_u8(ch_cmd);
- ms_msg.put_u8(s.get_u8());
- }
- }
- else
- {
- ms_msg.put_u8(ch);
- }
- }
+ replaced = true;
+ } else {
+ ms_msg.put_u8(ch);
+ ms_msg.put_u8(ch_cmd);
+ ms_msg.put_u8(s.get_u8());
+ }
+ } else {
+ ms_msg.put_u8(ch);
+ }
+ }
- if (replaced)
- {
- conn_remote->send(mbuf_msg.data(), mbuf_msg.size());
- return true;
- }
+ if (replaced) {
+ conn_remote->send(mbuf_msg.data(), mbuf_msg.size());
+ return true;
+ }
- return false;
+ return false;
}
-bool TelnetSession::_parse_win_size(TelnetConn* conn) {
- if (conn->data().size() < 9)
- return false;
- if (conn->data().data()[0] != TELNET_IAC)
- return false;
+bool TelnetSession::_parse_win_size(TelnetConn *conn) {
+ if (conn->data().size() < 9)
+ return false;
+ if (conn->data().data()[0] != TELNET_IAC)
+ return false;
- bool is_sub = false;
- MemStream s(conn->data());
- for (; s.left() > 0;)
- {
- if (s.get_u8() == TELNET_IAC)
- {
- if (s.left() < 2)
- return false;
+ bool is_sub = false;
+ MemStream s(conn->data());
+ for (; s.left() > 0;) {
+ if (s.get_u8() == TELNET_IAC) {
+ if (s.left() < 2)
+ return false;
- if (s.get_u8() == TELNET_SB)
- {
- size_t _begin = s.offset();
- size_t _end = 0;
+ if (s.get_u8() == TELNET_SB) {
+ size_t _begin = s.offset();
+ size_t _end = 0;
- // SUB NEGOTIATION,变长数据,以 TELNET_IAC+TELNET_SE (FF F0) 结束
- bool have_SE = false;
- ex_u8 ch_sub = 0;
- for (; s.left() > 0;)
- {
- _end = s.offset();
- if (s.get_u8() == TELNET_IAC)
- {
- if (s.left() > 0)
- {
- if (s.get_u8() == TELNET_SE)
- {
- have_SE = true;
- break;
- }
- else
- return false;
- }
- }
- }
+ // SUB NEGOTIATION,变长数据,以 TELNET_IAC+TELNET_SE (FF F0) 结束
+ bool have_SE = false;
+ ex_u8 ch_sub = 0;
+ for (; s.left() > 0;) {
+ _end = s.offset();
+ if (s.get_u8() == TELNET_IAC) {
+ if (s.left() > 0) {
+ if (s.get_u8() == TELNET_SE) {
+ have_SE = true;
+ break;
+ } else
+ return false;
+ }
+ }
+ }
- if (!have_SE)
- return false;
+ if (!have_SE)
+ return false;
- size_t len = _end - _begin;
- if (len == 5 && 0x1F == conn->data().data()[_begin]) {
- s.seek(_begin + 1);
- m_win_width = s.get_u16_be();
- m_win_height = s.get_u16_be();
- return true;
- }
- }
- }
- }
+ size_t len = _end - _begin;
+ if (len == 5 && 0x1F == conn->data().data()[_begin]) {
+ s.seek(_begin + 1);
+ m_win_width = s.get_u16_be();
+ m_win_height = s.get_u16_be();
+ return true;
+ }
+ }
+ }
+ }
- return false;
+ return false;
}