重构核心服务SSH模块,修正以下问题:

1. 某些情况下会卡在登录流程(通道中创建shell操作与收到服务端数据操作造成死锁);
2. 某些情况下连接断开了,但web界面仍然显示使用中(没有正确处理断开事件,没有更新数据库);
3. cat一个大文件会很慢,有时会导致连接断开(每个数据包都完整解析导致处理时间过长);
4. 连接/认证过程出错(密码错误、协议不支持、远程连接超时等等),均会提示用户重新输入密码(改为断开连接,避免造成误解);
dev
Apex Liu 2020-11-02 02:50:49 +08:00
parent b7d9f6f0d8
commit f26c71d52d
34 changed files with 1692 additions and 2112 deletions

View File

@ -4,67 +4,65 @@
#include "ex_types.h" #include "ex_types.h"
#include "ex_thread.h" #include "ex_thread.h"
#define EX_LOG_LEVEL_DEBUG 0 #define EX_LOG_LEVEL_DEBUG 0
#define EX_LOG_LEVEL_VERBOSE 1 #define EX_LOG_LEVEL_VERBOSE 1
#define EX_LOG_LEVEL_INFO 2 #define EX_LOG_LEVEL_INFO 2
#define EX_LOG_LEVEL_WARN 3 #define EX_LOG_LEVEL_WARN 3
#define EX_LOG_LEVEL_ERROR 4 #define EX_LOG_LEVEL_ERROR 4
#define EX_LOG_FILE_MAX_SIZE 1024*1024*10 #define EX_LOG_FILE_MAX_SIZE 1024*1024*10
#define EX_LOG_FILE_MAX_COUNT 10 #define EX_LOG_FILE_MAX_COUNT 10
class ExLogger class ExLogger
{ {
public: public:
ExLogger(); ExLogger();
~ExLogger(); ~ExLogger();
bool set_log_file(const ex_wstr& log_path, const ex_wstr& log_name, ex_u32 max_filesize, ex_u8 max_count); bool set_log_file(const ex_wstr &log_path, const ex_wstr &log_name, ex_u32 max_filesize, ex_u8 max_count);
void log_a(int level, const char* fmt, va_list valist); void log_a(int level, const char *fmt, va_list valist);
void log_w(int level, const wchar_t* fmt, va_list valist); void log_w(int level, const wchar_t *fmt, va_list valist);
bool write_a(const char* buf); bool write_a(const char *buf);
bool write_w(const wchar_t* buf); bool write_w(const wchar_t *buf);
protected: protected:
bool _open_file(); bool _open_file();
bool _rotate_file(void); // 将现有日志文件改名备份,然后新开一个日志文件
// 将现有日志文件改名备份,然后新开一个日志文件
bool _rotate_file();
public: public:
ExThreadLock lock; ExThreadLock lock;
int min_level; int min_level;
bool debug_mode; bool debug_mode;
bool to_console; bool to_console;
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
HANDLE console_handle; HANDLE console_handle;
#endif #endif
protected: protected:
ex_u32 m_filesize; ex_u32 m_filesize;
ex_u32 m_max_filesize; ex_u32 m_max_filesize;
ex_u8 m_max_count; ex_u8 m_max_count;
ex_wstr m_path; ex_wstr m_path;
ex_wstr m_filename; ex_wstr m_filename;
ex_wstr m_fullname; ex_wstr m_fullname;
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
HANDLE m_file; HANDLE m_file;
#else #else
FILE* m_file; FILE *m_file;
#endif #endif
}; };
//extern ExLogger g_ex_logger; void EXLOG_USE_LOGGER(ExLogger *logger);
// extern void* ex_logger;
void EXLOG_USE_LOGGER(ExLogger* logger);
void EXLOG_LEVEL(int min_level); void EXLOG_LEVEL(int min_level);
void EXLOG_DEBUG(bool debug_mode); void EXLOG_DEBUG(bool debug_mode);
// 设定日志文件名及路径如未指定路径则为可执行程序所在目录下的log目录。 // 设定日志文件名及路径如未指定路径则为可执行程序所在目录下的log目录。
void EXLOG_FILE(const wchar_t* log_file, const wchar_t* log_path = NULL, ex_u32 max_filesize = EX_LOG_FILE_MAX_SIZE, ex_u8 max_filecount = EX_LOG_FILE_MAX_COUNT); void EXLOG_FILE(const wchar_t *log_file, const wchar_t *log_path = nullptr, ex_u32 max_filesize = EX_LOG_FILE_MAX_SIZE, ex_u8 max_filecount = EX_LOG_FILE_MAX_COUNT);
void EXLOG_CONSOLE(bool output_to_console); void EXLOG_CONSOLE(bool output_to_console);
@ -82,20 +80,20 @@ void ex_printf_e_lasterror(const wchar_t* fmt, ...);
#endif #endif
void ex_printf_d(const char* fmt, ...); void ex_printf_d(const char *fmt, ...);
void ex_printf_v(const char* fmt, ...); void ex_printf_v(const char *fmt, ...);
void ex_printf_i(const char* fmt, ...); void ex_printf_i(const char *fmt, ...);
void ex_printf_w(const char* fmt, ...); void ex_printf_w(const char *fmt, ...);
void ex_printf_e(const char* fmt, ...); void ex_printf_e(const char *fmt, ...);
void ex_printf_d(const wchar_t* fmt, ...); void ex_printf_d(const wchar_t *fmt, ...);
void ex_printf_v(const wchar_t* fmt, ...); void ex_printf_v(const wchar_t *fmt, ...);
void ex_printf_i(const wchar_t* fmt, ...); void ex_printf_i(const wchar_t *fmt, ...);
void ex_printf_w(const wchar_t* fmt, ...); void ex_printf_w(const wchar_t *fmt, ...);
void ex_printf_e(const wchar_t* fmt, ...); void ex_printf_e(const wchar_t *fmt, ...);
void ex_printf_bin(const ex_u8* bin_data, size_t bin_size, const char* fmt, ...); void ex_printf_bin(const ex_u8 *bin_data, size_t bin_size, const char *fmt, ...);
void ex_printf_bin(const ex_u8* bin_data, size_t bin_size, const wchar_t* fmt, ...); void ex_printf_bin(const ex_u8 *bin_data, size_t bin_size, const wchar_t *fmt, ...);
#endif // __EX_LOG_H__ #endif // __EX_LOG_H__

View File

@ -81,7 +81,6 @@
# endif # endif
#endif #endif
/* /*
* On Windows PATH_MAX does not exist but MAX_PATH does. * On Windows PATH_MAX does not exist but MAX_PATH does.
* WinAPI MAX_PATH limit is only 256. MSVCR fuctions does not have this limit. * WinAPI MAX_PATH limit is only 256. MSVCR fuctions does not have this limit.

View File

@ -206,6 +206,6 @@ int ex_atomic_inc(volatile int* pt);
int ex_atomic_dec(volatile int* pt); int ex_atomic_dec(volatile int* pt);
// 线程相关操作 // 线程相关操作
ex_u64 ex_get_thread_id(); uint64_t ex_get_thread_id();
#endif // __EX_THREAD_H__ #endif // __EX_THREAD_H__

View File

@ -2,6 +2,7 @@
#define __LIB_EX_TYPE_H__ #define __LIB_EX_TYPE_H__
#include "ex_platform.h" #include "ex_platform.h"
#include <cstdint>
#include <vector> #include <vector>
@ -31,7 +32,7 @@ typedef int EX_BOOL;
typedef std::vector<ex_u8> ex_bin; typedef std::vector<ex_u8> ex_bin;
typedef std::vector<char> ex_chars; typedef std::vector<char> ex_chars;
typedef ex_u32 ex_rv; typedef uint32_t ex_rv;
#if defined(EX_OS_WIN32) #if defined(EX_OS_WIN32)

View File

@ -32,7 +32,6 @@ void ex_sleep_ms(int ms);
EX_BOOL ex_localtime_now(int* t, struct tm* dt); EX_BOOL ex_localtime_now(int* t, struct tm* dt);
FILE* ex_fopen(const ex_wstr& filename, const wchar_t* mode); FILE* ex_fopen(const ex_wstr& filename, const wchar_t* mode);
FILE* ex_fopen(const ex_astr& filename, const char* mode); FILE* ex_fopen(const ex_astr& filename, const char* mode);

View File

@ -1,5 +1,6 @@
#include <ex/ex_log.h> #include <ex/ex_log.h>
#include <ex/ex_path.h> #include <ex/ex_path.h>
#include <ex/ex_thread.h>
//#include <ex/ex_thread.h> //#include <ex/ex_thread.h>
//#include <vector> //#include <vector>
//#include <deque> //#include <deque>
@ -16,119 +17,125 @@
#define EX_LOG_CONTENT_MAX_LEN 2048 #define EX_LOG_CONTENT_MAX_LEN 2048
//typedef std::deque<unsigned long long> log_file_deque; static ExLogger* g_exlog = nullptr;
static ExLogger* g_exlog = NULL; void EXLOG_USE_LOGGER(ExLogger* logger) {
void EXLOG_USE_LOGGER(ExLogger* logger)
{
g_exlog = logger; g_exlog = logger;
} }
void EXLOG_LEVEL(int min_level) void EXLOG_LEVEL(int min_level) {
{ if (nullptr != g_exlog)
if(NULL != g_exlog) g_exlog->min_level = min_level;
g_exlog->min_level = min_level;
} }
void EXLOG_DEBUG(bool debug_mode) void EXLOG_DEBUG(bool debug_mode) {
{ if (nullptr != g_exlog)
if (NULL != g_exlog) g_exlog->debug_mode = debug_mode;
g_exlog->debug_mode = debug_mode;
} }
void EXLOG_CONSOLE(bool output_to_console) void EXLOG_CONSOLE(bool output_to_console) {
{ if (nullptr != g_exlog)
if(NULL != g_exlog) g_exlog->to_console = output_to_console;
g_exlog->to_console = output_to_console;
} }
void EXLOG_FILE(const wchar_t* log_file, const wchar_t* log_path /*= NULL*/, ex_u32 max_filesize /*= EX_LOG_FILE_MAX_SIZE*/, ex_u8 max_filecount /*= EX_LOG_FILE_MAX_COUNT*/) void EXLOG_FILE(const wchar_t* log_file, const wchar_t* log_path /*= nullptr*/, ex_u32 max_filesize /*= EX_LOG_FILE_MAX_SIZE*/, ex_u8 max_filecount /*= EX_LOG_FILE_MAX_COUNT*/) {
{ if (nullptr == g_exlog)
if(NULL == g_exlog)
return; return;
ex_wstr _path; ex_wstr _path;
if (NULL == log_path) if (nullptr == log_path) {
{ ex_exec_file(_path);
ex_exec_file(_path); ex_dirname(_path);
ex_dirname(_path); ex_path_join(_path, false, L"log", nullptr);
ex_path_join(_path, false, L"log", NULL); }
} else {
else _path = log_path;
{ }
_path = log_path;
}
g_exlog->set_log_file(_path, log_file, max_filesize, max_filecount); g_exlog->set_log_file(_path, log_file, max_filesize, max_filecount);
} }
ExLogger::ExLogger() ExLogger::ExLogger() {
{
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
console_handle = GetStdHandle(STD_OUTPUT_HANDLE); console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
#endif #endif
min_level = EX_LOG_LEVEL_INFO; min_level = EX_LOG_LEVEL_INFO;
debug_mode = false; debug_mode = false;
to_console = true; to_console = true;
m_file = NULL; m_file = nullptr;
m_filesize = 0; m_filesize = 0;
} }
ExLogger::~ExLogger() ExLogger::~ExLogger() {
{ if (nullptr != m_file) {
if (NULL != m_file)
{
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
CloseHandle(m_file); CloseHandle(m_file);
#else #else
fclose(m_file); fclose(m_file);
#endif #endif
m_file = NULL; m_file = nullptr;
} }
} }
void ExLogger::log_a(int level, const char* fmt, va_list valist) void ExLogger::log_a(int level, const char* fmt, va_list valist) {
{ if (nullptr == fmt)
if (NULL == fmt) return;
return;
if (0 == strlen(fmt)) if (0 == strlen(fmt))
return; return;
char szTmp[4096] = { 0 }; const char* _level = "";
size_t offset = 0; if (level == EX_LOG_LEVEL_ERROR)
_level = " [E]";
else if (level == EX_LOG_LEVEL_WARN)
_level = " [W]";
else if (level == EX_LOG_LEVEL_INFO)
_level = " [I]";
if (level == EX_LOG_LEVEL_ERROR) char prefix[100] = {0};
{ #ifdef EX_OS_WIN32
szTmp[0] = '['; SYSTEMTIME st;
szTmp[1] = 'E'; GetLocalTime(&st);
szTmp[2] = ']'; // sprintf_s(prefix, 100, "[%04d-%02d-%02d %02d:%02d:%02d %llu%s] ", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, ex_get_thread_id(), _level);
szTmp[3] = ' '; // sprintf_s(prefix, 100, "[%02d-%02d %02d:%02d:%02d %llu%s] ", st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, ex_get_thread_id(), _level);
offset = 4; sprintf_s(prefix, 100, "[%04d%02d%02d %02d:%02d:%02d %llu%s] ", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, ex_get_thread_id(), _level);
} #else
time_t timep;
struct tm* p;
time(&timep);
p = localtime(&timep);
if (p == nullptr)
return;
// sprintf(prefix, "[%04d-%02d-%02d %02d:%02d:%02d %llu%s] ", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, ex_get_thread_id(), _level);
// sprintf(prefix, "[%02d-%02d %02d:%02d:%02d %llu%s] ", p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, ex_get_thread_id(), _level);
sprintf(prefix, "[%04d%02d%02d %02d:%02d:%02d %llu]%s ", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, ex_get_thread_id(), _level);
#endif
size_t offset = strlen(prefix);
char szTmp[4096] = {0};
memcpy(szTmp, prefix, offset);
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
vsnprintf_s(szTmp+offset, 4096-offset, 4095-offset, fmt, valist); vsnprintf_s(szTmp+offset, 4096-offset, 4095-offset, fmt, valist);
if(to_console) if(to_console)
{ {
if (NULL != console_handle) if (nullptr != console_handle)
{ {
printf_s("%s", szTmp); printf_s("%s", szTmp);
fflush(stdout); fflush(stdout);
} }
else else
{ {
if(debug_mode) if(debug_mode)
OutputDebugStringA(szTmp); OutputDebugStringA(szTmp);
} }
} }
#else #else
vsnprintf(szTmp+offset, 4095-offset, fmt, valist); vsnprintf(szTmp + offset, 4095 - offset, fmt, valist);
if(to_console) if (to_console) {
{
// On linux, the stdout only output the first time output format (char or wchar_t). // On linux, the stdout only output the first time output format (char or wchar_t).
// e.g.: first time you use printf(), then after that, every wprintf() not work, and vice versa. // e.g.: first time you use printf(), then after that, every wprintf() not work, and vice versa.
// so we always use wprintf() to fix that. // so we always use wprintf() to fix that.
@ -138,164 +145,186 @@ void ExLogger::log_a(int level, const char* fmt, va_list valist)
ex_astr2wstr(tmp, _tmp); ex_astr2wstr(tmp, _tmp);
wprintf(L"%ls", _tmp.c_str()); wprintf(L"%ls", _tmp.c_str());
fflush(stdout); fflush(stdout);
}
// printf("%s", szTmp);
// fflush(stdout);
}
#endif #endif
write_a(szTmp); write_a(szTmp);
} }
void ExLogger::log_w(int level, const wchar_t* fmt, va_list valist) void ExLogger::log_w(int level, const wchar_t* fmt, va_list valist) {
{ if (nullptr == fmt || 0 == wcslen(fmt))
if (NULL == fmt || 0 == wcslen(fmt)) return;
return;
wchar_t szTmp[4096] = { 0 }; const char* _level = "";
size_t offset = 0; if (level == EX_LOG_LEVEL_ERROR)
_level = " [E]";
if (level == EX_LOG_LEVEL_ERROR) else if (level == EX_LOG_LEVEL_WARN)
{ _level = " [W]";
szTmp[0] = L'['; else if (level == EX_LOG_LEVEL_INFO)
szTmp[1] = L'E'; _level = " [I]";
szTmp[2] = L']';
szTmp[3] = L' ';
offset = 4;
}
char prefix[100] = {0};
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
_vsnwprintf_s(szTmp+offset, 4096-offset, 4095-offset, fmt, valist); SYSTEMTIME st;
if(to_console) GetLocalTime(&st);
{ // sprintf_s(prefix, 100, "[%04d-%02d-%02d %02d:%02d:%02d %llu%s] ", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, ex_get_thread_id(), _level);
if (NULL != console_handle) // sprintf_s(prefix, 100, "[%02d-%02d %02d:%02d:%02d %llu%s] ", st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, ex_get_thread_id(), _level);
{ sprintf_s(prefix, 100, "[%04d%02d-%02d %02d:%02d:%02d %llu]%s ", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, ex_get_thread_id(), _level);
wprintf_s(_T("%s"), szTmp);
fflush(stdout);
}
else
{
if(debug_mode)
OutputDebugStringW(szTmp);
}
}
#else #else
vswprintf(szTmp+offset, 4095-offset, fmt, valist); time_t timep;
if(to_console) struct tm* p;
{ time(&timep);
wprintf(L"%ls", szTmp); p = localtime(&timep);
fflush(stdout); if (p == nullptr)
} return;
// sprintf(prefix, "[%04d-%02d-%02d %02d:%02d:%02d %llu%s] ", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, ex_get_thread_id(), _level);
// sprintf(prefix, "[%02d-%02d %02d:%02d:%02d %llu%s] ", p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, ex_get_thread_id(), _level);
sprintf(prefix, "[%04d%02d%02d %02d:%02d:%02d %llu]%s ", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, ex_get_thread_id(), _level);
#endif #endif
write_w(szTmp); ex_wstr w_prefix;
ex_astr2wstr(prefix, w_prefix);
size_t offset = wcslen(w_prefix.c_str());
wchar_t szTmp[4096] = {0};
memcpy(szTmp, w_prefix.c_str(), offset * sizeof(wchar_t));
#ifdef EX_OS_WIN32
_vsnwprintf_s(szTmp+offset, 4096-offset, 4095-offset, fmt, valist);
if(to_console)
{
if (nullptr != console_handle)
{
wprintf_s(_T("%s"), szTmp);
fflush(stdout);
}
else
{
if(debug_mode)
OutputDebugStringW(szTmp);
}
}
#else
vswprintf(szTmp + offset, 4095 - offset, fmt, valist);
if (to_console) {
wprintf(L"%ls", szTmp);
fflush(stdout);
}
#endif
write_w(szTmp);
} }
#define EX_PRINTF_XA(fn, level) \ #define EX_PRINTF_XA(fn, level) \
void fn(const char* fmt, ...) \ void fn(const char* fmt, ...) \
{ \ { \
if(NULL == g_exlog) \ if(nullptr == g_exlog) \
return; \ return; \
if (g_exlog->min_level > level) \ if (g_exlog->min_level > level) \
return; \ return; \
ExThreadSmartLock locker(g_exlog->lock); \ ExThreadSmartLock locker(g_exlog->lock); \
va_list valist; \ va_list valist; \
va_start(valist, fmt); \ va_start(valist, fmt); \
g_exlog->log_a(level, fmt, valist); \ g_exlog->log_a(level, fmt, valist); \
va_end(valist); \ va_end(valist); \
} }
#define EX_PRINTF_XW(fn, level) \ #define EX_PRINTF_XW(fn, level) \
void fn(const wchar_t* fmt, ...) \ void fn(const wchar_t* fmt, ...) \
{ \ { \
if(NULL == g_exlog) \ if(nullptr == g_exlog) \
return; \ return; \
if (g_exlog->min_level > level) \ if (g_exlog->min_level > level) \
return; \ return; \
ExThreadSmartLock locker(g_exlog->lock); \ ExThreadSmartLock locker(g_exlog->lock); \
va_list valist; \ va_list valist; \
va_start(valist, fmt); \ va_start(valist, fmt); \
g_exlog->log_w(level, fmt, valist); \ g_exlog->log_w(level, fmt, valist); \
va_end(valist); \ va_end(valist); \
} }
EX_PRINTF_XA(ex_printf_d, EX_LOG_LEVEL_DEBUG) EX_PRINTF_XA(ex_printf_d, EX_LOG_LEVEL_DEBUG)
EX_PRINTF_XA(ex_printf_v, EX_LOG_LEVEL_VERBOSE) EX_PRINTF_XA(ex_printf_v, EX_LOG_LEVEL_VERBOSE)
EX_PRINTF_XA(ex_printf_i, EX_LOG_LEVEL_INFO) EX_PRINTF_XA(ex_printf_i, EX_LOG_LEVEL_INFO)
EX_PRINTF_XA(ex_printf_w, EX_LOG_LEVEL_WARN) EX_PRINTF_XA(ex_printf_w, EX_LOG_LEVEL_WARN)
EX_PRINTF_XA(ex_printf_e, EX_LOG_LEVEL_ERROR) EX_PRINTF_XA(ex_printf_e, EX_LOG_LEVEL_ERROR)
EX_PRINTF_XW(ex_printf_d, EX_LOG_LEVEL_DEBUG) EX_PRINTF_XW(ex_printf_d, EX_LOG_LEVEL_DEBUG)
EX_PRINTF_XW(ex_printf_v, EX_LOG_LEVEL_VERBOSE) EX_PRINTF_XW(ex_printf_v, EX_LOG_LEVEL_VERBOSE)
EX_PRINTF_XW(ex_printf_i, EX_LOG_LEVEL_INFO) EX_PRINTF_XW(ex_printf_i, EX_LOG_LEVEL_INFO)
EX_PRINTF_XW(ex_printf_w, EX_LOG_LEVEL_WARN) EX_PRINTF_XW(ex_printf_w, EX_LOG_LEVEL_WARN)
EX_PRINTF_XW(ex_printf_e, EX_LOG_LEVEL_ERROR) EX_PRINTF_XW(ex_printf_e, EX_LOG_LEVEL_ERROR)
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
void ex_printf_e_lasterror(const char* fmt, ...) void ex_printf_e_lasterror(const char* fmt, ...)
{ {
ExThreadSmartLock locker(g_exlog->lock); ExThreadSmartLock locker(g_exlog->lock);
va_list valist; va_list valist;
va_start(valist, fmt); va_start(valist, fmt);
g_exlog->log_a(EX_LOG_LEVEL_ERROR, fmt, valist); g_exlog->log_a(EX_LOG_LEVEL_ERROR, fmt, valist);
va_end(valist); va_end(valist);
//========================================= //=========================================
LPVOID lpMsgBuf; LPVOID lpMsgBuf;
DWORD dw = GetLastError(); DWORD dw = GetLastError();
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), nullptr, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)&lpMsgBuf, 0, NULL); (LPSTR)&lpMsgBuf, 0, nullptr);
ex_printf_e(" - WinErr(%d): %s\n", dw, (LPSTR)lpMsgBuf); ex_printf_e(" - WinErr(%d): %s\n", dw, (LPSTR)lpMsgBuf);
LocalFree(lpMsgBuf); LocalFree(lpMsgBuf);
} }
void ex_printf_e_lasterror(const wchar_t* fmt, ...) void ex_printf_e_lasterror(const wchar_t* fmt, ...)
{ {
ExThreadSmartLock locker(g_exlog->lock); ExThreadSmartLock locker(g_exlog->lock);
va_list valist; va_list valist;
va_start(valist, fmt); va_start(valist, fmt);
g_exlog->log_w(EX_LOG_LEVEL_ERROR, fmt, valist); g_exlog->log_w(EX_LOG_LEVEL_ERROR, fmt, valist);
va_end(valist); va_end(valist);
//========================================= //=========================================
LPVOID lpMsgBuf; LPVOID lpMsgBuf;
DWORD dw = GetLastError(); DWORD dw = GetLastError();
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), nullptr, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)&lpMsgBuf, 0, NULL); (LPSTR)&lpMsgBuf, 0, nullptr);
ex_printf_e(" - WinErr(%d): %s\n", dw, (LPSTR)lpMsgBuf); ex_printf_e(" - WinErr(%d): %s\n", dw, (LPSTR)lpMsgBuf);
LocalFree(lpMsgBuf); LocalFree(lpMsgBuf);
} }
#endif #endif
void ex_printf_bin(const ex_u8* bin_data, size_t bin_size, const char* fmt, ...) void ex_printf_bin(const ex_u8* bin_data, size_t bin_size, const char* fmt, ...) {
{ if (nullptr == g_exlog)
if(NULL == g_exlog) return;
if (!g_exlog->debug_mode)
return; return;
if (!g_exlog->debug_mode)
return;
ExThreadSmartLock locker(g_exlog->lock); ExThreadSmartLock locker(g_exlog->lock);
if (nullptr == fmt)
if (NULL == fmt)
return; return;
if (0 == strlen(fmt)) if (0 == strlen(fmt))
return; return;
char szTmp[128] = { 0 }; char szTmp[128] = {0};
// size_t offset = 0;
va_list valist; va_list valist;
va_start(valist, fmt); va_start(valist, fmt);
@ -307,235 +336,186 @@ void ex_printf_bin(const ex_u8* bin_data, size_t bin_size, const char* fmt, ...)
#endif #endif
va_end(valist); va_end(valist);
// ex_printf_d("%s (%d/0x%02x Bytes)\n", szTmp, bin_size, bin_size);
//
//
//
// va_list valist;
// va_start(valist, fmt);
// g_exlog->log_a(EX_LOG_LEVEL_DEBUG, fmt, valist);
// va_end(valist);
//
ex_printf_d("%s (%d/0x%02x Bytes)\n", szTmp, bin_size, bin_size);
const ex_u8* line = bin_data; const ex_u8* line = bin_data;
size_t thisline = 0; size_t offset = 0;
size_t offset = 0; while (offset < bin_size) {
unsigned int i = 0; size_t _offset = 0;
memset(szTmp, 0, 128);
// char szTmp[128] = { 0 }; snprintf(szTmp + _offset, 128 - _offset, "%06x ", (int) offset);
size_t _offset = 0; _offset += 8;
while (offset < bin_size) size_t this_line = bin_size - offset;
{ if (this_line > 16)
memset(szTmp, 0, 128); this_line = 16;
_offset = 0;
snprintf(szTmp + _offset, 128 - _offset, "%06x ", (int)offset); size_t i = 0;
_offset += 8; for (; i < this_line; i++) {
snprintf(szTmp + _offset, 128 - _offset, "%02x ", line[i]);
_offset += 3;
}
thisline = bin_size - offset; snprintf(szTmp + _offset, 128 - _offset, " ");
if (thisline > 16) _offset += 2;
thisline = 16;
for (i = 0; i < thisline; i++) for (; i < 16; i++) {
{ snprintf(szTmp + _offset, 128 - _offset, " ");
snprintf(szTmp + _offset, 128 - _offset, "%02x ", line[i]); _offset += 3;
_offset += 3; }
}
snprintf(szTmp + _offset, 128 - _offset, " "); for (i = 0; i < this_line; i++) {
_offset += 2; snprintf(szTmp + _offset, 128 - _offset, "%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
_offset += 1;
}
for (; i < 16; i++) snprintf(szTmp + _offset, 128 - _offset, "\n");
{
snprintf(szTmp + _offset, 128 - _offset, " ");
_offset += 3;
}
for (i = 0; i < thisline; i++) ex_printf_d("%s", szTmp);
{
snprintf(szTmp + _offset, 128 - _offset, "%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
_offset += 1;
}
snprintf(szTmp + _offset, 128 - _offset, "\n"); offset += this_line;
_offset += 1; line += this_line;
}
ex_printf_d("%s", szTmp); fflush(stdout);
offset += thisline;
line += thisline;
}
fflush(stdout);
} }
bool ExLogger::set_log_file(const ex_wstr& log_path, const ex_wstr& log_name, ex_u32 max_filesize, ex_u8 max_count) bool ExLogger::set_log_file(const ex_wstr& log_path, const ex_wstr& log_name, ex_u32 max_filesize, ex_u8 max_count) {
{ m_max_filesize = max_filesize;
m_max_filesize = max_filesize; m_max_count = max_count;
m_max_count = max_count;
m_filename = log_name; m_filename = log_name;
m_path = log_path; m_path = log_path;
ex_abspath(m_path); ex_abspath(m_path);
ex_mkdirs(m_path); ex_mkdirs(m_path);
m_fullname = m_path; m_fullname = m_path;
ex_path_join(m_fullname, false, log_name.c_str(), NULL); ex_path_join(m_fullname, false, log_name.c_str(), nullptr);
return _open_file(); return _open_file();
} }
bool ExLogger::_open_file() {
bool ExLogger::_open_file() if (m_file) {
{
if (m_file)
{
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
CloseHandle(m_file); CloseHandle(m_file);
#else #else
fclose(m_file); fclose(m_file);
#endif #endif
m_file = NULL; m_file = nullptr;
} }
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
// 注意:这里必须使用 CreateFile() 来打开日志文件使用FILE指针无法传递给动态库进行操作。 // 注意:这里必须使用 CreateFile() 来打开日志文件使用FILE指针无法传递给动态库进行操作。
m_file = CreateFileW(m_fullname.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); m_file = CreateFileW(m_fullname.c_str(), GENERIC_WRITE, FILE_SHARE_READ, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
if (INVALID_HANDLE_VALUE == m_file) if (INVALID_HANDLE_VALUE == m_file)
{ {
m_file = NULL; m_file = nullptr;
return false; return false;
} }
SetFilePointer(m_file, 0, NULL, FILE_END); SetFilePointer(m_file, 0, nullptr, FILE_END);
m_filesize = GetFileSize(m_file, NULL); m_filesize = GetFileSize(m_file, nullptr);
#else #else
ex_astr _fullname; ex_astr _fullname;
ex_wstr2astr(m_fullname, _fullname); ex_wstr2astr(m_fullname, _fullname);
m_file = fopen(_fullname.c_str(), "a"); m_file = fopen(_fullname.c_str(), "a");
if (NULL == m_file) if (nullptr == m_file) {
{ return false;
return false; }
}
fseek(m_file, 0, SEEK_END); fseek(m_file, 0, SEEK_END);
m_filesize = (ex_u32)ftell(m_file); m_filesize = (ex_u32) ftell(m_file);
#endif #endif
return _rotate_file(); return _rotate_file();
} }
bool ExLogger::_rotate_file(void) bool ExLogger::_rotate_file() {
{ if (m_filesize < m_max_filesize)
if (m_filesize < m_max_filesize) return true;
return true;
if (m_file) if (m_file) {
{
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
CloseHandle(m_file); CloseHandle(m_file);
#else #else
fclose(m_file); fclose(m_file);
#endif #endif
m_file = NULL; m_file = nullptr;
} }
// make a name for backup file. // make a name for backup file.
wchar_t _tmpname[64] = { 0 }; wchar_t _tmpname[64] = {0};
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
SYSTEMTIME st; SYSTEMTIME st;
GetLocalTime(&st); GetLocalTime(&st);
swprintf_s(_tmpname, 64, L"%s.%04d%02d%02d%02d%02d%02d.bak", m_filename.c_str(), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); swprintf_s(_tmpname, 64, L"%s.%04d%02d%02d%02d%02d%02d.bak", m_filename.c_str(), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
#else #else
time_t timep; time_t timep;
time(&timep); time(&timep);
struct tm *p = localtime(&timep); struct tm* p = localtime(&timep);
if (p == NULL) if (p == nullptr)
return false; return false;
ex_wcsformat(_tmpname, 64, L"%ls.%04d%02d%02d%02d%02d%02d.bak", m_filename.c_str(), p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); ex_wcsformat(_tmpname, 64, L"%ls.%04d%02d%02d%02d%02d%02d.bak", m_filename.c_str(), p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec);
#endif #endif
ex_wstr _new_fullname(m_path); ex_wstr _new_fullname(m_path);
ex_path_join(_new_fullname, false, _tmpname, NULL); ex_path_join(_new_fullname, false, _tmpname, nullptr);
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
if (!MoveFileW(m_fullname.c_str(), _new_fullname.c_str())) if (!MoveFileW(m_fullname.c_str(), _new_fullname.c_str()))
{ {
EXLOGE_WIN("can not rename log file, remove old one and try again."); EXLOGE_WIN("can not rename log file, remove old one and try again.");
DeleteFileW(_new_fullname.c_str()); DeleteFileW(_new_fullname.c_str());
if (!MoveFileW(m_fullname.c_str(), _new_fullname.c_str())) if (!MoveFileW(m_fullname.c_str(), _new_fullname.c_str()))
return false; return false;
} }
#else #else
ex_astr _a_fullname; ex_astr _a_fullname;
ex_astr _a_new_fullname; ex_astr _a_new_fullname;
ex_wstr2astr(m_fullname, _a_fullname); ex_wstr2astr(m_fullname, _a_fullname);
ex_wstr2astr(_new_fullname, _a_new_fullname); ex_wstr2astr(_new_fullname, _a_new_fullname);
if (rename(_a_fullname.c_str(), _a_new_fullname.c_str()) != 0) if (rename(_a_fullname.c_str(), _a_new_fullname.c_str()) != 0) {
{ remove(_a_new_fullname.c_str());
remove(_a_new_fullname.c_str()); if (0 != (rename(_a_fullname.c_str(), _a_new_fullname.c_str())))
if (0 != (rename(_a_fullname.c_str(), _a_new_fullname.c_str()))) return false;
return false; }
}
#endif #endif
return _open_file(); return _open_file();
} }
bool ExLogger::write_a(const char* buf) bool ExLogger::write_a(const char* buf) {
{ if (nullptr == m_file)
if (NULL == m_file) return false;
return false;
size_t len = strlen(buf); size_t len = strlen(buf);
if (len > EX_LOG_CONTENT_MAX_LEN) if (len > EX_LOG_CONTENT_MAX_LEN)
return false; return false;
char szTime[100] = { 0 };
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
SYSTEMTIME st; WriteFile(m_file, buf, len, &dwWritten, nullptr);
GetLocalTime(&st); m_filesize += len;
sprintf_s(szTime, 100, "[%04d-%02d-%02d %02d:%02d:%02d] ", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); FlushFileBuffers(m_file);
int lenTime = strlen(szTime);
DWORD dwWritten = 0;
WriteFile(m_file, szTime, lenTime, &dwWritten, NULL);
m_filesize += lenTime;
WriteFile(m_file, buf, len, &dwWritten, NULL);
m_filesize += len;
FlushFileBuffers(m_file);
#else #else
time_t timep; fwrite(buf, len, 1, m_file);
struct tm *p; m_filesize += len;
time(&timep);
p = localtime(&timep);
if (p == NULL)
return false;
sprintf(szTime, "[%04d-%02d-%02d %02d:%02d:%02d] ", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec);
size_t lenTime = strlen(szTime);
fwrite(szTime, lenTime, 1, m_file);
m_filesize += lenTime;
fwrite(buf, len, 1, m_file);
m_filesize += len;
fflush(m_file); fflush(m_file);
#endif #endif
return _rotate_file(); return _rotate_file();
} }
bool ExLogger::write_w(const wchar_t* buf) bool ExLogger::write_w(const wchar_t* buf) {
{ ex_astr _buf;
ex_astr _buf; ex_wstr2astr(buf, _buf, EX_CODEPAGE_UTF8);
ex_wstr2astr(buf, _buf, EX_CODEPAGE_UTF8); return write_a(_buf.c_str());
return write_a(_buf.c_str());
} }

View File

@ -214,11 +214,17 @@ int ex_atomic_dec(volatile int *pt) {
#endif #endif
} }
uint64_t ex_get_thread_id()
ex_u64 ex_get_thread_id() { {
#ifdef EX_OS_WIN32 #if defined(EX_OS_WIN32)
return GetCurrentThreadId(); return (uint64_t)GetCurrentThreadId();
#elif defined(EX_OS_LINUX)
return pthread_self();
#elif defined(EX_OS_MACOS)
uint64_t tid = 0;
pthread_threadid_np(nullptr, &tid);
return tid;
#else #else
return (ex_u64) pthread_self(); # error "unsupport platform."
#endif #endif
} }

View File

@ -3,19 +3,20 @@
#include <ex/ex_str.h> #include <ex/ex_str.h>
#include <ex/ex_log.h> #include <ex/ex_log.h>
EX_BOOL ex_initialize(const char *lc_ctype) { EX_BOOL ex_initialize(const char *lc_ctype)
{
#ifdef EX_OS_UNIX #ifdef EX_OS_UNIX
const char *_lc_default = "en_US.UTF-8"; const char *_lc_default = "en_US.UTF-8";
const char *_lc_ctype = NULL; const char *_lc_ctype = nullptr;
char *_loc = NULL; char *_loc = nullptr;
if (NULL == lc_ctype) if (nullptr == lc_ctype)
_lc_ctype = _lc_default; _lc_ctype = _lc_default;
else else
_lc_ctype = lc_ctype; _lc_ctype = lc_ctype;
_loc = setlocale(LC_CTYPE, _lc_ctype); _loc = setlocale(LC_CTYPE, _lc_ctype);
if (NULL == _loc) if (nullptr == _loc)
return EX_FALSE; return EX_FALSE;
// if(0 != strcmp(_loc, _lc_ctype)) // if(0 != strcmp(_loc, _lc_ctype))
// return EX_FALSE; // return EX_FALSE;
@ -27,50 +28,61 @@ EX_BOOL ex_initialize(const char *lc_ctype) {
} }
void ex_free(void *buffer) { void ex_free(void *buffer)
if (NULL == buffer) {
if (nullptr == buffer)
return; return;
free(buffer); free(buffer);
} }
const ex_u8 *ex_memmem(const ex_u8 *haystack, size_t haystacklen, const ex_u8 *needle, size_t needlelen) { const ex_u8 *ex_memmem(const ex_u8 *haystack, size_t haystacklen, const ex_u8 *needle, size_t needlelen)
const ex_u8 *cursor = NULL; {
const ex_u8 *cursor = nullptr;
const ex_u8 *last_possible_needle_location = haystack + haystacklen - needlelen; const ex_u8 *last_possible_needle_location = haystack + haystacklen - needlelen;
/** Easy answers */ /** Easy answers */
if (needlelen > haystacklen) return (NULL); if (needlelen > haystacklen)
if (needle == NULL) return (NULL); return (nullptr);
if (haystack == NULL) return (NULL); if (needle == nullptr)
if (needlelen == 0) return (NULL); return (nullptr);
if (haystacklen == 0) return (NULL); if (haystack == nullptr)
return (nullptr);
if (needlelen == 0)
return (nullptr);
if (haystacklen == 0)
return (nullptr);
for (cursor = haystack; cursor <= last_possible_needle_location; cursor++) { for (cursor = haystack; cursor <= last_possible_needle_location; cursor++)
{
if (memcmp(needle, cursor, needlelen) == 0) if (memcmp(needle, cursor, needlelen) == 0)
return cursor; return cursor;
} }
return (NULL); return (nullptr);
} }
void ex_mem_reverse(ex_u8 *p, size_t l) { void ex_mem_reverse(ex_u8 *p, size_t l)
ex_u8 temp = 0; {
size_t i = 0, j = 0; ex_u8 temp = 0;
size_t i = 0, j = 0;
for (i = 0, j = l - 1; i < j; i++, j--) { for (i = 0, j = l - 1; i < j; i++, j--)
{
temp = p[i]; temp = p[i];
p[i] = p[j]; p[i] = p[j];
p[j] = temp; p[j] = temp;
} }
} }
void ex_printf(const char *fmt, ...) { void ex_printf(const char *fmt, ...)
if (NULL == fmt || 0 == strlen(fmt)) {
if (nullptr == fmt || 0 == strlen(fmt))
return; return;
va_list valist; va_list valist;
va_start(valist, fmt); va_start(valist, fmt);
//_ts_printf_a(TS_COLOR_GRAY, TS_COLOR_BLACK, fmt, valist); //_ts_printf_a(TS_COLOR_GRAY, TS_COLOR_BLACK, fmt, valist);
char _tmp[4096] = {0}; char _tmp[4096] = { 0 };
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
vsnprintf_s(_tmp, 4096, 4095, fmt, valist); vsnprintf_s(_tmp, 4096, 4095, fmt, valist);
printf_s("%s", _tmp); printf_s("%s", _tmp);
@ -84,14 +96,15 @@ void ex_printf(const char *fmt, ...) {
va_end(valist); va_end(valist);
} }
void ex_wprintf(const wchar_t *fmt, ...) { void ex_wprintf(const wchar_t *fmt, ...)
if (NULL == fmt || 0 == wcslen(fmt)) {
if (nullptr == fmt || 0 == wcslen(fmt))
return; return;
va_list valist; va_list valist;
va_start(valist, fmt); va_start(valist, fmt);
wchar_t _tmp[4096] = {0}; wchar_t _tmp[4096] = { 0 };
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
_vsnwprintf_s(_tmp, 4096, 4095, fmt, valist); _vsnwprintf_s(_tmp, 4096, 4095, fmt, valist);
wprintf_s(L"%s", _tmp); wprintf_s(L"%s", _tmp);
@ -109,7 +122,8 @@ void ex_wprintf(const wchar_t *fmt, ...) {
va_end(valist); va_end(valist);
} }
ex_u64 ex_get_tick_count(void) { ex_u64 ex_get_tick_count(void)
{
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
# if (_WIN32_WINNT >= 0x0600) # if (_WIN32_WINNT >= 0x0600)
return GetTickCount64(); return GetTickCount64();
@ -132,7 +146,8 @@ ex_u64 ex_get_tick_count(void) {
#endif #endif
} }
void ex_sleep_ms(int ms) { void ex_sleep_ms(int ms)
{
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
Sleep(ms); Sleep(ms);
#else #else
@ -140,8 +155,9 @@ void ex_sleep_ms(int ms) {
#endif #endif
} }
EX_BOOL ex_localtime_now(int *t, struct tm *dt) { EX_BOOL ex_localtime_now(int *t, struct tm *dt)
// if (NULL == dt) {
// if (nullptr == dt)
// return EX_FALSE; // return EX_FALSE;
//struct tm *_tmp; //struct tm *_tmp;
@ -152,34 +168,35 @@ EX_BOOL ex_localtime_now(int *t, struct tm *dt) {
_time32(&timep); _time32(&timep);
if (0 != _localtime32_s(&_tmp, &timep)) if (0 != _localtime32_s(&_tmp, &timep))
return EX_FALSE; return EX_FALSE;
if(NULL != dt) if(nullptr != dt)
memcpy(dt, &_tmp, sizeof(struct tm)); memcpy(dt, &_tmp, sizeof(struct tm));
#else #else
struct tm *_tmp; struct tm *_tmp;
time_t timep; time_t timep;
time(&timep); time(&timep);
_tmp = localtime(&timep); //get server's time _tmp = localtime(&timep); //get server's time
if (_tmp == NULL) if (_tmp == nullptr)
return EX_FALSE; return EX_FALSE;
if (NULL != dt) if (nullptr != dt)
memcpy(dt, _tmp, sizeof(struct tm)); memcpy(dt, _tmp, sizeof(struct tm));
#endif #endif
if (NULL != t) if (nullptr != t)
*t = (int) timep; *t = (int) timep;
return EX_TRUE; return EX_TRUE;
} }
FILE *ex_fopen(const ex_wstr &filename, const wchar_t *mode) { FILE *ex_fopen(const ex_wstr &filename, const wchar_t *mode)
FILE *f = NULL; {
FILE *f = nullptr;
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
errno_t err = 0; errno_t err = 0;
err = _wfopen_s(&f, filename.c_str(), mode); err = _wfopen_s(&f, filename.c_str(), mode);
if (0 == err) if (0 == err)
return f; return f;
else else
return NULL; return nullptr;
#else #else
ex_astr _fname; ex_astr _fname;
ex_wstr2astr(filename, _fname); ex_wstr2astr(filename, _fname);
@ -190,32 +207,35 @@ FILE *ex_fopen(const ex_wstr &filename, const wchar_t *mode) {
#endif #endif
} }
FILE* ex_fopen(const ex_astr& filename, const char* mode) { FILE *ex_fopen(const ex_astr &filename, const char *mode)
FILE *f = NULL; {
FILE *f = nullptr;
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
errno_t err = 0; errno_t err = 0;
err = fopen_s(&f, filename.c_str(), mode); err = fopen_s(&f, filename.c_str(), mode);
if (0 == err) if (0 == err)
return f; return f;
else else
return NULL; return nullptr;
#else #else
f = fopen(filename.c_str(), mode); f = fopen(filename.c_str(), mode);
return f; return f;
#endif #endif
} }
bool ex_read_text_file(const ex_wstr &strFileName, ex_astr& file_content) { bool ex_read_text_file(const ex_wstr &strFileName, ex_astr &file_content)
{
std::vector<char> tmp; std::vector<char> tmp;
FILE *f = ex_fopen(strFileName, L"rb"); FILE *f = ex_fopen(strFileName, L"rb");
if (f == NULL) if (f == nullptr)
return false; return false;
fseek(f, 0L, SEEK_END); fseek(f, 0L, SEEK_END);
unsigned long ulFileSize = (unsigned long) ftell(f); unsigned long ulFileSize = (unsigned long) ftell(f);
if (-1 == ulFileSize) { if (-1 == ulFileSize)
{
fclose(f); fclose(f);
return false; return false;
} }
@ -230,22 +250,27 @@ bool ex_read_text_file(const ex_wstr &strFileName, ex_astr& file_content) {
fclose(f); fclose(f);
if(ulRead != ulFileSize) { if (ulRead != ulFileSize)
{
return false; return false;
} }
if ((ulFileSize > 3) && (0 == memcmp(&tmp[0], "\xEF\xBB\xBF", 3))) { if ((ulFileSize > 3) && (0 == memcmp(&tmp[0], "\xEF\xBB\xBF", 3)))
{
file_content = &tmp[3]; file_content = &tmp[3];
} else { }
else
{
file_content = &tmp[0]; file_content = &tmp[0];
} }
return true; return true;
} }
bool ex_write_text_file(const ex_wstr &strFileName, const ex_astr& file_content) { bool ex_write_text_file(const ex_wstr &strFileName, const ex_astr &file_content)
{
FILE *f = ex_fopen(strFileName, L"wb"); FILE *f = ex_fopen(strFileName, L"wb");
if (f == NULL) if (f == nullptr)
return false; return false;
unsigned long ulWrite = fwrite(file_content.c_str(), 1, file_content.length(), f); unsigned long ulWrite = fwrite(file_content.c_str(), 1, file_content.length(), f);
@ -254,35 +279,39 @@ bool ex_write_text_file(const ex_wstr &strFileName, const ex_astr& file_content)
return ulWrite == file_content.length(); return ulWrite == file_content.length();
} }
EX_DYLIB_HANDLE ex_dlopen(const wchar_t *dylib_path) { EX_DYLIB_HANDLE ex_dlopen(const wchar_t *dylib_path)
EX_DYLIB_HANDLE handle = NULL; {
EX_DYLIB_HANDLE handle = nullptr;
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
handle = LoadLibraryExW(dylib_path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); handle = LoadLibraryExW(dylib_path, nullptr, LOAD_WITH_ALTERED_SEARCH_PATH);
if (NULL == handle) if (nullptr == handle)
{ {
EXLOGE_WIN(L"LoadLibraryEx('%ls') failed.\n", dylib_path); EXLOGE_WIN(L"LoadLibraryEx('%ls') failed.\n", dylib_path);
return NULL; return nullptr;
} }
#else #else
ex_astr path; ex_astr path;
if (!ex_wstr2astr(dylib_path, path, EX_CODEPAGE_UTF8)) { if (!ex_wstr2astr(dylib_path, path, EX_CODEPAGE_UTF8))
{
EXLOGE("convert dylib_path failed.\n"); EXLOGE("convert dylib_path failed.\n");
return NULL; return nullptr;
} }
handle = dlopen(path.c_str(), RTLD_NOW | RTLD_GLOBAL); handle = dlopen(path.c_str(), RTLD_NOW | RTLD_GLOBAL);
if (NULL == handle) { if (nullptr == handle)
{
EXLOGE("dlopen() failed: %s.\n", dlerror()); EXLOGE("dlopen() failed: %s.\n", dlerror());
return NULL; return nullptr;
} }
#endif #endif
return handle; return handle;
} }
void ex_dlclose(EX_DYLIB_HANDLE dylib) { void ex_dlclose(EX_DYLIB_HANDLE dylib)
{
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
FreeLibrary(dylib); FreeLibrary(dylib);
#else #else
@ -308,173 +337,188 @@ void ex_dlclose(EX_DYLIB_HANDLE dylib) {
// return _inet_ntop4((const unsigned char *) &(src->sin_addr), dst, size); // return _inet_ntop4((const unsigned char *) &(src->sin_addr), dst, size);
// } // }
// //
static const char * _inet_ntop_v4(const void *src, char *dst, size_t size) static const char *_inet_ntop_v4(const void *src, char *dst, size_t size)
{ {
const char digits[] = "0123456789"; const char digits[] = "0123456789";
int i; int i;
struct in_addr *addr = (struct in_addr *)src; struct in_addr *addr = (struct in_addr *) src;
u_long a = ntohl(addr->s_addr); u_long a = ntohl(addr->s_addr);
const char *orig_dst = dst; const char *orig_dst = dst;
if (size < EX_IPV4_NAME_LEN) { if (size < EX_IPV4_NAME_LEN)
//errno = ENOSPC; {
return NULL; //errno = ENOSPC;
} return nullptr;
for (i = 0; i < 4; ++i) { }
int n = (a >> (24 - i * 8)) & 0xFF; for (i = 0; i < 4; ++i)
int non_zerop = 0; {
int n = (a >> (24 - i * 8)) & 0xFF;
int non_zerop = 0;
if (non_zerop || n / 100 > 0) { if (non_zerop || n / 100 > 0)
*dst++ = digits[n / 100]; {
n %= 100; *dst++ = digits[n / 100];
non_zerop = 1; n %= 100;
} non_zerop = 1;
if (non_zerop || n / 10 > 0) { }
*dst++ = digits[n / 10]; if (non_zerop || n / 10 > 0)
n %= 10; {
non_zerop = 1; *dst++ = digits[n / 10];
} n %= 10;
*dst++ = digits[n]; non_zerop = 1;
if (i != 3) }
*dst++ = '.'; *dst++ = digits[n];
} if (i != 3)
*dst++ = '\0'; *dst++ = '.';
return orig_dst; }
*dst++ = '\0';
return orig_dst;
} }
#define IN6ADDRSZ 16 #define IN6ADDRSZ 16
#define INT16SZ 2 #define INT16SZ 2
static const char * _inet_ntop_v6(const ex_u8 *src, char *dst, size_t size)
static const char *_inet_ntop_v6(const ex_u8 *src, char *dst, size_t size)
{ {
/* /*
* Note that int32_t and int16_t need only be "at least" large enough * Note that int32_t and int16_t need only be "at least" large enough
* to contain a value of the specified size. On some systems, like * to contain a value of the specified size. On some systems, like
* Crays, there is no such thing as an integer variable with 16 bits. * Crays, there is no such thing as an integer variable with 16 bits.
* Keep this in mind if you think this function should have been coded * Keep this in mind if you think this function should have been coded
* to use pointer overlays. All the world's not a VAX. * to use pointer overlays. All the world's not a VAX.
*/ */
char tmp[EX_IPV6_NAME_LEN]; char tmp[EX_IPV6_NAME_LEN];
char *tp; char *tp;
struct { struct
long base; {
long len; long base;
} best, cur; long len;
u_long words[IN6ADDRSZ / INT16SZ]; } best, cur;
int i; u_long words[IN6ADDRSZ / INT16SZ];
int i;
/* Preprocess: /* Preprocess:
* Copy the input (bytewise) array into a wordwise array. * Copy the input (bytewise) array into a wordwise array.
* Find the longest run of 0x00's in src[] for :: shorthanding. * Find the longest run of 0x00's in src[] for :: shorthanding.
*/ */
memset(words, 0, sizeof(words)); memset(words, 0, sizeof(words));
for (i = 0; i < IN6ADDRSZ; i++) for (i = 0; i < IN6ADDRSZ; i++)
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); {
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
}
best.base = -1; best.base = -1;
cur.base = -1; cur.base = -1;
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
{ {
if (words[i] == 0) if (words[i] == 0)
{ {
if (cur.base == -1) { if (cur.base == -1)
{
cur.base = i; cur.base = i;
cur.len = 1; cur.len = 1;
} }
else{ else
{
cur.len++; cur.len++;
} }
} }
else if (cur.base != -1) else if (cur.base != -1)
{ {
if (best.base == -1 || cur.len > best.len) if (best.base == -1 || cur.len > best.len)
best = cur; best = cur;
cur.base = -1; cur.base = -1;
} }
} }
if ((cur.base != -1) && (best.base == -1 || cur.len > best.len)) if ((cur.base != -1) && (best.base == -1 || cur.len > best.len))
best = cur; best = cur;
if (best.base != -1 && best.len < 2) if (best.base != -1 && best.len < 2)
best.base = -1; best.base = -1;
/* Format the result. /* Format the result.
*/ */
tp = tmp; tp = tmp;
size_t tmp_size = 0; size_t tmp_size = 0;
size_t offset = 0; size_t offset = 0;
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
{ {
/* Are we inside the best run of 0x00's? /* Are we inside the best run of 0x00's?
*/ */
if (best.base != -1 && i >= best.base && i < (best.base + best.len)) if (best.base != -1 && i >= best.base && i < (best.base + best.len))
{ {
if (i == best.base) { if (i == best.base)
*tp++ = ':'; {
offset += 1; *tp++ = ':';
} offset += 1;
continue; }
} continue;
}
/* Are we following an initial run of 0x00s or any real hex? /* Are we following an initial run of 0x00s or any real hex?
*/ */
if (i != 0) { if (i != 0)
*tp++ = ':'; {
offset += 1; *tp++ = ':';
} offset += 1;
}
/* Is this address an encapsulated IPv4? /* Is this address an encapsulated IPv4?
*/ */
if (i == 6 && best.base == 0 && if (i == 6 && best.base == 0 &&
(best.len == 6 || (best.len == 5 && words[5] == 0xffff))) (best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
{ {
if (!_inet_ntop_v4(src + 12, tp, sizeof(tmp) - (tp - tmp))) if (!_inet_ntop_v4(src + 12, tp, sizeof(tmp) - (tp - tmp)))
{ {
//errno = ENOSPC; //errno = ENOSPC;
return (NULL); return (nullptr);
} }
tmp_size = strlen(tp); tmp_size = strlen(tp);
tp += tmp_size; tp += tmp_size;
offset += tmp_size; offset += tmp_size;
break; break;
} }
//tp += ex_strformat(tp, "%lX", words[i]); //tp += ex_strformat(tp, "%lX", words[i]);
tmp_size = ex_strformat(tp, EX_IPV6_NAME_LEN-offset, "%lX", words[i]); tmp_size = ex_strformat(tp, EX_IPV6_NAME_LEN - offset, "%lX", words[i]);
tp += tmp_size; tp += tmp_size;
offset += tmp_size; offset += tmp_size;
} }
/* Was it a trailing run of 0x00's? /* Was it a trailing run of 0x00's?
*/ */
if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
*tp++ = ':'; *tp++ = ':';
*tp++ = '\0'; *tp++ = '\0';
/* Check for overflow, copy, and we're done. /* Check for overflow, copy, and we're done.
*/ */
if ((size_t)(tp - tmp) > size) if ((size_t) (tp - tmp) > size)
{ {
//errno = ENOSPC; //errno = ENOSPC;
return (NULL); return (nullptr);
} }
//return strcpy(dst, tmp); //return strcpy(dst, tmp);
return ex_strcpy(dst, size, tmp); return ex_strcpy(dst, size, tmp);
//return (NULL); //return (nullptr);
} }
const char* ex_inet_ntop(int af, const void *src, char *dst, size_t size) { const char *ex_inet_ntop(int af, const void *src, char *dst, size_t size)
switch (af) { {
case AF_INET: switch (af)
return _inet_ntop_v4(src, dst, size); {
case AF_INET6: case AF_INET:
return _inet_ntop_v6((const ex_u8*)src, dst, size); return _inet_ntop_v4(src, dst, size);
default: case AF_INET6:
errno = EAFNOSUPPORT; return _inet_ntop_v6((const ex_u8 *) src, dst, size);
return NULL; default:
} errno = EAFNOSUPPORT;
return nullptr;
}
} }
int ex_ip4_name(const struct sockaddr_in *src, char *dst, size_t size) { int ex_ip4_name(const struct sockaddr_in *src, char *dst, size_t size)
if (NULL == _inet_ntop_v4((const unsigned char *)&(src->sin_addr), dst, size)) {
return -1; if (nullptr == _inet_ntop_v4((const unsigned char *) &(src->sin_addr), dst, size))
return 0; return -1;
return 0;
} }

View File

@ -11,142 +11,143 @@
//======================================================= //=======================================================
// Urlprotocol相关 // Urlprotocol相关
//======================================================= //=======================================================
#define TP_URLPROTO_APP_NAME "teleport" #define TP_URLPROTO_APP_NAME "teleport"
//======================================================= //=======================================================
// 远程连接认证方式 // 远程连接认证方式
//======================================================= //=======================================================
#define TP_AUTH_TYPE_NONE 0 #define TP_AUTH_TYPE_NONE 0
#define TP_AUTH_TYPE_PASSWORD 1 #define TP_AUTH_TYPE_PASSWORD 1
#define TP_AUTH_TYPE_PRIVATE_KEY 2 #define TP_AUTH_TYPE_PRIVATE_KEY 2
//======================================================= //=======================================================
// 远程连接协议 // 远程连接协议
//======================================================= //=======================================================
#define TP_PROTOCOL_TYPE_RDP 1 #define TP_PROTOCOL_TYPE_RDP 1
#define TP_PROTOCOL_TYPE_SSH 2 #define TP_PROTOCOL_TYPE_SSH 2
#define TP_PROTOCOL_TYPE_TELNET 3 #define TP_PROTOCOL_TYPE_TELNET 3
//======================================================= //=======================================================
// 远程连接子协议 // 远程连接子协议
//======================================================= //=======================================================
#define TP_PROTOCOL_TYPE_RDP_DESKTOP 100 #define TP_PROTOCOL_TYPE_RDP_DESKTOP 100
#define TP_PROTOCOL_TYPE_SSH_SHELL 200 #define TP_PROTOCOL_TYPE_SSH_SHELL 200
#define TP_PROTOCOL_TYPE_SSH_SFTP 201 #define TP_PROTOCOL_TYPE_SSH_SFTP 201
#define TP_PROTOCOL_TYPE_TELNET_SHELL 300 #define TP_PROTOCOL_TYPE_TELNET_SHELL 300
//======================================================= //=======================================================
// 远程主机操作系统 // 远程主机操作系统
//======================================================= //=======================================================
#define TP_OS_TYPE_WINDOWS 1 #define TP_OS_TYPE_WINDOWS 1
#define TP_OS_TYPE_LINUX 2 #define TP_OS_TYPE_LINUX 2
//======================================================= //=======================================================
// 远程连接会话状态 // 远程连接会话状态
//======================================================= //=======================================================
#define TP_SESS_STAT_RUNNING 0 // 会话开始了,正在连接 #define TP_SESS_STAT_RUNNING 0 // 会话开始了,正在连接
#define TP_SESS_STAT_END 9999 // 会话成功结束 #define TP_SESS_STAT_ERR_AUTH_DENIED 1 // 会话结束,因为认证失败
#define TP_SESS_STAT_ERR_AUTH_DENIED 1 // 会话结束,因为认证失败 #define TP_SESS_STAT_ERR_CONNECT 2 // 会话结束,因为无法连接到远程主机
#define TP_SESS_STAT_ERR_CONNECT 2 // 会话结束,因为无法连接到远程主机 #define TP_SESS_STAT_ERR_BAD_SSH_KEY 3 // 会话结束因为无法识别SSH私钥
#define TP_SESS_STAT_ERR_BAD_SSH_KEY 3 // 会话结束因为无法识别SSH私钥 #define TP_SESS_STAT_ERR_INTERNAL 4 // 会话结束,因为内部错误
#define TP_SESS_STAT_ERR_INTERNAL 4 // 会话结束,因为内部错误 #define TP_SESS_STAT_ERR_UNSUPPORT_PROTOCOL 5 // 会话结束,因为协议不支持(RDP)
#define TP_SESS_STAT_ERR_UNSUPPORT_PROTOCOL 5 // 会话结束,因为协议不支持(RDP) #define TP_SESS_STAT_ERR_BAD_PKG 6 // 会话结束,因为收到错误的报文
#define TP_SESS_STAT_ERR_BAD_PKG 6 // 会话结束,因为收到错误的报文 #define TP_SESS_STAT_ERR_RESET 7 // 会话结束因为teleport核心服务重置了
#define TP_SESS_STAT_ERR_RESET 7 // 会话结束因为teleport核心服务重置了 #define TP_SESS_STAT_ERR_IO 8 // 会话结束,因为网络中断
#define TP_SESS_STAT_ERR_IO 8 // 会话结束,因为网络中断 #define TP_SESS_STAT_ERR_SESSION 9 // 会话结束因为无效的会话ID
#define TP_SESS_STAT_ERR_SESSION 9 // 会话结束因为无效的会话ID #define TP_SESS_STAT_ERR_AUTH_TYPE 10 // 会话结束,因为不被允许的认证方式
#define TP_SESS_STAT_ERR_AUTH_TYPE 10 // 会话结束,因为不被允许的认证方式 #define TP_SESS_STAT_ERR_CREATE_CHANNEL 11 // 会话结束,因为创建通道失败
#define TP_SESS_STAT_STARTED 100 // 已经连接成功了,开始记录录像了 #define TP_SESS_STAT_STARTED 100 // 已经连接成功了,开始记录录像了
#define TP_SESS_STAT_ERR_START_INTERNAL 104 // 会话结束,因为内部错误 #define TP_SESS_STAT_ERR_START_INTERNAL 104 // 会话结束,因为内部错误
#define TP_SESS_STAT_ERR_START_BAD_PKG 106 // 会话结束,因为收到错误的报文 #define TP_SESS_STAT_ERR_START_BAD_PKG 106 // 会话结束,因为收到错误的报文
#define TP_SESS_STAT_ERR_START_RESET 107 // 会话结束因为teleport核心服务重置了 #define TP_SESS_STAT_ERR_START_RESET 107 // 会话结束因为teleport核心服务重置了
#define TP_SESS_STAT_ERR_START_IO 108 // 会话结束,因为网络中断 #define TP_SESS_STAT_ERR_START_IO 108 // 会话结束,因为网络中断
#define TP_SESS_STAT_END 9999 // 会话成功结束
//======================================================= //=======================================================
// 授权标记 // 授权标记
//======================================================= //=======================================================
#define TP_FLAG_ALL 0xFFFFFFFF #define TP_FLAG_ALL 0xFFFFFFFF
// 会话记录相关 // 会话记录相关
#define TP_FLAG_RECORD_REPLAY 0x00000001 // 允许记录历史(录像回放) #define TP_FLAG_RECORD_REPLAY 0x00000001 // 允许记录历史(录像回放)
#define TP_FLAG_RECORD_REAL_TIME 0x00000002 // 允许实时监控 #define TP_FLAG_RECORD_REAL_TIME 0x00000002 // 允许实时监控
// RDP相关 // RDP相关
#define TP_FLAG_RDP_DESKTOP 0x00000001 // 允许远程桌面 #define TP_FLAG_RDP_DESKTOP 0x00000001 // 允许远程桌面
#define TP_FLAG_RDP_CLIPBOARD 0x00000002 // 允许剪贴板 #define TP_FLAG_RDP_CLIPBOARD 0x00000002 // 允许剪贴板
#define TP_FLAG_RDP_DISK 0x00000004 // 允许磁盘映射 #define TP_FLAG_RDP_DISK 0x00000004 // 允许磁盘映射
#define TP_FLAG_RDP_APP 0x00000008 // 允许远程APP尚未实现 #define TP_FLAG_RDP_APP 0x00000008 // 允许远程APP尚未实现
#define TP_FLAG_RDP_CONSOLE 0x00001000 //允许连接到管理员会话RDP的console选项 #define TP_FLAG_RDP_CONSOLE 0x00001000 // 允许连接到管理员会话RDP的console选项
// SSH相关 // SSH相关
#define TP_FLAG_SSH_SHELL 0x00000001 // 允许SHELL #define TP_FLAG_SSH_SHELL 0x00000001 // 允许SHELL
#define TP_FLAG_SSH_SFTP 0x00000002 // 允许SFTP #define TP_FLAG_SSH_SFTP 0x00000002 // 允许SFTP
#define TP_FLAG_SSH_X11 0x00000004 // 允许X11转发尚未实现 #define TP_FLAG_SSH_X11 0x00000004 // 允许X11转发尚未实现
#define TP_FLAG_SSH_EXEC 0x00000008 // 允许exec执行远程命令尚未实现 #define TP_FLAG_SSH_EXEC 0x00000008 // 允许exec执行远程命令尚未实现
#define TP_FLAG_SSH_TUNNEL 0x00000010 // allow ssh tunnel. (not impl.) #define TP_FLAG_SSH_TUNNEL 0x00000010 // allow ssh tunnel. (not impl.)
//======================================================= //=======================================================
// 错误值 // 错误值
//======================================================= //=======================================================
#define TPE_OK 0 // 成功 #define TPE_OK 0 // 成功
//------------------------------------------------------- //-------------------------------------------------------
// 通用错误值 // 通用错误值
//------------------------------------------------------- //-------------------------------------------------------
#define TPE_NEED_MORE_DATA 1 // 需要更多数据(不一定是错误) #define TPE_NEED_MORE_DATA 1 // 需要更多数据(不一定是错误)
#define TPE_NEED_LOGIN 2 // 需要登录 #define TPE_NEED_LOGIN 2 // 需要登录
#define TPE_PRIVILEGE 3 // 没有操作权限 #define TPE_PRIVILEGE 3 // 没有操作权限
#define TPE_NOT_IMPLEMENT 7 // 功能尚未实现 #define TPE_NOT_IMPLEMENT 7 // 功能尚未实现
#define TPE_EXISTS 8 // 目标已经存在 #define TPE_EXISTS 8 // 目标已经存在
#define TPE_NOT_EXISTS 9 // 目标不存在 #define TPE_NOT_EXISTS 9 // 目标不存在
// 100~299是通用错误值 // 100~299是通用错误值
#define TPE_FAILED 100 // 内部错误 #define TPE_FAILED 100 // 内部错误
#define TPE_NETWORK 101 // 网络错误 #define TPE_NETWORK 101 // 网络错误
#define TPE_DATABASE 102 // 数据库操作失败 #define TPE_DATABASE 102 // 数据库操作失败
// HTTP请求相关错误 // HTTP请求相关错误
#define TPE_HTTP_METHOD 120 // 无效的请求方法不是GET/POST等或者错误的请求方法例如需要POST却使用GET方式请求 #define TPE_HTTP_METHOD 120 // 无效的请求方法不是GET/POST等或者错误的请求方法例如需要POST却使用GET方式请求
#define TPE_HTTP_URL_ENCODE 121 // URL编码错误无法解码 #define TPE_HTTP_URL_ENCODE 121 // URL编码错误无法解码
//#define TPE_HTTP_URI 122 // 无效的URI //#define TPE_HTTP_URI 122 // 无效的URI
#define TPE_UNKNOWN_CMD 124 // 未知的命令 #define TPE_UNKNOWN_CMD 124 // 未知的命令
#define TPE_JSON_FORMAT 125 // 错误的JSON格式需要JSON格式数据但是却无法按JSON格式解码 #define TPE_JSON_FORMAT 125 // 错误的JSON格式需要JSON格式数据但是却无法按JSON格式解码
#define TPE_PARAM 126 // 参数错误 #define TPE_PARAM 126 // 参数错误
#define TPE_INVALID_DATA 127 // 数据错误 #define TPE_INVALID_DATA 127 // 数据错误
#define TPE_UNEXPECTED_DATA 128 // 不是期望的数据 #define TPE_UNEXPECTED_DATA 128 // 不是期望的数据
// #define TPE_OPENFILE_ERROR 0x1007 // 无法打开文件 // #define TPE_OPENFILE_ERROR 0x1007 // 无法打开文件
// #define TPE_GETTEMPPATH_ERROR 0x1007 // #define TPE_GETTEMPPATH_ERROR 0x1007
#define TPE_OPENFILE 300 #define TPE_OPENFILE 300
//------------------------------------------------------- //-------------------------------------------------------
// WEB服务专用错误值 // WEB服务专用错误值
//------------------------------------------------------- //-------------------------------------------------------
#define TPE_CAPTCHA_EXPIRED 10000 // 验证码已过期 #define TPE_CAPTCHA_EXPIRED 10000 // 验证码已过期
#define TPE_CAPTCHA_MISMATCH 10001 // 验证码错误 #define TPE_CAPTCHA_MISMATCH 10001 // 验证码错误
#define TPE_OATH_MISMATCH 10002 // 身份验证器动态验证码错误 #define TPE_OATH_MISMATCH 10002 // 身份验证器动态验证码错误
#define TPE_SYS_MAINTENANCE 10003 // 系统维护中 #define TPE_SYS_MAINTENANCE 10003 // 系统维护中
#define TPE_USER_LOCKED 10100 // 用户已经被锁定(连续多次错误密码) #define TPE_USER_LOCKED 10100 // 用户已经被锁定(连续多次错误密码)
#define TPE_USER_DISABLED 10101 // 用户已经被禁用 #define TPE_USER_DISABLED 10101 // 用户已经被禁用
#define TPE_USER_AUTH 10102 // 身份验证失败 #define TPE_USER_AUTH 10102 // 身份验证失败
//------------------------------------------------------- //-------------------------------------------------------
// 助手程序专用错误值 // 助手程序专用错误值
//------------------------------------------------------- //-------------------------------------------------------
#define TPE_NO_ASSIST 100000 // 未能检测到助手程序 #define TPE_NO_ASSIST 100000 // 未能检测到助手程序
#define TPE_OLD_ASSIST 100001 // 助手程序版本太低 #define TPE_OLD_ASSIST 100001 // 助手程序版本太低
#define TPE_START_CLIENT 100002 // 无法启动客户端程序(无法创建进程) #define TPE_START_CLIENT 100002 // 无法启动客户端程序(无法创建进程)
//------------------------------------------------------- //-------------------------------------------------------
// 核心服务专用错误值 // 核心服务专用错误值
//------------------------------------------------------- //-------------------------------------------------------
#define TPE_NO_CORE_SERVER 200000 // 未能检测到核心服务 #define TPE_NO_CORE_SERVER 200000 // 未能检测到核心服务
#endif // __TELEPORT_CONST_H__ #endif // __TELEPORT_CONST_H__

View File

@ -1,48 +1,46 @@
#include "base_env.h" #include "base_env.h"
TppEnvBase::TppEnvBase() TppEnvBase::TppEnvBase() :
{} get_connect_info(nullptr),
free_connect_info(nullptr),
session_begin(nullptr),
session_update(nullptr),
session_end(nullptr) {}
TppEnvBase::~TppEnvBase() TppEnvBase::~TppEnvBase() = default;
{}
bool TppEnvBase::init(TPP_INIT_ARGS* args) bool TppEnvBase::init(TPP_INIT_ARGS* args) {
{ if (nullptr == args) {
if (NULL == args) EXLOGE("invalid init args(1).\n");
{ return false;
EXLOGE("invalid init args(1).\n"); }
return false;
}
EXLOG_USE_LOGGER(args->logger); EXLOG_USE_LOGGER(args->logger);
exec_path = args->exec_path; exec_path = args->exec_path;
etc_path = args->etc_path; etc_path = args->etc_path;
replay_path = args->replay_path; replay_path = args->replay_path;
get_connect_info = args->func_get_connect_info; get_connect_info = args->func_get_connect_info;
free_connect_info = args->func_free_connect_info; free_connect_info = args->func_free_connect_info;
session_begin = args->func_session_begin; session_begin = args->func_session_begin;
session_update = args->func_session_update; session_update = args->func_session_update;
session_end = args->func_session_end; session_end = args->func_session_end;
if (NULL == get_connect_info || NULL == free_connect_info || NULL == session_begin || NULL == session_update || NULL == session_end) if (!get_connect_info || !free_connect_info || !session_begin || !session_update || !session_end) {
{ EXLOGE("invalid init args(2).\n");
EXLOGE("invalid init args(2).\n"); return false;
return false; }
}
if (NULL == args->cfg) if (nullptr == args->cfg) {
{ EXLOGE("invalid init args(3).\n");
EXLOGE("invalid init args(3).\n"); return false;
return false; }
}
if (!_on_init(args)) if (!_on_init(args)) {
{ EXLOGE("invalid init args(4).\n");
EXLOGE("invalid init args(4).\n"); return false;
return false; }
}
return true; return true;
} }

View File

@ -3,27 +3,27 @@
#include "protocol_interface.h" #include "protocol_interface.h"
class TppEnvBase class TppEnvBase {
{
public: public:
TppEnvBase(); TppEnvBase();
virtual ~TppEnvBase();
bool init(TPP_INIT_ARGS* args); virtual ~TppEnvBase();
bool init(TPP_INIT_ARGS* args);
public: public:
ex_wstr exec_path; ex_wstr exec_path;
ex_wstr etc_path; // 配置文件、SSH服务器的私钥文件的存放路径 ex_wstr etc_path; // 配置文件、SSH服务器的私钥文件的存放路径
ex_wstr replay_path; ex_wstr replay_path;
TPP_GET_CONNNECT_INFO_FUNC get_connect_info; TPP_GET_CONNECT_INFO_FUNC get_connect_info;
TPP_FREE_CONNECT_INFO_FUNC free_connect_info; TPP_FREE_CONNECT_INFO_FUNC free_connect_info;
TPP_SESSION_BEGIN_FUNC session_begin; TPP_SESSION_BEGIN_FUNC session_begin;
TPP_SESSION_UPDATE_FUNC session_update; TPP_SESSION_UPDATE_FUNC session_update;
TPP_SESSION_END_FUNC session_end; TPP_SESSION_END_FUNC session_end;
protected: protected:
virtual bool _on_init(TPP_INIT_ARGS* args) = 0; virtual bool _on_init(TPP_INIT_ARGS* args) = 0;
}; };
#endif // __TS_BASE_ENV_H__ #endif // __TS_BASE_ENV_H__

View File

@ -14,87 +14,87 @@
# define TPP_API # define TPP_API
#endif #endif
#define TPP_CMD_INIT 0x00000000 #define TPP_CMD_INIT 0x00000000
#define TPP_CMD_SET_RUNTIME_CFG 0x00000005 #define TPP_CMD_SET_RUNTIME_CFG 0x00000005
#define TPP_CMD_KILL_SESSIONS 0x00000006 #define TPP_CMD_KILL_SESSIONS 0x00000006
typedef struct TPP_CONNECT_INFO typedef struct TPP_CONNECT_INFO {
{ char* sid;
char* sid;
// 与此连接信息相关的三个要素的ID // 与此连接信息相关的三个要素的ID
int user_id; int user_id;
int host_id; int host_id;
int acc_id; int acc_id;
char* user_username; // 申请本次连接的用户名 char* user_username; // 申请本次连接的用户名
char* host_ip; // 真正的远程主机IP如果是直接连接模式则与remote_host_ip相同 char* host_ip; // 真正的远程主机IP如果是直接连接模式则与remote_host_ip相同
char* conn_ip; // 要连接的远程主机的IP如果是端口映射模式则为路由主机的IP char* conn_ip; // 要连接的远程主机的IP如果是端口映射模式则为路由主机的IP
int conn_port; // 要连接的远程主机的端口(如果是端口映射模式,则为路由主机的端口) int conn_port; // 要连接的远程主机的端口(如果是端口映射模式,则为路由主机的端口)
char* client_ip; char* client_ip;
char* acc_username; // 远程主机的账号 char* acc_username; // 远程主机的账号
char* acc_secret; // 远程主机账号的密码(或者私钥) char* acc_secret; // 远程主机账号的密码(或者私钥)
char* username_prompt; // for telnet char* username_prompt; // for telnet
char* password_prompt; // for telnet char* password_prompt; // for telnet
int protocol_type; int protocol_type;
int protocol_sub_type; int protocol_sub_type;
int protocol_flag; int protocol_flag;
int record_flag; int record_flag;
int auth_type; int auth_type;
}TPP_CONNECT_INFO; } TPP_CONNECT_INFO;
typedef TPP_CONNECT_INFO* (*TPP_GET_CONNNECT_INFO_FUNC)(const char* sid); typedef TPP_CONNECT_INFO* (* TPP_GET_CONNECT_INFO_FUNC)(const char* sid);
typedef void(*TPP_FREE_CONNECT_INFO_FUNC)(TPP_CONNECT_INFO* info);
typedef bool(*TPP_SESSION_BEGIN_FUNC)(const TPP_CONNECT_INFO* info, int* db_id); typedef void(* TPP_FREE_CONNECT_INFO_FUNC)(TPP_CONNECT_INFO* info);
typedef bool(*TPP_SESSION_UPDATE_FUNC)(int db_id, int protocol_sub_type, int state);
typedef bool(*TPP_SESSION_END_FUNC)(const char* sid, int db_id, int ret); typedef bool(* TPP_SESSION_BEGIN_FUNC)(const TPP_CONNECT_INFO* info, int* db_id);
typedef bool(* TPP_SESSION_UPDATE_FUNC)(int db_id, int protocol_sub_type, int state);
typedef bool(* TPP_SESSION_END_FUNC)(const char* sid, int db_id, int ret);
typedef struct TPP_INIT_ARGS typedef struct TPP_INIT_ARGS {
{ ExLogger* logger;
ExLogger* logger; ex_wstr exec_path;
ex_wstr exec_path; ex_wstr etc_path;
ex_wstr etc_path; ex_wstr replay_path;
ex_wstr replay_path; ExIniFile* cfg;
ExIniFile* cfg;
TPP_GET_CONNNECT_INFO_FUNC func_get_connect_info; TPP_GET_CONNECT_INFO_FUNC func_get_connect_info;
TPP_FREE_CONNECT_INFO_FUNC func_free_connect_info; TPP_FREE_CONNECT_INFO_FUNC func_free_connect_info;
TPP_SESSION_BEGIN_FUNC func_session_begin; TPP_SESSION_BEGIN_FUNC func_session_begin;
TPP_SESSION_UPDATE_FUNC func_session_update; TPP_SESSION_UPDATE_FUNC func_session_update;
TPP_SESSION_END_FUNC func_session_end; TPP_SESSION_END_FUNC func_session_end;
}TPP_INIT_ARGS; } TPP_INIT_ARGS;
// typedef struct TPP_SET_CFG_ARGS {
// ex_u32 noop_timeout; // as second.
// }TPP_SET_CFG_ARGS;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"
{ {
#endif #endif
TPP_API ex_rv tpp_init(TPP_INIT_ARGS* init_args); TPP_API ex_rv tpp_init(TPP_INIT_ARGS* init_args);
TPP_API ex_rv tpp_start(void); TPP_API ex_rv tpp_start(void);
TPP_API ex_rv tpp_stop(void); TPP_API ex_rv tpp_stop(void);
TPP_API void tpp_timer(void); TPP_API void tpp_timer(void);
// TPP_API void tpp_set_cfg(TPP_SET_CFG_ARGS* cfg_args);
TPP_API ex_rv tpp_command(ex_u32 cmd, const char* param); TPP_API ex_rv tpp_command(ex_u32 cmd, const char* param);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
typedef ex_rv (*TPP_INIT_FUNC)(TPP_INIT_ARGS* init_args); typedef ex_rv (* TPP_INIT_FUNC)(TPP_INIT_ARGS* init_args);
typedef ex_rv (*TPP_START_FUNC)(void);
typedef ex_rv(*TPP_STOP_FUNC)(void);
typedef void(*TPP_TIMER_FUNC)(void);
// typedef void(*TPP_SET_CFG_FUNC)(TPP_SET_CFG_ARGS* cfg_args);
typedef ex_rv(*TPP_COMMAND_FUNC)(ex_u32 cmd, const char* param); // param is a JSON formatted string. typedef ex_rv (* TPP_START_FUNC)(void);
typedef ex_rv(* TPP_STOP_FUNC)(void);
typedef void(* TPP_TIMER_FUNC)(void);
// param: a JSON formatted string.
typedef ex_rv(* TPP_COMMAND_FUNC)(ex_u32 cmd, const char* param);
#endif // __TP_PROTOCOL_INTERFACE_H__ #endif // __TP_PROTOCOL_INTERFACE_H__

View File

@ -28,7 +28,7 @@ static ex_u8 g_run_type = RUN_UNKNOWN;
#define EOM_CORE_SERVICE_NAME L"Teleport Core Service" #define EOM_CORE_SERVICE_NAME L"Teleport Core Service"
static bool _run_daemon(void); static bool _run_daemon();
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
static int service_install() static int service_install()
@ -113,7 +113,7 @@ static bool _process_cmd_line(int argc, wchar_t** argv)
} }
static int _main_loop(void) static int _main_loop()
{ {
if (g_run_type == RUN_CORE) if (g_run_type == RUN_CORE)
return ts_main(); return ts_main();
@ -163,7 +163,7 @@ int _app_main(int argc, wchar_t** argv)
if (g_run_type == RUN_STOP) { if (g_run_type == RUN_STOP) {
char url[1024] = {0}; char url[1024] = {0};
ex_strformat(url, 1023, "http://%s:%d/rpc?{\"method\":\"exit\"}", g_env.rpc_bind_ip.c_str(), g_env.rpc_bind_port); ex_strformat(url, 1023, R"(http://%s:%d/rpc?{"method":"exit"})", g_env.rpc_bind_ip.c_str(), g_env.rpc_bind_port);
ex_astr body; ex_astr body;
ts_http_get(url, body); ts_http_get(url, body);
ex_printf("%s\n", body.c_str()); ex_printf("%s\n", body.c_str());
@ -195,8 +195,8 @@ int _app_main(int argc, wchar_t** argv)
#endif #endif
static SERVICE_STATUS g_ServiceStatus = { 0 }; static SERVICE_STATUS g_ServiceStatus = { 0 };
static SERVICE_STATUS_HANDLE g_hServiceStatusHandle = NULL; static SERVICE_STATUS_HANDLE g_hServiceStatusHandle = nullptr;
HANDLE g_hWorkerThread = NULL; HANDLE g_hWorkerThread = nullptr;
VOID WINAPI service_main(DWORD argc, wchar_t** argv); VOID WINAPI service_main(DWORD argc, wchar_t** argv);
void WINAPI service_handler(DWORD fdwControl); void WINAPI service_handler(DWORD fdwControl);
@ -214,7 +214,7 @@ int main()
ret = _app_main(_argc, _argv); ret = _app_main(_argc, _argv);
LocalFree(_argv); LocalFree(_argv);
_argv = NULL; _argv = nullptr;
return ret; return ret;
} }
@ -224,8 +224,8 @@ static bool _run_daemon(void)
SERVICE_TABLE_ENTRY DispatchTable[2]; SERVICE_TABLE_ENTRY DispatchTable[2];
DispatchTable[0].lpServiceName = EOM_CORE_SERVICE_NAME; DispatchTable[0].lpServiceName = EOM_CORE_SERVICE_NAME;
DispatchTable[0].lpServiceProc = service_main; DispatchTable[0].lpServiceProc = service_main;
DispatchTable[1].lpServiceName = NULL; DispatchTable[1].lpServiceName = nullptr;
DispatchTable[1].lpServiceProc = NULL; DispatchTable[1].lpServiceProc = nullptr;
if (!StartServiceCtrlDispatcher(DispatchTable)) if (!StartServiceCtrlDispatcher(DispatchTable))
{ {
@ -262,7 +262,7 @@ static void WINAPI service_handler(DWORD fdwControl)
if (g_hWorkerThread) if (g_hWorkerThread)
{ {
// TerminateThread(g_hWorkerThread, 1); // TerminateThread(g_hWorkerThread, 1);
// g_hWorkerThread = NULL; // g_hWorkerThread = nullptr;
g_exit_flag = true; g_exit_flag = true;
g_ServiceStatus.dwWin32ExitCode = 0; g_ServiceStatus.dwWin32ExitCode = 0;
@ -307,8 +307,8 @@ VOID WINAPI service_main(DWORD argc, wchar_t** argv)
} }
DWORD tid = 0; DWORD tid = 0;
g_hWorkerThread = CreateThread(NULL, 0, service_thread_func, NULL, 0, &tid); g_hWorkerThread = CreateThread(nullptr, 0, service_thread_func, nullptr, 0, &tid);
if (NULL == g_hWorkerThread) if (nullptr == g_hWorkerThread)
{ {
EXLOGE_WIN("CreateThread()"); EXLOGE_WIN("CreateThread()");
@ -345,7 +345,7 @@ int main(int argc, char** argv)
memset(&act, 0, sizeof(act)); memset(&act, 0, sizeof(act));
act.sa_sigaction = _sig_handler; act.sa_sigaction = _sig_handler;
act.sa_flags = SA_SIGINFO; act.sa_flags = SA_SIGINFO;
sigaction(SIGINT, &act, NULL); sigaction(SIGINT, &act, nullptr);
wchar_t** wargv = ex_make_wargv(argc, argv); wchar_t** wargv = ex_make_wargv(argc, argv);
int ret = _app_main(argc, wargv); int ret = _app_main(argc, wargv);
@ -359,12 +359,12 @@ void _sig_handler(int signum, siginfo_t* info, void* ptr)
{ {
if (signum == SIGINT || signum == SIGTERM) if (signum == SIGINT || signum == SIGTERM)
{ {
EXLOGW("\n[core] received signal SIGINT, exit now.\n"); EXLOGW("[core] received signal SIGINT, exit now.\n");
g_exit_flag = true; g_exit_flag = true;
} }
} }
static bool _run_daemon(void) static bool _run_daemon()
{ {
pid_t pid = fork(); pid_t pid = fork();
if (pid < 0) if (pid < 0)
@ -382,7 +382,7 @@ static bool _run_daemon(void)
{ {
EXLOGE("[core] setsid() failed.\n"); EXLOGE("[core] setsid() failed.\n");
assert(0); assert(0);
exit(EXIT_FAILURE); // exit(EXIT_FAILURE);
} }
umask(0); umask(0);
@ -399,14 +399,14 @@ static bool _run_daemon(void)
} }
// now I'm second children. // now I'm second children.
int ret = chdir("/"); chdir("/");
close(STDIN_FILENO); close(STDIN_FILENO);
int stdfd = open("/dev/null", O_RDWR); int std_fd = open("/dev/null", O_RDWR);
close(STDOUT_FILENO); close(STDOUT_FILENO);
close(STDERR_FILENO); close(STDERR_FILENO);
dup2(stdfd, STDOUT_FILENO); dup2(std_fd, STDOUT_FILENO);
dup2(stdfd, STDERR_FILENO); dup2(std_fd, STDERR_FILENO);
return true; return true;
} }

View File

@ -1,119 +1,101 @@
#include "tp_tpp_mgr.h" #include "tp_tpp_mgr.h"
#include "ts_main.h" #include "ts_main.h"
// #include "ts_session.h"
// #include "ts_http_rpc.h"
// #include "ts_web_rpc.h"
#include "ts_env.h" #include "ts_env.h"
// #include <mbedtls/platform.h>
// #include <mbedtls/debug.h>
TppManager g_tpp_mgr; TppManager g_tpp_mgr;
extern ExLogger g_ex_logger; extern ExLogger g_ex_logger;
bool TppManager::load_tpp(const ex_wstr& libname) bool TppManager::load_tpp(const ex_wstr& libname) {
{ ex_wstr filename;
ex_wstr filename;
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
filename = libname + L".dll"; filename = libname + L".dll";
#elif defined (EX_OS_LINUX) #elif defined (EX_OS_LINUX)
filename = L"lib"; filename = L"lib";
filename += libname; filename += libname;
filename += L".so"; filename += L".so";
#elif defined (EX_OS_MACOS) #elif defined (EX_OS_MACOS)
filename = L"lib"; filename = L"lib";
filename += libname; filename += libname;
filename += L".dylib"; filename += L".dylib";
#endif #endif
ex_wstr libfile = g_env.m_exec_path; ex_wstr lib_file = g_env.m_exec_path;
ex_path_join(libfile, false, filename.c_str(), NULL); ex_path_join(lib_file, false, filename.c_str(), nullptr);
EXLOGV(L"[core] load protocol lib: %ls\n", libfile.c_str()); EXLOGI(L"[core] load protocol lib: %ls\n", lib_file.c_str());
TPP_LIB* lib = new TPP_LIB; auto lib = new TPP_LIB;
lib->dylib = ex_dlopen(libfile.c_str()); lib->dylib = ex_dlopen(lib_file.c_str());
if (NULL == lib->dylib) if (nullptr == lib->dylib) {
{ EXLOGE(L"[core] load dylib `%ls` failed.\n", lib_file.c_str());
EXLOGE(L"[core] load dylib `%ls` failed.\n", libfile.c_str()); delete lib;
delete lib; return false;
return false; }
}
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
lib->init = (TPP_INIT_FUNC)GetProcAddress(lib->dylib, "tpp_init"); lib->init = (TPP_INIT_FUNC)GetProcAddress(lib->dylib, "tpp_init");
lib->start = (TPP_START_FUNC)GetProcAddress(lib->dylib, "tpp_start"); lib->start = (TPP_START_FUNC)GetProcAddress(lib->dylib, "tpp_start");
lib->stop = (TPP_STOP_FUNC)GetProcAddress(lib->dylib, "tpp_stop"); lib->stop = (TPP_STOP_FUNC)GetProcAddress(lib->dylib, "tpp_stop");
lib->timer = (TPP_TIMER_FUNC)GetProcAddress(lib->dylib, "tpp_timer"); lib->timer = (TPP_TIMER_FUNC)GetProcAddress(lib->dylib, "tpp_timer");
// lib->set_cfg = (TPP_SET_CFG_FUNC)GetProcAddress(lib->dylib, "tpp_set_cfg"); lib->command = (TPP_COMMAND_FUNC)GetProcAddress(lib->dylib, "tpp_command");
lib->command = (TPP_COMMAND_FUNC)GetProcAddress(lib->dylib, "tpp_command");
#else #else
lib->init = (TPP_INIT_FUNC)dlsym(lib->dylib, "tpp_init"); lib->init = (TPP_INIT_FUNC) dlsym(lib->dylib, "tpp_init");
lib->start = (TPP_START_FUNC)dlsym(lib->dylib, "tpp_start"); lib->start = (TPP_START_FUNC) dlsym(lib->dylib, "tpp_start");
lib->stop = (TPP_STOP_FUNC)dlsym(lib->dylib, "tpp_stop"); lib->stop = (TPP_STOP_FUNC) dlsym(lib->dylib, "tpp_stop");
lib->timer = (TPP_TIMER_FUNC)dlsym(lib->dylib, "tpp_timer"); lib->timer = (TPP_TIMER_FUNC) dlsym(lib->dylib, "tpp_timer");
// lib->set_cfg = (TPP_SET_CFG_FUNC)dlsym(lib->dylib, "tpp_set_cfg"); lib->command = (TPP_COMMAND_FUNC) dlsym(lib->dylib, "tpp_command");
lib->command = (TPP_COMMAND_FUNC)dlsym(lib->dylib, "tpp_command");
#endif #endif
if ( if (
lib->init == NULL lib->init == nullptr
|| lib->start == NULL || lib->start == nullptr
|| lib->stop == NULL || lib->stop == nullptr
|| lib->timer == NULL || lib->timer == nullptr
//|| lib->set_cfg == NULL || lib->command == nullptr
|| lib->command == NULL ) {
) EXLOGE(L"[core] load dylib `%ls` failed, can not locate all functions.\n", lib_file.c_str());
{ delete lib;
EXLOGE(L"[core] load dylib `%ls` failed, can not locate all functions.\n", libfile.c_str()); return false;
delete lib; }
return false;
}
TPP_INIT_ARGS init_args; TPP_INIT_ARGS init_args;
init_args.logger = &g_ex_logger; init_args.logger = &g_ex_logger;
init_args.exec_path = g_env.m_exec_path; init_args.exec_path = g_env.m_exec_path;
init_args.etc_path = g_env.m_etc_path; init_args.etc_path = g_env.m_etc_path;
init_args.replay_path = g_env.m_replay_path; init_args.replay_path = g_env.m_replay_path;
init_args.cfg = &g_env.get_ini(); init_args.cfg = &g_env.get_ini();
init_args.func_get_connect_info = tpp_get_connect_info; init_args.func_get_connect_info = tpp_get_connect_info;
init_args.func_free_connect_info = tpp_free_connect_info; init_args.func_free_connect_info = tpp_free_connect_info;
init_args.func_session_begin = tpp_session_begin; init_args.func_session_begin = tpp_session_begin;
init_args.func_session_update = tpp_session_update; init_args.func_session_update = tpp_session_update;
init_args.func_session_end = tpp_session_end; init_args.func_session_end = tpp_session_end;
if (EXRV_OK != lib->init(&init_args)) if (EXRV_OK != lib->init(&init_args)) {
{ EXLOGE(L"[core] failed to init protocol `%ls`.\n", libname.c_str());
EXLOGE(L"[core] failed to init protocol `%ls`.\n", libname.c_str()); delete lib;
delete lib; return false;
return false; }
} if (EXRV_OK != lib->start()) {
if (EXRV_OK != lib->start()) EXLOGE(L"[core] failed to start protocol `%ls`.\n", libname.c_str());
{ delete lib;
EXLOGE(L"[core] failed to start protocol `%ls`.\n", libname.c_str()); return false;
delete lib; }
return false;
}
m_libs.push_back(lib); m_libs.push_back(lib);
return true; return true;
} }
void TppManager::stop_all(void) { void TppManager::stop_all() {
tpp_libs::iterator it = m_libs.begin(); for (auto& lib : m_libs) {
for (; it != m_libs.end(); ++it) lib->stop();
{ }
(*it)->stop();
}
} }
void TppManager::timer(void) { void TppManager::timer() {
tpp_libs::iterator it = m_libs.begin(); for (auto& lib : m_libs) {
for (; it != m_libs.end(); ++it) lib->timer();
{ }
(*it)->timer();
}
} }
// void TppManager::set_config(int noop_timeout) { // void TppManager::set_config(int noop_timeout) {
@ -129,16 +111,13 @@ void TppManager::timer(void) {
// } // }
void TppManager::set_runtime_config(const ex_astr& sp) { void TppManager::set_runtime_config(const ex_astr& sp) {
tpp_libs::iterator it = m_libs.begin(); for (auto& lib : m_libs) {
for (; it != m_libs.end(); ++it) { lib->command(TPP_CMD_SET_RUNTIME_CFG, sp.c_str());
(*it)->command(TPP_CMD_SET_RUNTIME_CFG, sp.c_str()); }
}
} }
void TppManager::kill_sessions(const ex_astr& sp) { void TppManager::kill_sessions(const ex_astr& sp) {
tpp_libs::iterator it = m_libs.begin(); for (auto& lib : m_libs) {
for (; it != m_libs.end(); ++it) { lib->command(TPP_CMD_KILL_SESSIONS, sp.c_str());
(*it)->command(TPP_CMD_KILL_SESSIONS, sp.c_str()); }
}
} }

View File

@ -5,59 +5,59 @@
#include <ex.h> #include <ex.h>
typedef struct TPP_LIB typedef struct TPP_LIB {
{ TPP_LIB() :
TPP_LIB() dylib(nullptr),
{ init(nullptr),
dylib = NULL; start(nullptr),
init = NULL; stop(nullptr),
} timer(nullptr),
~TPP_LIB() command(nullptr) {
{ }
if (NULL != dylib)
ex_dlclose(dylib);
dylib = NULL;
}
EX_DYLIB_HANDLE dylib; ~TPP_LIB() {
TPP_INIT_FUNC init; if (nullptr != dylib)
TPP_START_FUNC start; ex_dlclose(dylib);
TPP_STOP_FUNC stop; dylib = nullptr;
TPP_TIMER_FUNC timer; }
// TPP_SET_CFG_FUNC set_cfg;
TPP_COMMAND_FUNC command; EX_DYLIB_HANDLE dylib;
}TPP_LIB; TPP_INIT_FUNC init;
TPP_START_FUNC start;
TPP_STOP_FUNC stop;
TPP_TIMER_FUNC timer;
TPP_COMMAND_FUNC command;
} TPP_LIB;
typedef std::list<TPP_LIB*> tpp_libs; typedef std::list<TPP_LIB*> tpp_libs;
class TppManager class TppManager {
{
public: public:
TppManager() TppManager() = default;
{
}
~TppManager()
{
tpp_libs::iterator it = m_libs.begin();
for (; it != m_libs.end(); ++it)
{
delete (*it);
}
m_libs.clear();
}
bool load_tpp(const ex_wstr& libfile); ~TppManager() {
void stop_all(void); for (auto lib : m_libs) {
void timer(void); // ´óÔ¼1Ãëµ÷ÓÃÒ»´Î delete lib;
int count(void) { return m_libs.size(); } }
m_libs.clear();
}
void set_config(int noop_timeout); bool load_tpp(const ex_wstr& lib_file);
void set_runtime_config(const ex_astr& sp);
void kill_sessions(const ex_astr& sp); void stop_all();
void timer(); // ´óÔ¼1Ãëµ÷ÓÃÒ»´Î
int count() {
return m_libs.size();
}
void set_runtime_config(const ex_astr& sp);
void kill_sessions(const ex_astr& sp);
private: private:
tpp_libs m_libs; tpp_libs m_libs;
}; };
extern TppManager g_tpp_mgr; extern TppManager g_tpp_mgr;

View File

@ -6,52 +6,53 @@
#include "tp_tpp_mgr.h" #include "tp_tpp_mgr.h"
#include <mbedtls/platform.h> #include <mbedtls/platform.h>
#include <mbedtls/debug.h> // #include <mbedtls/debug.h>
bool g_exit_flag = false; bool g_exit_flag = false;
TPP_CONNECT_INFO *tpp_get_connect_info(const char *sid) { TPP_CONNECT_INFO* tpp_get_connect_info(const char* sid) {
TS_CONNECT_INFO sinfo; TS_CONNECT_INFO connect_info;
bool ret = g_session_mgr.get_connect_info(sid, sinfo);
bool ret = g_session_mgr.get_connect_info(sid, connect_info);
if (!ret) if (!ret)
return NULL; return nullptr;
TPP_CONNECT_INFO *info = (TPP_CONNECT_INFO *) calloc(1, sizeof(TPP_CONNECT_INFO)); auto info = (TPP_CONNECT_INFO*) calloc(1, sizeof(TPP_CONNECT_INFO));
info->sid = (char *) calloc(1, sinfo.sid.length() + 1); info->sid = (char*) calloc(1, connect_info.sid.length() + 1);
ex_strcpy(info->sid, sinfo.sid.length() + 1, sinfo.sid.c_str()); ex_strcpy(info->sid, connect_info.sid.length() + 1, connect_info.sid.c_str());
info->user_username = (char *) calloc(1, sinfo.user_username.length() + 1); info->user_username = (char*) calloc(1, connect_info.user_username.length() + 1);
ex_strcpy(info->user_username, sinfo.user_username.length() + 1, sinfo.user_username.c_str()); ex_strcpy(info->user_username, connect_info.user_username.length() + 1, connect_info.user_username.c_str());
info->host_ip = (char *) calloc(1, sinfo.host_ip.length() + 1); info->host_ip = (char*) calloc(1, connect_info.host_ip.length() + 1);
ex_strcpy(info->host_ip, sinfo.host_ip.length() + 1, sinfo.host_ip.c_str()); ex_strcpy(info->host_ip, connect_info.host_ip.length() + 1, connect_info.host_ip.c_str());
info->conn_ip = (char *) calloc(1, sinfo.conn_ip.length() + 1); info->conn_ip = (char*) calloc(1, connect_info.conn_ip.length() + 1);
ex_strcpy(info->conn_ip, sinfo.conn_ip.length() + 1, sinfo.conn_ip.c_str()); ex_strcpy(info->conn_ip, connect_info.conn_ip.length() + 1, connect_info.conn_ip.c_str());
info->client_ip = (char *) calloc(1, sinfo.client_ip.length() + 1); info->client_ip = (char*) calloc(1, connect_info.client_ip.length() + 1);
ex_strcpy(info->client_ip, sinfo.client_ip.length() + 1, sinfo.client_ip.c_str()); ex_strcpy(info->client_ip, connect_info.client_ip.length() + 1, connect_info.client_ip.c_str());
info->acc_username = (char *) calloc(1, sinfo.acc_username.length() + 1); info->acc_username = (char*) calloc(1, connect_info.acc_username.length() + 1);
ex_strcpy(info->acc_username, sinfo.acc_username.length() + 1, sinfo.acc_username.c_str()); ex_strcpy(info->acc_username, connect_info.acc_username.length() + 1, connect_info.acc_username.c_str());
info->acc_secret = (char *) calloc(1, sinfo.acc_secret.length() + 1); info->acc_secret = (char*) calloc(1, connect_info.acc_secret.length() + 1);
ex_strcpy(info->acc_secret, sinfo.acc_secret.length() + 1, sinfo.acc_secret.c_str()); ex_strcpy(info->acc_secret, connect_info.acc_secret.length() + 1, connect_info.acc_secret.c_str());
info->username_prompt = (char *) calloc(1, sinfo.username_prompt.length() + 1); info->username_prompt = (char*) calloc(1, connect_info.username_prompt.length() + 1);
ex_strcpy(info->username_prompt, sinfo.username_prompt.length() + 1, sinfo.username_prompt.c_str()); ex_strcpy(info->username_prompt, connect_info.username_prompt.length() + 1, connect_info.username_prompt.c_str());
info->password_prompt = (char *) calloc(1, sinfo.password_prompt.length() + 1); info->password_prompt = (char*) calloc(1, connect_info.password_prompt.length() + 1);
ex_strcpy(info->password_prompt, sinfo.password_prompt.length() + 1, sinfo.password_prompt.c_str()); ex_strcpy(info->password_prompt, connect_info.password_prompt.length() + 1, connect_info.password_prompt.c_str());
info->user_id = sinfo.user_id; info->user_id = connect_info.user_id;
info->host_id = sinfo.host_id; info->host_id = connect_info.host_id;
info->acc_id = sinfo.acc_id; info->acc_id = connect_info.acc_id;
info->conn_port = sinfo.conn_port; info->conn_port = connect_info.conn_port;
info->protocol_type = sinfo.protocol_type; info->protocol_type = connect_info.protocol_type;
info->protocol_sub_type = sinfo.protocol_sub_type; info->protocol_sub_type = connect_info.protocol_sub_type;
info->protocol_flag = sinfo.protocol_flag; info->protocol_flag = connect_info.protocol_flag;
info->record_flag = sinfo.record_flag; info->record_flag = connect_info.record_flag;
info->auth_type = sinfo.auth_type; info->auth_type = connect_info.auth_type;
return info; return info;
} }
void tpp_free_connect_info(TPP_CONNECT_INFO *info) { void tpp_free_connect_info(TPP_CONNECT_INFO* info) {
if (NULL == info) if (nullptr == info)
return; return;
g_session_mgr.free_connect_info(info->sid); g_session_mgr.free_connect_info(info->sid);
@ -68,190 +69,46 @@ void tpp_free_connect_info(TPP_CONNECT_INFO *info) {
free(info); free(info);
} }
bool tpp_session_begin(const TPP_CONNECT_INFO *info, int *db_id) { bool tpp_session_begin(const TPP_CONNECT_INFO* info, int* db_id) {
if (NULL == info || NULL == db_id) if (nullptr == info || nullptr == db_id)
return false; return false;
TS_CONNECT_INFO sinfo; TS_CONNECT_INFO connect_info;
sinfo.sid = info->sid; connect_info.sid = info->sid;
sinfo.user_id = info->user_id; connect_info.user_id = info->user_id;
sinfo.host_id = info->host_id; connect_info.host_id = info->host_id;
sinfo.acc_id = info->acc_id; connect_info.acc_id = info->acc_id;
sinfo.user_username = info->user_username; connect_info.user_username = info->user_username;
sinfo.host_ip = info->host_ip; connect_info.host_ip = info->host_ip;
sinfo.conn_ip = info->conn_ip; connect_info.conn_ip = info->conn_ip;
sinfo.client_ip = info->client_ip; connect_info.client_ip = info->client_ip;
sinfo.acc_username = info->acc_username; connect_info.acc_username = info->acc_username;
sinfo.conn_port = info->conn_port; connect_info.conn_port = info->conn_port;
sinfo.protocol_type = info->protocol_type; connect_info.protocol_type = info->protocol_type;
sinfo.protocol_sub_type = info->protocol_sub_type; connect_info.protocol_sub_type = info->protocol_sub_type;
sinfo.auth_type = info->auth_type; connect_info.auth_type = info->auth_type;
return ts_web_rpc_session_begin(sinfo, *db_id); return ts_web_rpc_session_begin(connect_info, *db_id);
} }
bool tpp_session_update(int db_id, int protocol_sub_type, int state) { 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) { bool tpp_session_end(const char* sid, int db_id, int ret) {
return ts_web_rpc_session_end(sid, db_id, ret); return ts_web_rpc_session_end(sid, db_id, ret);
} }
// typedef struct TPP_LIB int ts_main() {
// { ExIniFile& ini = g_env.get_ini();
// TPP_LIB()
// {
// dylib = NULL;
// init = NULL;
// }
// ~TPP_LIB()
// {
// if (NULL != dylib)
// ex_dlclose(dylib);
// dylib = NULL;
// }
//
// EX_DYLIB_HANDLE dylib;
// TPP_INIT_FUNC init;
// TPP_START_FUNC start;
// TPP_STOP_FUNC stop;
// TPP_TIMER_FUNC timer;
// }TPP_LIB;
//
// typedef std::list<TPP_LIB*> tpp_libs;
//
// class TppManager
// {
// public:
// TppManager()
// {
// }
// ~TppManager()
// {
// tpp_libs::iterator it = m_libs.begin();
// for (; it != m_libs.end(); ++it)
// {
// delete (*it);
// }
// m_libs.clear();
// }
//
// bool load_tpp(const ex_wstr& libfile);
// void stop_all(void);
// void timer(void); // ´óÔ¼1Ãëµ÷ÓÃÒ»´Î
// int count(void) { return m_libs.size(); }
//
// private:
// tpp_libs m_libs;
// };
//
// static TppManager g_tpp_mgr;
// extern ExLogger g_ex_logger;
//
// bool TppManager::load_tpp(const ex_wstr& libname)
// {
// ex_wstr filename;
// #ifdef EX_OS_WIN32
// filename = libname + L".dll";
// #elif defined (EX_OS_LINUX)
// filename = L"lib";
// filename += libname;
// filename += L".so";
// #elif defined (EX_OS_MACOS)
// filename = L"lib";
// filename += libname;
// filename += L".dylib";
// #endif
//
// ex_wstr libfile = g_env.m_exec_path;
// ex_path_join(libfile, false, filename.c_str(), NULL);
// EXLOGV(L"[core] load protocol lib: %ls\n", libfile.c_str());
//
// TPP_LIB* lib = new TPP_LIB;
//
// lib->dylib = ex_dlopen(libfile.c_str());
// if (NULL == lib->dylib)
// {
// EXLOGE(L"[core] load dylib `%ls` failed.\n", libfile.c_str());
// delete lib;
// return false;
// }
//
// #ifdef EX_OS_WIN32
// lib->init = (TPP_INIT_FUNC)GetProcAddress(lib->dylib, "tpp_init");
// lib->start = (TPP_START_FUNC)GetProcAddress(lib->dylib, "tpp_start");
// lib->stop = (TPP_STOP_FUNC)GetProcAddress(lib->dylib, "tpp_stop");
// lib->timer = (TPP_TIMER_FUNC)GetProcAddress(lib->dylib, "tpp_timer");
// #else
// lib->init = (TPP_INIT_FUNC)dlsym(lib->dylib, "tpp_init");
// lib->start = (TPP_START_FUNC)dlsym(lib->dylib, "tpp_start");
// lib->stop = (TPP_STOP_FUNC)dlsym(lib->dylib, "tpp_stop");
// lib->timer = (TPP_TIMER_FUNC)dlsym(lib->dylib, "tpp_timer");
// #endif
//
// if (lib->init == NULL || lib->start == NULL || lib->stop == NULL || lib->timer == NULL)
// {
// EXLOGE(L"[core] load dylib `%ls` failed, can not locate all functions.\n", libfile.c_str());
// delete lib;
// return false;
// }
//
// TPP_INIT_ARGS init_args;
// init_args.logger = &g_ex_logger;
// init_args.exec_path = g_env.m_exec_path;
// init_args.etc_path = g_env.m_etc_path;
// init_args.replay_path = g_env.m_replay_path;
// init_args.cfg = &g_env.get_ini();
// init_args.func_get_connect_info = tpp_get_connect_info;
// init_args.func_free_connect_info = tpp_free_connect_info;
// init_args.func_session_begin = tpp_session_begin;
// init_args.func_session_update = tpp_session_update;
// init_args.func_session_end = tpp_session_end;
//
// if (EXRV_OK != lib->init(&init_args))
// {
// EXLOGE(L"[core] failed to init protocol `%ls`.\n", libname.c_str());
// delete lib;
// return false;
// }
// if (EXRV_OK != lib->start())
// {
// EXLOGE(L"[core] failed to start protocol `%ls`.\n", libname.c_str());
// delete lib;
// return false;
// }
//
// m_libs.push_back(lib);
// return true;
// }
//
// void TppManager::stop_all(void) {
// tpp_libs::iterator it = m_libs.begin();
// for (; it != m_libs.end(); ++it)
// {
// (*it)->stop();
// }
// }
//
// void TppManager::timer(void) {
// tpp_libs::iterator it = m_libs.begin();
// for (; it != m_libs.end(); ++it)
// {
// (*it)->timer();
// }
// }
int ts_main(void) { EXLOGI("\n");
ExIniFile &ini = g_env.get_ini(); EXLOGI("###############################################################\n");
EXLOGI(L"\n");
EXLOGI(L"###############################################################\n");
EXLOGI(L"Load config file: %ls.\n", ini.get_filename().c_str()); EXLOGI(L"Load config file: %ls.\n", ini.get_filename().c_str());
EXLOGI(L"Teleport Core Server starting ...\n"); EXLOGI("Teleport Core Server starting ...\n");
ex_ini_sections &secs = ini.GetAllSections(); ex_ini_sections& secs = ini.GetAllSections();
TsHttpRpc rpc; TsHttpRpc rpc;
// 枚举配置文件中的[protocol-xxx]小节,加载对应的协议动态库 // 枚举配置文件中的[protocol-xxx]小节,加载对应的协议动态库
@ -259,18 +116,18 @@ int ts_main(void) {
do { do {
if (!g_session_mgr.start()) { if (!g_session_mgr.start()) {
EXLOGE(L"[core] failed to start session-id manager.\n"); EXLOGE("[core] failed to start session-id manager.\n");
all_ok = false; all_ok = false;
break; break;
} }
if (!rpc.init() || !rpc.start()) { if (!rpc.init() || !rpc.start()) {
EXLOGE(L"[core] rpc init/start failed.\n"); EXLOGE("[core] rpc init/start failed.\n");
all_ok = false; all_ok = false;
break; break;
} }
ex_ini_sections::iterator it = secs.begin(); auto it = secs.begin();
for (; it != secs.end(); ++it) { for (; it != secs.end(); ++it) {
if (it->first.length() > 9 && 0 == wcsncmp(it->first.c_str(), L"protocol-", 9)) { if (it->first.length() > 9 && 0 == wcsncmp(it->first.c_str(), L"protocol-", 9)) {
ex_wstr libname; ex_wstr libname;
@ -280,7 +137,7 @@ int ts_main(void) {
bool enabled = false; bool enabled = false;
it->second->GetBool(L"enabled", enabled, false); it->second->GetBool(L"enabled", enabled, false);
if (!enabled) { if (!enabled) {
EXLOGV(L"[core] `%ls` not enabled.\n", libname.c_str()); EXLOGW(L"[core] `%ls` not enabled.\n", libname.c_str());
continue; continue;
} }
@ -291,7 +148,7 @@ int ts_main(void) {
} }
} }
} while (0); } while (false);
if (0 == g_tpp_mgr.count()) { if (0 == g_tpp_mgr.count()) {
all_ok = false; all_ok = false;
@ -304,17 +161,19 @@ int ts_main(void) {
if (!g_exit_flag) { if (!g_exit_flag) {
ts_web_rpc_register_core(); ts_web_rpc_register_core();
EXLOGV("[core] ---- initialized, ready for service ----\n"); EXLOGI("[core] ---- initialized, ready for service ----\n");
while (!g_exit_flag) { while (!g_exit_flag) {
ex_sleep_ms(1000); ex_sleep_ms(1000);
g_tpp_mgr.timer(); g_tpp_mgr.timer();
} }
} }
EXLOGW("[core] try to stop all thread and exit.\n"); EXLOGI("[core] try to stop all thread and exit.\n");
g_tpp_mgr.stop_all(); g_tpp_mgr.stop_all();
rpc.stop(); rpc.stop();
g_session_mgr.stop(); g_session_mgr.stop();
EXLOGI("[core] done.\n");
return 0; return 0;
} }

View File

@ -3,7 +3,7 @@
#include "../common/protocol_interface.h" #include "../common/protocol_interface.h"
int ts_main(void); int ts_main();
TPP_CONNECT_INFO* tpp_get_connect_info(const char* sid); TPP_CONNECT_INFO* tpp_get_connect_info(const char* sid);
void tpp_free_connect_info(TPP_CONNECT_INFO* info); void tpp_free_connect_info(TPP_CONNECT_INFO* info);

View File

@ -11,7 +11,7 @@ TsSessionManager::TsSessionManager() :
} }
TsSessionManager::~TsSessionManager() { TsSessionManager::~TsSessionManager() {
ts_connections::iterator it_conn = m_connections.begin(); auto it_conn = m_connections.begin();
for (; it_conn != m_connections.end(); ++it_conn) { for (; it_conn != m_connections.end(); ++it_conn) {
EXLOGD("[core] m_connections not clean: %s, %s\n", it_conn->first.c_str(), it_conn->second->acc_username.c_str()); EXLOGD("[core] m_connections not clean: %s, %s\n", it_conn->first.c_str(), it_conn->second->acc_username.c_str());
delete it_conn->second; delete it_conn->second;
@ -19,7 +19,7 @@ TsSessionManager::~TsSessionManager() {
m_connections.clear(); m_connections.clear();
} }
void TsSessionManager::_thread_loop(void) { void TsSessionManager::_thread_loop() {
for (;;) { for (;;) {
ex_sleep_ms(1000); ex_sleep_ms(1000);
if (m_need_stop) if (m_need_stop)
@ -28,13 +28,13 @@ void TsSessionManager::_thread_loop(void) {
} }
} }
void TsSessionManager::_remove_expired_connect_info(void) { void TsSessionManager::_remove_expired_connect_info() {
// 超过15秒未进行连接的connect-info会被移除 // 超过15秒未进行连接的connect-info会被移除
ExThreadSmartLock locker(m_lock); ExThreadSmartLock locker(m_lock);
ex_u64 _now = ex_get_tick_count(); ex_u64 _now = ex_get_tick_count();
ts_connections::iterator it = m_connections.begin(); auto it = m_connections.begin();
for (; it != m_connections.end();) { 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)); //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) { if (it->second->ref_count == 0 && _now - 15000 > it->second->ticket_start) {
@ -42,16 +42,17 @@ void TsSessionManager::_remove_expired_connect_info(void) {
delete it->second; delete it->second;
m_connections.erase(it++); m_connections.erase(it++);
EXLOGD("[core] there are %d connection info exists.\n", m_connections.size()); EXLOGD("[core] there are %d connection info exists.\n", m_connections.size());
} else { }
else {
++it; ++it;
} }
} }
} }
bool TsSessionManager::get_connect_info(const ex_astr &sid, TS_CONNECT_INFO &info) { bool TsSessionManager::get_connect_info(const ex_astr& sid, TS_CONNECT_INFO& info) {
ExThreadSmartLock locker(m_lock); ExThreadSmartLock locker(m_lock);
ts_connections::iterator it = m_connections.find(sid); auto it = m_connections.find(sid);
if (it == m_connections.end()) if (it == m_connections.end())
return false; return false;
@ -79,10 +80,10 @@ bool TsSessionManager::get_connect_info(const ex_astr &sid, TS_CONNECT_INFO &inf
return true; return true;
} }
bool TsSessionManager::free_connect_info(const ex_astr &sid) { bool TsSessionManager::free_connect_info(const ex_astr& sid) {
ExThreadSmartLock locker(m_lock); ExThreadSmartLock locker(m_lock);
ts_connections::iterator it = m_connections.find(sid); auto it = m_connections.find(sid);
if (it == m_connections.end()) if (it == m_connections.end())
return false; return false;
@ -97,7 +98,8 @@ bool TsSessionManager::free_connect_info(const ex_astr &sid) {
m_connections.erase(it); m_connections.erase(it);
EXLOGD("[core] there are %d connection info exists.\n", m_connections.size()); EXLOGD("[core] there are %d connection info exists.\n", m_connections.size());
} }
} else { }
else {
if (it->second->ref_count == 1) if (it->second->ref_count == 1)
it->second->ref_count = 0; it->second->ref_count = 0;
it->second->ticket_start = ex_get_tick_count() + 45000; // 我们将时间向后移动45秒这样如果没有发生RDP的第二次连接这个连接信息就会在一分钟后被清除。 it->second->ticket_start = ex_get_tick_count() + 45000; // 我们将时间向后移动45秒这样如果没有发生RDP的第二次连接这个连接信息就会在一分钟后被清除。
@ -107,11 +109,14 @@ bool TsSessionManager::free_connect_info(const ex_astr &sid) {
return true; return true;
} }
bool TsSessionManager::request_session(ex_astr &sid, TS_CONNECT_INFO *info) { bool TsSessionManager::request_session(ex_astr& sid, TS_CONNECT_INFO* info) {
ExThreadSmartLock locker(m_lock); ExThreadSmartLock locker(m_lock);
EXLOGD("[core] request session: account: [%s], protocol: [%d], auth-mode: [%d]\n", info->acc_username.c_str(), EXLOGD(
info->protocol_type, info->auth_type); "[core] request session: account: [%s], protocol: [%d], auth-mode: [%d]\n",
info->acc_username.c_str(),
info->protocol_type, info->auth_type
);
ex_astr _sid; ex_astr _sid;
int retried = 0; int retried = 0;
@ -143,7 +148,7 @@ bool TsSessionManager::request_session(ex_astr &sid, TS_CONNECT_INFO *info) {
return true; return true;
} }
void TsSessionManager::_gen_session_id(ex_astr &sid, const TS_CONNECT_INFO *info, int len) { void TsSessionManager::_gen_session_id(ex_astr& sid, const TS_CONNECT_INFO* info, int len) {
mbedtls_sha1_context sha; mbedtls_sha1_context sha;
ex_u8 sha_digist[20] = {0}; ex_u8 sha_digist[20] = {0};
@ -152,11 +157,11 @@ void TsSessionManager::_gen_session_id(ex_astr &sid, const TS_CONNECT_INFO *info
mbedtls_sha1_init(&sha); mbedtls_sha1_init(&sha);
mbedtls_sha1_starts(&sha); mbedtls_sha1_starts(&sha);
mbedtls_sha1_update(&sha, (const unsigned char *) &_tick, sizeof(ex_u64)); 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*) &_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->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->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_update(&sha, (const unsigned char*) info->acc_username.c_str(), info->acc_username.length());
mbedtls_sha1_finish(&sha, sha_digist); mbedtls_sha1_finish(&sha, sha_digist);
mbedtls_sha1_free(&sha); mbedtls_sha1_free(&sha);

View File

@ -6,68 +6,65 @@
#include <ex.h> #include <ex.h>
typedef struct TS_CONNECT_INFO typedef struct TS_CONNECT_INFO {
{ ex_astr sid;
// TODO:
//TPP_CONNECT_INFO conn;
ex_astr sid; // 与此连接信息相关的三个要素的ID
int user_id;
int host_id;
int acc_id;
// 与此连接信息相关的三个要素的ID ex_astr user_username;// 申请本次连接的用户名
int user_id;
int host_id;
int acc_id;
ex_astr user_username;// 申请本次连接的用户名 ex_astr host_ip;// 真正的远程主机IP如果是直接连接模式则与remote_host_ip相同
ex_astr conn_ip;// 要连接的远程主机的IP如果是端口映射模式则为路由主机的IP
int conn_port;// 要连接的远程主机的端口(如果是端口映射模式,则为路由主机的端口)
ex_astr client_ip;
ex_astr host_ip;// 真正的远程主机IP如果是直接连接模式则与remote_host_ip相同 ex_astr acc_username; // 远程主机的账号
ex_astr conn_ip;// 要连接的远程主机的IP如果是端口映射模式则为路由主机的IP ex_astr acc_secret; // 远程主机账号的密码(或者私钥
int conn_port;// 要连接的远程主机的端口(如果是端口映射模式,则为路由主机的端口) ex_astr username_prompt;// for telnet
ex_astr client_ip; ex_astr password_prompt;// for telnet
ex_astr acc_username; // 远程主机的账号 int protocol_type;
ex_astr acc_secret; // 远程主机账号的密码(或者私钥) int protocol_sub_type;
ex_astr username_prompt;// for telnet int protocol_flag;
ex_astr password_prompt;// for telnet int record_flag;
int auth_type;
int protocol_type; int ref_count;// 这个连接信息的引用计数如果创建的连接信息从来未被使用则超过30秒后自动销毁
int protocol_sub_type; ex_u64 ticket_start;// 此连接信息的创建时间(用于超时未使用就销毁的功能)
int protocol_flag; } TS_CONNECT_INFO;
int record_flag;
int auth_type;
int ref_count;// 这个连接信息的引用计数如果创建的连接信息从来未被使用则超过30秒后自动销毁
ex_u64 ticket_start;// 此连接信息的创建时间(用于超时未使用就销毁的功能)
}TS_CONNECT_INFO;
typedef std::map<ex_astr, TS_CONNECT_INFO*> ts_connections; // sid -> TS_CONNECT_INFO typedef std::map<ex_astr, TS_CONNECT_INFO*> ts_connections; // sid -> TS_CONNECT_INFO
class TsSessionManager : public ExThreadBase class TsSessionManager : public ExThreadBase {
{
public: public:
TsSessionManager(); TsSessionManager();
~TsSessionManager();
// generate a sid for connection info. ~TsSessionManager() override;
bool request_session(ex_astr& sid, TS_CONNECT_INFO* info);
// 根据sid得到连接信息并增加引用计数 // generate a sid for connection info.
bool get_connect_info(const ex_astr& sid, TS_CONNECT_INFO& info); bool request_session(ex_astr& sid, TS_CONNECT_INFO* info);
// 减少引用计数当引用计数为0时删除之
bool free_connect_info(const ex_astr& sid); // 根据sid得到连接信息并增加引用计数
bool get_connect_info(const ex_astr& sid, TS_CONNECT_INFO& info);
// 减少引用计数当引用计数为0时删除之
bool free_connect_info(const ex_astr& sid);
protected: protected:
void _thread_loop(void); void _thread_loop() override;
private: private:
void _gen_session_id(ex_astr& sid, const TS_CONNECT_INFO* info, int len); void _gen_session_id(ex_astr& sid, const TS_CONNECT_INFO* info, int len);
// 定时检查超过30秒未进行连接的connect-info会被移除 // 定时检查超过30秒未进行连接的connect-info会被移除
void _remove_expired_connect_info(void); void _remove_expired_connect_info();
private: private:
ExThreadLock m_lock; ExThreadLock m_lock;
ts_connections m_connections; ts_connections m_connections;
}; };
extern TsSessionManager g_session_mgr; extern TsSessionManager g_session_mgr;

View File

@ -253,7 +253,6 @@ bool ts_web_rpc_session_begin(TS_CONNECT_INFO& info, int& record_id)
jreq["param"]["protocol_sub_type"] = info.protocol_sub_type; jreq["param"]["protocol_sub_type"] = info.protocol_sub_type;
ex_astr json_param; ex_astr json_param;
//json_param = json_writer.write(jreq);
Json::StreamWriterBuilder jwb; Json::StreamWriterBuilder jwb;
std::unique_ptr<Json::StreamWriter> jwriter(jwb.newStreamWriter()); std::unique_ptr<Json::StreamWriter> jwriter(jwb.newStreamWriter());
ex_aoss os; ex_aoss os;
@ -276,16 +275,13 @@ bool ts_web_rpc_session_begin(TS_CONNECT_INFO& info, int& record_id)
return false; return false;
} }
//Json::Reader jreader;
Json::Value jret; Json::Value jret;
//if (!jreader.parse(body.c_str(), jret))
Json::CharReaderBuilder jcrb; Json::CharReaderBuilder jcrb;
std::unique_ptr<Json::CharReader> const jreader(jcrb.newCharReader()); std::unique_ptr<Json::CharReader> const jreader(jcrb.newCharReader());
const char *str_json_begin = body.c_str(); const char *str_json_begin = body.c_str();
ex_astr err; ex_astr err;
//if (!jreader.parse(func_args.c_str(), jsRoot)) {
if (!jreader->parse(str_json_begin, str_json_begin + body.length(), &jret, &err)) if (!jreader->parse(str_json_begin, str_json_begin + body.length(), &jret, &err))
return false; return false;
if (!jret.isObject()) if (!jret.isObject())

View File

@ -4,78 +4,66 @@
#include <teleport_const.h> #include <teleport_const.h>
SshChannelPair::SshChannelPair(SshSession *_owner, ssh_channel _rsc_tp2cli, ssh_channel _rsc_tp2srv) : SshChannelPair::SshChannelPair(SshSession* _owner, uint32_t dbg_id, ssh_channel _rsc_tp2cli, ssh_channel _rsc_tp2srv) :
m_owner(_owner), m_owner(_owner),
rsc_tp2cli(_rsc_tp2cli), m_dbg_id(dbg_id),
rsc_tp2srv(_rsc_tp2srv) type(TS_SSH_CHANNEL_TYPE_UNKNOWN),
{ win_width(0),
rsc_tp2cli(_rsc_tp2cli),
rsc_tp2srv(_rsc_tp2srv) {
last_access_timestamp = (ex_u32) time(nullptr); last_access_timestamp = (ex_u32) time(nullptr);
ex_strformat(m_dbg_name, 128, "%s-%d", m_owner->dbg_name().c_str(), dbg_id);
state = TP_SESS_STAT_RUNNING; state = TP_SESS_STAT_RUNNING;
db_id = 0; db_id = 0;
channel_id = 0;
win_width = 0;
is_first_server_data = true; is_first_server_data = true;
need_close = false; need_close = false;
m_is_cmd_mode = false;
m_recv_prompt = false;
m_client_last_char = 0;
m_pty_stat = PTY_STAT_NORMAL_WAIT_PROMPT; m_pty_stat = PTY_STAT_NORMAL_WAIT_PROMPT;
} }
SshChannelPair::~SshChannelPair() SshChannelPair::~SshChannelPair() = default;
{
}
void SshChannelPair::process_pty_data_from_client(const uint8_t *data, uint32_t len) void SshChannelPair::process_pty_data_from_client(const uint8_t* data, uint32_t len) {
{
if (data == nullptr || len == 0) if (data == nullptr || len == 0)
return; return;
if (len == 1) if (len == 1) {
{ if (data[0] == 0x0d) {
if (data[0] == 0x0d)
{
// 0x0d 回车键 // 0x0d 回车键
if (!m_cmd.empty()) if (!m_cmd.empty()) {
EXLOGD("[%s] CMD=[%s]\n", m_owner->dbg_name().c_str(), m_cmd.str().c_str()); // EXLOGD("[%s] CMD=[%s]\n", m_owner->dbg_name().c_str(), m_cmd.str().c_str());
rec.record_command(0, m_cmd.str());
}
m_cmd.reset(); m_cmd.reset();
m_pty_stat = PTY_STAT_NORMAL_WAIT_PROMPT; m_pty_stat = PTY_STAT_NORMAL_WAIT_PROMPT;
// EXLOGD("------ turn to PTY_STAT_NORMAL_WAIT_PROMPT, input single RETURN.\n"); // EXLOGD("------ turn to PTY_STAT_NORMAL_WAIT_PROMPT, input single RETURN.\n");
return; return;
} }
else if (data[0] == 0x03) else if (data[0] == 0x03) {
{
// 0x03 Ctrl-C // 0x03 Ctrl-C
m_pty_stat = PTY_STAT_NORMAL_WAIT_PROMPT; m_pty_stat = PTY_STAT_NORMAL_WAIT_PROMPT;
// EXLOGD("------ turn to PTY_STAT_NORMAL_WAIT_PROMPT, input Ctrl-C.\n"); // EXLOGD("------ turn to PTY_STAT_NORMAL_WAIT_PROMPT, input Ctrl-C.\n");
return; return;
} }
else if (data[0] == 0x09) else if (data[0] == 0x09) {
{
// 0x09 TAB键 // 0x09 TAB键
if (m_pty_stat == PTY_STAT_WAIT_CLIENT_INPUT || m_pty_stat == PTY_STAT_TAB_WAIT_PROMPT || m_pty_stat == PTY_STAT_TAB_PRESSED) if (m_pty_stat == PTY_STAT_WAIT_CLIENT_INPUT || m_pty_stat == PTY_STAT_TAB_WAIT_PROMPT || m_pty_stat == PTY_STAT_TAB_PRESSED) {
{
m_pty_stat = PTY_STAT_TAB_PRESSED; m_pty_stat = PTY_STAT_TAB_PRESSED;
// EXLOGD("------ turn to PTY_STAT_TAB_PRESSED, input TAB.\n"); // EXLOGD("------ turn to PTY_STAT_TAB_PRESSED, input TAB.\n");
return; return;
} }
} }
else if (data[0] == 0x7f) else if (data[0] == 0x7f) {
{
// 7f backspace 回删键 // 7f backspace 回删键
m_pty_stat = PTY_STAT_WAIT_SERVER_ECHO; m_pty_stat = PTY_STAT_WAIT_SERVER_ECHO;
// EXLOGD("------ turn to PTY_STAT_WAIT_SERVER_ECHO, input BACKSPACE.\n"); // EXLOGD("------ turn to PTY_STAT_WAIT_SERVER_ECHO, input BACKSPACE.\n");
return; return;
} }
} }
else if (len == 3) else if (len == 3) {
{ if (data[0] == 0x1b && data[1] == 0x5b && (data[2] == 0x41 || data[2] == 0x42 || data[2] == 0x43 || data[2] == 0x44)) {
if (data[0] == 0x1b && data[1] == 0x5b && (data[2] == 0x41 || data[2] == 0x42 || data[2] == 0x43 || data[2] == 0x44))
{
// 1b 5b 41 (上箭头) // 1b 5b 41 (上箭头)
// 1b 5b 42 (下箭头) // 1b 5b 42 (下箭头)
// 1b 5b 43 (右箭头) // 1b 5b 43 (右箭头)
@ -85,10 +73,8 @@ void SshChannelPair::process_pty_data_from_client(const uint8_t *data, uint32_t
return; return;
} }
} }
else if (len == 4) else if (len == 4) {
{ if (data[0] == 0x1b && data[1] == 0x5b && data[2] == 0x33 && data[3] == 0x7e) {
if (data[0] == 0x1b && data[1] == 0x5b && data[2] == 0x33 && data[3] == 0x7e)
{
// 1b 5b 33 7e (删除一个字符) // 1b 5b 33 7e (删除一个字符)
m_pty_stat = PTY_STAT_WAIT_SERVER_ECHO; m_pty_stat = PTY_STAT_WAIT_SERVER_ECHO;
// EXLOGD("------ turn to PTY_STAT_WAIT_SERVER_ECHO, input DEL.\n"); // EXLOGD("------ turn to PTY_STAT_WAIT_SERVER_ECHO, input DEL.\n");
@ -96,44 +82,36 @@ void SshChannelPair::process_pty_data_from_client(const uint8_t *data, uint32_t
} }
} }
if (len >= 512) if (len >= 512) {
{ if (m_pty_stat != PTY_STAT_EXEC_MULTI_LINE_CMD) {
if (m_pty_stat != PTY_STAT_EXEC_MULTI_LINE_CMD)
{
m_pty_stat = PTY_STAT_NORMAL_WAIT_PROMPT; m_pty_stat = PTY_STAT_NORMAL_WAIT_PROMPT;
// EXLOGD("------ turn to PTY_STAT_NORMAL_WAIT_PROMPT, input too large.\n"); // EXLOGD("------ turn to PTY_STAT_NORMAL_WAIT_PROMPT, input too large.\n");
} }
return; return;
} }
int return_count = 0; int return_count = 0;
bool valid_input = true; bool valid_input = true;
int offset = 0; int offset = 0;
int last_return_pos = 0; int last_return_pos = 0;
for (; offset < len;) for (; offset < len;) {
{
uint8_t ch = data[offset]; uint8_t ch = data[offset];
switch (ch) switch (ch) {
{
case 0x1b: case 0x1b:
if (offset + 1 < len) if (offset + 1 < len) {
{ if (data[offset + 1] == 0x5b) {
if (data[offset + 1] == 0x5b)
{
valid_input = false; valid_input = false;
break; break;
} }
} }
break; break;
case 0x0d: case 0x0d:return_count++;
return_count++;
last_return_pos = offset; last_return_pos = offset;
break; break;
default: default:break;
break;
} }
if (!valid_input) if (!valid_input)
@ -142,33 +120,29 @@ void SshChannelPair::process_pty_data_from_client(const uint8_t *data, uint32_t
offset++; offset++;
} }
if (!valid_input) if (!valid_input) {
{ if (m_pty_stat != PTY_STAT_EXEC_MULTI_LINE_CMD) {
if (m_pty_stat != PTY_STAT_EXEC_MULTI_LINE_CMD)
{
m_pty_stat = PTY_STAT_NORMAL_WAIT_PROMPT; m_pty_stat = PTY_STAT_NORMAL_WAIT_PROMPT;
// EXLOGD("------ turn to PTY_STAT_NORMAL_WAIT_PROMPT, input invalid.\n"); // EXLOGD("------ turn to PTY_STAT_NORMAL_WAIT_PROMPT, input invalid.\n");
} }
return; return;
} }
if (return_count > 0) if (return_count > 0) {
{ std::string tmp_cmd((const char*) data, last_return_pos + 1);
std::string tmp_cmd((const char *) data, last_return_pos + 1);
EXLOGD("[%s] Paste CMD=[%s]\n", m_owner->dbg_name().c_str(), tmp_cmd.c_str()); EXLOGD("[%s] Paste CMD=[%s]\n", m_owner->dbg_name().c_str(), tmp_cmd.c_str());
rec.record_command(1, tmp_cmd);
m_pty_stat = PTY_STAT_EXEC_MULTI_LINE_CMD; m_pty_stat = PTY_STAT_EXEC_MULTI_LINE_CMD;
// EXLOGD("------ turn to PTY_STAT_EXEC_MULTI_LINE_CMD, maybe paste.\n"); // EXLOGD("------ turn to PTY_STAT_EXEC_MULTI_LINE_CMD, maybe paste.\n");
} }
else else {
{
m_pty_stat = PTY_STAT_WAIT_SERVER_ECHO; m_pty_stat = PTY_STAT_WAIT_SERVER_ECHO;
// EXLOGD("------ turn to PTY_STAT_WAIT_SERVER_ECHO, input something.\n"); // EXLOGD("------ turn to PTY_STAT_WAIT_SERVER_ECHO, input something.\n");
} }
} }
void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t len) void SshChannelPair::process_pty_data_from_server(const uint8_t* data, uint32_t len) {
{
if (data == nullptr || len == 0) if (data == nullptr || len == 0)
return; return;
@ -176,32 +150,26 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t
if (m_pty_stat == PTY_STAT_NORMAL_WAIT_PROMPT if (m_pty_stat == PTY_STAT_NORMAL_WAIT_PROMPT
|| m_pty_stat == PTY_STAT_TAB_WAIT_PROMPT || m_pty_stat == PTY_STAT_TAB_WAIT_PROMPT
|| m_pty_stat == PTY_STAT_MULTI_CMD_WAIT_PROMPT || m_pty_stat == PTY_STAT_MULTI_CMD_WAIT_PROMPT
|| m_pty_stat == PTY_STAT_WAIT_SERVER_ECHO) || m_pty_stat == PTY_STAT_WAIT_SERVER_ECHO) {
{ if (_contains_cmd_prompt(data, len)) {
if (_contains_cmd_prompt(data, len))
{
contains_prompt = true; contains_prompt = true;
if (m_pty_stat == PTY_STAT_NORMAL_WAIT_PROMPT) if (m_pty_stat == PTY_STAT_NORMAL_WAIT_PROMPT) {
{
// EXLOGD("------ turn to PTY_STAT_WAIT_CLIENT_INPUT, recv prompt after exec.\n"); // EXLOGD("------ turn to PTY_STAT_WAIT_CLIENT_INPUT, recv prompt after exec.\n");
m_pty_stat = PTY_STAT_WAIT_CLIENT_INPUT; m_pty_stat = PTY_STAT_WAIT_CLIENT_INPUT;
return; return;
} }
else if (m_pty_stat == PTY_STAT_TAB_WAIT_PROMPT) else if (m_pty_stat == PTY_STAT_TAB_WAIT_PROMPT) {
{
// EXLOGD("------ turn to PTY_STAT_WAIT_CLIENT_INPUT, recv prompt after TAB.\n"); // EXLOGD("------ turn to PTY_STAT_WAIT_CLIENT_INPUT, recv prompt after TAB.\n");
m_pty_stat = PTY_STAT_WAIT_CLIENT_INPUT; m_pty_stat = PTY_STAT_WAIT_CLIENT_INPUT;
return; return;
} }
else if (m_pty_stat == PTY_STAT_MULTI_CMD_WAIT_PROMPT) else if (m_pty_stat == PTY_STAT_MULTI_CMD_WAIT_PROMPT) {
{
// EXLOGD("------ turn to PTY_STAT_MULTI_CMD_WAIT_PROMPT, recv prompt while multi-exec.\n"); // EXLOGD("------ turn to PTY_STAT_MULTI_CMD_WAIT_PROMPT, recv prompt while multi-exec.\n");
m_pty_stat = PTY_STAT_EXEC_MULTI_LINE_CMD; m_pty_stat = PTY_STAT_EXEC_MULTI_LINE_CMD;
return; return;
} }
else if (m_pty_stat == PTY_STAT_WAIT_SERVER_ECHO) else if (m_pty_stat == PTY_STAT_WAIT_SERVER_ECHO) {
{
// EXLOGD("------ turn to PTY_STAT_WAIT_CLIENT_INPUT, recv prompt while wait echo.\n"); // EXLOGD("------ turn to PTY_STAT_WAIT_CLIENT_INPUT, recv prompt while wait echo.\n");
m_pty_stat = PTY_STAT_WAIT_CLIENT_INPUT; m_pty_stat = PTY_STAT_WAIT_CLIENT_INPUT;
m_cmd.reset(); m_cmd.reset();
@ -210,46 +178,39 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t
} }
} }
if (!contains_prompt) if (!contains_prompt) {
{
if (m_pty_stat == PTY_STAT_NORMAL_WAIT_PROMPT if (m_pty_stat == PTY_STAT_NORMAL_WAIT_PROMPT
|| m_pty_stat == PTY_STAT_TAB_WAIT_PROMPT || m_pty_stat == PTY_STAT_TAB_WAIT_PROMPT
|| m_pty_stat == PTY_STAT_MULTI_CMD_WAIT_PROMPT) || m_pty_stat == PTY_STAT_MULTI_CMD_WAIT_PROMPT) {
{
return; return;
} }
} }
if (!( if (!(
m_pty_stat == PTY_STAT_WAIT_SERVER_ECHO m_pty_stat == PTY_STAT_WAIT_SERVER_ECHO
|| m_pty_stat == PTY_STAT_EXEC_MULTI_LINE_CMD || m_pty_stat == PTY_STAT_EXEC_MULTI_LINE_CMD
|| m_pty_stat == PTY_STAT_MULTI_CMD_WAIT_PROMPT || m_pty_stat == PTY_STAT_MULTI_CMD_WAIT_PROMPT
|| m_pty_stat == PTY_STAT_TAB_WAIT_PROMPT || m_pty_stat == PTY_STAT_TAB_WAIT_PROMPT
|| m_pty_stat == PTY_STAT_TAB_PRESSED || m_pty_stat == PTY_STAT_TAB_PRESSED
)) )) {
{
// EXLOGD("------ keep PTY_STAT, recv but not in ECHO or multi-cmd mode.\n"); // EXLOGD("------ keep PTY_STAT, recv but not in ECHO or multi-cmd mode.\n");
return; return;
} }
if (len > 512) if (len > 512) {
{
// EXLOGD("------ keep PTY_STAT, recv too large.\n"); // EXLOGD("------ keep PTY_STAT, recv too large.\n");
return; return;
} }
// 处理输入回显,合成最终的命令行字符串 // 处理输入回显,合成最终的命令行字符串
int offset = 0; int offset = 0;
bool esc_mode = false; bool esc_mode = false;
int esc_arg = 0; int esc_arg = 0;
for (; offset < len;) for (; offset < len;) {
{
uint8_t ch = data[offset]; uint8_t ch = data[offset];
if (esc_mode) if (esc_mode) {
{ switch (ch) {
switch (ch)
{
case '0': case '0':
case '1': case '1':
case '2': case '2':
@ -259,30 +220,24 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t
case '6': case '6':
case '7': case '7':
case '8': case '8':
case '9': case '9':esc_arg = esc_arg * 10 + (ch - '0');
esc_arg = esc_arg * 10 + (ch - '0');
break; break;
case 0x3f: case 0x3f:
case ';': case ';':
case '>': case '>':m_cmd.reset();
m_cmd.reset();
return; return;
case 0x4b: case 0x4b: { // 'K'
{ // 'K' if (0 == esc_arg) {
if (0 == esc_arg)
{
// 删除光标到行尾的字符串 // 删除光标到行尾的字符串
m_cmd.erase_to_end(); m_cmd.erase_to_end();
} }
else if (1 == esc_arg) else if (1 == esc_arg) {
{
// 删除从开始到光标处的字符串 // 删除从开始到光标处的字符串
m_cmd.erase_to_begin(); m_cmd.erase_to_begin();
} }
else if (2 == esc_arg) else if (2 == esc_arg) {
{
// 删除整行 // 删除整行
m_cmd.reset(); m_cmd.reset();
} }
@ -290,8 +245,7 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t
esc_mode = false; esc_mode = false;
break; break;
} }
case 0x43: case 0x43: {// ^[C
{// ^[C
// 光标右移 // 光标右移
if (esc_arg == 0) if (esc_arg == 0)
esc_arg = 1; esc_arg = 1;
@ -299,8 +253,7 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t
esc_mode = false; esc_mode = false;
break; break;
} }
case 0x44: case 0x44: { // ^[D
{ // ^[D
// 光标左移 // 光标左移
if (esc_arg == 0) if (esc_arg == 0)
esc_arg = 1; esc_arg = 1;
@ -309,8 +262,7 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t
break; break;
} }
case 0x50: case 0x50: {
{
// 'P' 删除指定数量的字符 // 'P' 删除指定数量的字符
if (esc_arg == 0) if (esc_arg == 0)
esc_arg = 1; esc_arg = 1;
@ -319,8 +271,7 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t
break; break;
} }
case 0x40: case 0x40: { // '@' 插入指定数量的空白字符
{ // '@' 插入指定数量的空白字符
if (esc_arg == 0) if (esc_arg == 0)
esc_arg = 1; esc_arg = 1;
m_cmd.insert_white_space(esc_arg); m_cmd.insert_white_space(esc_arg);
@ -328,8 +279,7 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t
break; break;
} }
default: default:esc_mode = false;
esc_mode = false;
break; break;
} }
@ -337,25 +287,20 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t
continue; continue;
} }
switch (ch) switch (ch) {
{
case 0x07: case 0x07:
// 响铃 // 响铃
break; break;
case 0x08: case 0x08: {
{
// 光标左移 // 光标左移
m_cmd.cursor_move_left(1); m_cmd.cursor_move_left(1);
break; break;
} }
case 0x1b: case 0x1b: {
{ if (offset + 1 < len) {
if (offset + 1 < len) if (data[offset + 1] == 0x5b) {
{
if (data[offset + 1] == 0x5b)
{
esc_mode = true; esc_mode = true;
esc_arg = 0; esc_arg = 0;
offset += 1; offset += 1;
} }
@ -363,12 +308,9 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t
break; break;
} }
case 0x0d: case 0x0d: {
{ if (offset + 1 < len && data[offset + 1] == 0x0a) {
if (offset + 1 < len && data[offset + 1] == 0x0a) if (m_pty_stat == PTY_STAT_EXEC_MULTI_LINE_CMD) {
{
if (m_pty_stat == PTY_STAT_EXEC_MULTI_LINE_CMD)
{
if (!m_cmd.empty()) if (!m_cmd.empty())
EXLOGD("[%s] one of multi-cmd, CMD=[%s]\n", m_owner->dbg_name().c_str(), m_cmd.str().c_str()); EXLOGD("[%s] one of multi-cmd, CMD=[%s]\n", m_owner->dbg_name().c_str(), m_cmd.str().c_str());
m_cmd.reset(); m_cmd.reset();
@ -376,14 +318,12 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t
m_pty_stat = PTY_STAT_MULTI_CMD_WAIT_PROMPT; m_pty_stat = PTY_STAT_MULTI_CMD_WAIT_PROMPT;
// EXLOGD("------ turn to PTY_STAT_MULTI_CMD_WAIT_PROMPT, recv 0x0d0a after multi-exec.\n"); // EXLOGD("------ turn to PTY_STAT_MULTI_CMD_WAIT_PROMPT, recv 0x0d0a after multi-exec.\n");
if (_contains_cmd_prompt(data, len)) if (_contains_cmd_prompt(data, len)) {
{
m_pty_stat = PTY_STAT_EXEC_MULTI_LINE_CMD; m_pty_stat = PTY_STAT_EXEC_MULTI_LINE_CMD;
// EXLOGD("------ turn to PTY_STAT_EXEC_MULTI_LINE_CMD, recv prompt after multi-exec.\n"); // EXLOGD("------ turn to PTY_STAT_EXEC_MULTI_LINE_CMD, recv prompt after multi-exec.\n");
} }
} }
else if (m_pty_stat == PTY_STAT_TAB_PRESSED) else if (m_pty_stat == PTY_STAT_TAB_PRESSED) {
{
m_pty_stat = PTY_STAT_TAB_WAIT_PROMPT; m_pty_stat = PTY_STAT_TAB_WAIT_PROMPT;
// EXLOGD("------ turn to PTY_STAT_TAB_WAIT_PROMPT, recv 0d0a after TAB pressed.\n"); // EXLOGD("------ turn to PTY_STAT_TAB_WAIT_PROMPT, recv 0d0a after TAB pressed.\n");
} }
@ -392,10 +332,8 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t
break; break;
} }
default: default:m_cmd.replace(ch);
m_cmd.replace(ch); if (m_pty_stat == PTY_STAT_WAIT_SERVER_ECHO) {
if (m_pty_stat == PTY_STAT_WAIT_SERVER_ECHO)
{
m_pty_stat = PTY_STAT_WAIT_CLIENT_INPUT; m_pty_stat = PTY_STAT_WAIT_CLIENT_INPUT;
// EXLOGD("------ turn to PTY_STAT_WAIT_CLIENT_INPUT, recv something.\n"); // EXLOGD("------ turn to PTY_STAT_WAIT_CLIENT_INPUT, recv something.\n");
} }
@ -405,15 +343,13 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t
offset++; offset++;
} }
if (m_pty_stat == PTY_STAT_MULTI_CMD_WAIT_PROMPT && contains_prompt) if (m_pty_stat == PTY_STAT_MULTI_CMD_WAIT_PROMPT && contains_prompt) {
{
m_pty_stat = PTY_STAT_EXEC_MULTI_LINE_CMD; m_pty_stat = PTY_STAT_EXEC_MULTI_LINE_CMD;
// EXLOGD("------ turn to PTY_STAT_EXEC_MULTI_LINE_CMD, recv prompt.\n"); // EXLOGD("------ turn to PTY_STAT_EXEC_MULTI_LINE_CMD, recv prompt.\n");
} }
} }
bool SshChannelPair::_contains_cmd_prompt(const uint8_t *data, uint32_t len) bool SshChannelPair::_contains_cmd_prompt(const uint8_t* data, uint32_t len) {
{
// 正常情况下收到的服务端数据一包数据不会太大可以考虑限定在512字节范围内从后向前查找 0x07它的位置 // 正常情况下收到的服务端数据一包数据不会太大可以考虑限定在512字节范围内从后向前查找 0x07它的位置
// 应该位于倒数256字节范围内这之后的数据可能是命令行提示符的内容了不会太长的。继续向前找应该能够找到正 // 应该位于倒数256字节范围内这之后的数据可能是命令行提示符的内容了不会太长的。继续向前找应该能够找到正
// 序为 1b 5d 30/31/32/33 3b ... 直到刚才的 07。满足这样格式的99%可能处于命令行模式了还有1%可能是Mac // 序为 1b 5d 30/31/32/33 3b ... 直到刚才的 07。满足这样格式的99%可能处于命令行模式了还有1%可能是Mac
@ -434,21 +370,19 @@ bool SshChannelPair::_contains_cmd_prompt(const uint8_t *data, uint32_t len)
bool found_0x07 = false; bool found_0x07 = false;
bool found_0x3b = false; bool found_0x3b = false;
bool found_Ps = false; bool found_Ps = false;
bool found_0x5d = false; bool found_0x5d = false;
int offset = static_cast<int>(len) - 1; int offset = static_cast<int>(len) - 1;
for (int i = 0; offset >= 0; i++) for (int i = 0; offset >= 0; i++) {
{
if (i > 256) if (i > 256)
return false; return false;
if (found_0x5d) if (found_0x5d)
return (data[offset] == 0x1b); return (data[offset] == 0x1b);
if (found_Ps) if (found_Ps) {
{
found_0x5d = (data[offset] == 0x5d); found_0x5d = (data[offset] == 0x5d);
if (!found_0x5d) if (!found_0x5d)
return false; return false;
@ -456,8 +390,7 @@ bool SshChannelPair::_contains_cmd_prompt(const uint8_t *data, uint32_t len)
continue; continue;
} }
if (found_0x3b) if (found_0x3b) {
{
found_Ps = (data[offset] == 0x30 || data[offset] == 0x31 || data[offset] == 0x32); found_Ps = (data[offset] == 0x30 || data[offset] == 0x31 || data[offset] == 0x32);
if (!found_Ps) if (!found_Ps)
return false; return false;
@ -465,8 +398,7 @@ bool SshChannelPair::_contains_cmd_prompt(const uint8_t *data, uint32_t len)
continue; continue;
} }
if (!found_0x07) if (!found_0x07) {
{
found_0x07 = (data[offset] == 0x07); found_0x07 = (data[offset] == 0x07);
offset--; offset--;
continue; continue;
@ -479,8 +411,7 @@ bool SshChannelPair::_contains_cmd_prompt(const uint8_t *data, uint32_t len)
return false; return false;
} }
void SshChannelPair::process_sftp_command(ssh_channel ch, const uint8_t *data, uint32_t len) void SshChannelPair::process_sftp_command(ssh_channel ch, const uint8_t* data, uint32_t len) {
{
// SFTP protocol: https://tools.ietf.org/html/draft-ietf-secsh-filexfer-13 // SFTP protocol: https://tools.ietf.org/html/draft-ietf-secsh-filexfer-13
// EXLOG_BIN(data, len, "[sftp] client channel data"); // EXLOG_BIN(data, len, "[sftp] client channel data");
@ -502,8 +433,7 @@ void SshChannelPair::process_sftp_command(ssh_channel ch, const uint8_t *data, u
ex_u8 sftp_cmd = data[4]; ex_u8 sftp_cmd = data[4];
if (sftp_cmd == 0x01) if (sftp_cmd == 0x01) {
{
// 0x01 = 1 = SSH_FXP_INIT // 0x01 = 1 = SSH_FXP_INIT
rec.record_command(0, "SFTP INITIALIZE\r\n"); rec.record_command(0, "SFTP INITIALIZE\r\n");
EXLOGD("[sftp-%s] SFTP INITIALIZE\n", m_owner->dbg_name().c_str()); EXLOGD("[sftp-%s] SFTP INITIALIZE\n", m_owner->dbg_name().c_str());
@ -516,16 +446,15 @@ void SshChannelPair::process_sftp_command(ssh_channel ch, const uint8_t *data, u
if (len < 14) if (len < 14)
return; return;
ex_u8 *str1_ptr = (ex_u8 *) data + 9; ex_u8* str1_ptr = (ex_u8*) data + 9;
int str1_len = (int) ((str1_ptr[0] << 24) | (str1_ptr[1] << 16) | (str1_ptr[2] << 8) | str1_ptr[3]); int str1_len = (int) ((str1_ptr[0] << 24) | (str1_ptr[1] << 16) | (str1_ptr[2] << 8) | str1_ptr[3]);
// if (str1_len + 9 != pkg_len) // if (str1_len + 9 != pkg_len)
// return; // return;
ex_u8 *str2_ptr = nullptr;// (ex_u8*)data + 13; ex_u8* str2_ptr = nullptr;// (ex_u8*)data + 13;
int str2_len = 0;// (int)((data[9] << 24) | (data[10] << 16) | (data[11] << 8) | data[12]); int str2_len = 0;// (int)((data[9] << 24) | (data[10] << 16) | (data[11] << 8) | data[12]);
switch (sftp_cmd) switch (sftp_cmd) {
{
case 0x03: case 0x03:
// 0x03 = 3 = SSH_FXP_OPEN // 0x03 = 3 = SSH_FXP_OPEN
EXLOGD("[sftp-%s] SSH_FXP_OPEN\n", m_owner->dbg_name().c_str()); EXLOGD("[sftp-%s] SSH_FXP_OPEN\n", m_owner->dbg_name().c_str());
@ -560,8 +489,7 @@ void SshChannelPair::process_sftp_command(ssh_channel ch, const uint8_t *data, u
str2_len = (int) ((str2_ptr[0] << 24) | (str2_ptr[1] << 16) | (str2_ptr[2] << 8) | str2_ptr[3]); str2_len = (int) ((str2_ptr[0] << 24) | (str2_ptr[1] << 16) | (str2_ptr[2] << 8) | str2_ptr[3]);
EXLOGD("[sftp-%s] SSH_FXP_LINK\n", m_owner->dbg_name().c_str()); EXLOGD("[sftp-%s] SSH_FXP_LINK\n", m_owner->dbg_name().c_str());
break; break;
default: default:return;
return;
} }
int total_len = 5 + str1_len + 4; int total_len = 5 + str1_len + 4;
@ -570,16 +498,14 @@ void SshChannelPair::process_sftp_command(ssh_channel ch, const uint8_t *data, u
if (total_len > pkg_len) if (total_len > pkg_len)
return; return;
char msg[2048] = { 0 }; char msg[2048] = {0};
if (str2_len == 0) if (str2_len == 0) {
{ ex_astr str1((char*) ((ex_u8*) data + 13), str1_len);
ex_astr str1((char *) ((ex_u8 *) data + 13), str1_len);
ex_strformat(msg, 2048, "%d,%d,%s", sftp_cmd, 0, str1.c_str()); ex_strformat(msg, 2048, "%d,%d,%s", sftp_cmd, 0, str1.c_str());
} }
else else {
{ ex_astr str1((char*) (str1_ptr + 4), str1_len);
ex_astr str1((char *) (str1_ptr + 4), str1_len); ex_astr str2((char*) (str2_ptr + 4), str2_len);
ex_astr str2((char *) (str2_ptr + 4), str2_len);
ex_strformat(msg, 2048, "%d,%d,%s:%s", sftp_cmd, 0, str1.c_str(), str2.c_str()); ex_strformat(msg, 2048, "%d,%d,%s:%s", sftp_cmd, 0, str1.c_str(), str2.c_str());
} }
@ -587,21 +513,20 @@ void SshChannelPair::process_sftp_command(ssh_channel ch, const uint8_t *data, u
rec.record_command(0, msg); rec.record_command(0, msg);
} }
bool SshChannelPair::record_begin(const TPP_CONNECT_INFO *conn_info) bool SshChannelPair::record_begin(const TPP_CONNECT_INFO* conn_info) {
{
#ifndef TEST_SSH_SESSION_000000 #ifndef TEST_SSH_SESSION_000000
if (!g_ssh_env.session_begin(conn_info, &db_id)) { if (!g_ssh_env.session_begin(conn_info, &db_id)) {
EXLOGE("[ssh] can not save to database, channel begin failed.\n"); EXLOGE("[%s] can not save to database, channel begin failed.\n", m_dbg_name.c_str());
return false; return false;
} }
else { // else {
channel_id = db_id; // channel_id = db_id;
// EXLOGD("[ssh] [channel:%d] channel begin\n", cp->channel_id); // // EXLOGD("[ssh] [channel:%d] channel begin\n", cp->channel_id);
} // }
if (!g_ssh_env.session_update(db_id, conn_info->protocol_sub_type, TP_SESS_STAT_STARTED)) { if (!g_ssh_env.session_update(db_id, conn_info->protocol_sub_type, TP_SESS_STAT_STARTED)) {
EXLOGE("[ssh] [channel:%d] can not update state, cannel begin failed.\n", channel_id); EXLOGE("[%s] can not update state, cannel begin failed.\n", m_dbg_name.c_str());
return false; return false;
} }
@ -611,11 +536,10 @@ bool SshChannelPair::record_begin(const TPP_CONNECT_INFO *conn_info)
return true; return true;
} }
void SshChannelPair::record_end() void SshChannelPair::record_end() {
{
#ifndef TEST_SSH_SESSION_000000 #ifndef TEST_SSH_SESSION_000000
if (db_id > 0) { if (db_id > 0) {
// EXLOGD("[ssh] [channel:%d] channel end with code: %d\n", cp->channel_id, cp->state); EXLOGD("[%s] channel end with code: %d\n", m_dbg_name.c_str(), state);
// 如果会话过程中没有发生错误,则将其状态改为结束,否则记录下错误值 // 如果会话过程中没有发生错误,则将其状态改为结束,否则记录下错误值
if (state == TP_SESS_STAT_RUNNING || state == TP_SESS_STAT_STARTED) if (state == TP_SESS_STAT_RUNNING || state == TP_SESS_STAT_STARTED)
@ -626,7 +550,7 @@ void SshChannelPair::record_end()
db_id = 0; db_id = 0;
} }
else { else {
// EXLOGD("[ssh] [channel:%d] when channel end, no db-id.\n", cp->channel_id); EXLOGD("[%s] when channel end, no db-id.\n", m_dbg_name.c_str());
} }
#endif #endif
} }
@ -636,17 +560,13 @@ void SshChannelPair::record_end()
// SshCommand // SshCommand
// ================================================== // ==================================================
SshCommand::SshCommand() SshCommand::SshCommand() {
{
m_cmd.clear(); m_cmd.clear();
m_pos = m_cmd.begin(); m_pos = m_cmd.begin();
} }
SshCommand::~SshCommand() SshCommand::~SshCommand() = default;
{
}
void SshCommand::_dump(const char *msg) void SshCommand::_dump(const char* msg) {
{
// EXLOGD("CMD-BUFFER: %s [%s]\n", msg, str().c_str()); // EXLOGD("CMD-BUFFER: %s [%s]\n", msg, str().c_str());
} }

View File

@ -8,53 +8,46 @@
class SshSession; class SshSession;
class SshCommand class SshCommand {
{
public: public:
SshCommand(); SshCommand();
virtual ~SshCommand(); virtual ~SshCommand();
void reset() void reset() {
{
m_cmd.clear(); m_cmd.clear();
m_pos = m_cmd.end(); m_pos = m_cmd.end();
_dump("reset"); _dump("reset");
} }
std::string str() std::string str() {
{
if (empty()) if (empty())
return ""; return "";
else else
return std::string(m_cmd.begin(), m_cmd.end()); return std::string(m_cmd.begin(), m_cmd.end());
} }
bool empty() const bool empty() const {
{
return m_cmd.empty(); return m_cmd.empty();
} }
void erase_to_end() void erase_to_end() {
{
// 删除光标到行尾的字符串 // 删除光标到行尾的字符串
m_cmd.erase(m_pos, m_cmd.end()); m_cmd.erase(m_pos, m_cmd.end());
m_pos = m_cmd.end(); m_pos = m_cmd.end();
_dump("erase to end"); _dump("erase to end");
} }
void erase_to_begin() void erase_to_begin() {
{
// 删除从开始到光标处的字符串 // 删除从开始到光标处的字符串
m_cmd.erase(m_cmd.begin(), m_pos); m_cmd.erase(m_cmd.begin(), m_pos);
m_pos = m_cmd.begin(); m_pos = m_cmd.begin();
_dump("erase to begin"); _dump("erase to begin");
} }
void cursor_move_right(int count) void cursor_move_right(int count) {
{
// 光标右移 // 光标右移
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i) {
{
if (m_pos != m_cmd.end()) if (m_pos != m_cmd.end())
m_pos++; m_pos++;
else else
@ -63,11 +56,9 @@ public:
_dump("cursor move right"); _dump("cursor move right");
} }
void cursor_move_left(int count) void cursor_move_left(int count) {
{
// 光标左移 // 光标左移
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i) {
{
if (m_pos != m_cmd.begin()) if (m_pos != m_cmd.begin())
m_pos--; m_pos--;
else else
@ -76,11 +67,9 @@ public:
_dump("cursor move left"); _dump("cursor move left");
} }
void erase_chars(int count) void erase_chars(int count) {
{
// 删除指定数量的字符 // 删除指定数量的字符
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i) {
{
if (m_pos != m_cmd.end()) if (m_pos != m_cmd.end())
m_pos = m_cmd.erase(m_pos); m_pos = m_cmd.erase(m_pos);
else else
@ -89,26 +78,21 @@ public:
_dump("erase char"); _dump("erase char");
} }
void insert_white_space(int count) void insert_white_space(int count) {
{
// 插入指定数量的空白字符 // 插入指定数量的空白字符
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i) {
{
m_pos = m_cmd.insert(m_pos, ' '); m_pos = m_cmd.insert(m_pos, ' ');
} }
_dump("insert white space"); _dump("insert white space");
} }
void replace(uint8_t ch) void replace(uint8_t ch) {
{ if (m_pos != m_cmd.end()) {
if (m_pos != m_cmd.end())
{
m_pos = m_cmd.erase(m_pos); m_pos = m_cmd.erase(m_pos);
m_pos = m_cmd.insert(m_pos, ch); m_pos = m_cmd.insert(m_pos, ch);
m_pos++; m_pos++;
} }
else else {
{
m_cmd.push_back(ch); m_cmd.push_back(ch);
//cmd_char_pos = cmd_char_list.end(); //cmd_char_pos = cmd_char_list.end();
m_pos = m_cmd.end(); m_pos = m_cmd.end();
@ -116,17 +100,13 @@ public:
_dump("replace char"); _dump("replace char");
} }
void insert(const uint8_t *data, int len) void insert(const uint8_t* data, int len) {
{ for (int i = 0; i < len; ++i) {
for (int i = 0; i < len; ++i) if (m_pos == m_cmd.end()) {
{
if (m_pos == m_cmd.end())
{
m_cmd.push_back(data[i]); m_cmd.push_back(data[i]);
m_pos = m_cmd.end(); m_pos = m_cmd.end();
} }
else else {
{
m_pos = m_cmd.insert(m_pos, data[i]); m_pos = m_cmd.insert(m_pos, data[i]);
m_pos++; m_pos++;
} }
@ -134,15 +114,12 @@ public:
_dump("insert chars"); _dump("insert chars");
} }
void insert(uint8_t ch) void insert(uint8_t ch) {
{ if (m_pos == m_cmd.end()) {
if (m_pos == m_cmd.end())
{
m_cmd.push_back(ch); m_cmd.push_back(ch);
m_pos = m_cmd.end(); m_pos = m_cmd.end();
} }
else else {
{
m_pos = m_cmd.insert(m_pos, ch); m_pos = m_cmd.insert(m_pos, ch);
m_pos++; m_pos++;
} }
@ -150,16 +127,15 @@ public:
} }
protected: protected:
void _dump(const char *msg); void _dump(const char* msg);
private: private:
std::list<char> m_cmd; std::list<char> m_cmd;
std::list<char>::iterator m_pos; std::list<char>::iterator m_pos;
}; };
// SSH命令解析有限状态机状态值 // SSH命令解析有限状态机状态值
enum PTY_STAT enum PTY_STAT {
{
PTY_STAT_NORMAL_WAIT_PROMPT = 0, PTY_STAT_NORMAL_WAIT_PROMPT = 0,
PTY_STAT_MULTI_CMD_WAIT_PROMPT, PTY_STAT_MULTI_CMD_WAIT_PROMPT,
PTY_STAT_TAB_PRESSED, PTY_STAT_TAB_PRESSED,
@ -170,35 +146,37 @@ enum PTY_STAT
}; };
class SshChannelPair class SshChannelPair {
{
friend class SshSession; friend class SshSession;
public: public:
SshChannelPair(SshSession *owner, ssh_channel rsc_tp2cli, ssh_channel rsc_tp2srv); SshChannelPair(SshSession* owner, uint32_t dbg_id, ssh_channel rsc_tp2cli, ssh_channel rsc_tp2srv);
virtual ~SshChannelPair(); virtual ~SshChannelPair();
void process_pty_data_from_client(const uint8_t *data, uint32_t len); void process_pty_data_from_client(const uint8_t* data, uint32_t len);
void process_pty_data_from_server(const uint8_t *data, uint32_t len);
void process_pty_data_from_server(const uint8_t* data, uint32_t len);
void process_sftp_command(ssh_channel ch, const uint8_t *data, uint32_t len); void process_sftp_command(ssh_channel ch, const uint8_t* data, uint32_t len);
// when client<->server channel created, start to record. // when client<->server channel created, start to record.
bool record_begin(const TPP_CONNECT_INFO *conn_info); bool record_begin(const TPP_CONNECT_INFO* conn_info);
// stop record because channel closed. // stop record because channel closed.
void record_end(); void record_end();
protected: protected:
bool _contains_cmd_prompt(const uint8_t *data, uint32_t len); bool _contains_cmd_prompt(const uint8_t* data, uint32_t len);
protected: protected:
SshSession *m_owner; SshSession* m_owner;
uint32_t m_dbg_id;
std::string m_dbg_name;
int win_width; // window width, in char count.
int type; // TS_SSH_CHANNEL_TYPE_SHELL or TS_SSH_CHANNEL_TYPE_SFTP int type; // TS_SSH_CHANNEL_TYPE_SHELL or TS_SSH_CHANNEL_TYPE_SFTP
int win_width; // window width, in char count.
ssh_channel rsc_tp2cli; ssh_channel rsc_tp2cli;
ssh_channel rsc_tp2srv; ssh_channel rsc_tp2srv;
@ -206,28 +184,18 @@ protected:
uint32_t last_access_timestamp; uint32_t last_access_timestamp;
TppSshRec rec; TppSshRec rec;
int db_id; int db_id;
int state; int state;
int channel_id; // for debug only.
bool is_first_server_data; bool is_first_server_data;
bool need_close; bool need_close;
// 是否处于命令行输入模式
bool m_is_cmd_mode;
bool m_recv_prompt;
uint8_t m_client_last_char;
SshCommand m_cmd; SshCommand m_cmd;
// uint32_t m_input_flag;
// std::vector<uint8_t> m_last_input;
PTY_STAT m_pty_stat; PTY_STAT m_pty_stat;
}; };
typedef std::list<SshChannelPair *> TPChannelPairs; typedef std::list<SshChannelPair*> TPChannelPairs;
typedef std::map<ssh_channel, SshChannelPair *> channel_map; typedef std::map<ssh_channel, SshChannelPair*> channel_map;
#endif //__SSH_CHANNEL_PAIR_H__ #endif //__SSH_CHANNEL_PAIR_H__

View File

@ -4,46 +4,39 @@
SshProxy g_ssh_proxy; SshProxy g_ssh_proxy;
SshProxy::SshProxy() noexcept: SshProxy::SshProxy() noexcept:
ExThreadBase("ssh-proxy-thread"), ExThreadBase("ssh-proxy-thread"),
m_bind(nullptr), m_bind(nullptr),
m_host_port(0) m_host_port(0) {
{
m_timer_counter_check_noop = 0; m_timer_counter_check_noop = 0;
m_timer_counter_keep_alive = 0; m_timer_counter_keep_alive = 0;
m_noop_timeout_sec = 0;//900; // default to 15 minutes. m_noop_timeout_sec = 0;//900; // default to 15 minutes.
m_listener_running = false; m_listener_running = false;
m_dbg_id = 0; m_dbg_id = 0;
} }
SshProxy::~SshProxy() SshProxy::~SshProxy() {
{ if (m_bind) {
if (m_bind)
{
ssh_bind_free(m_bind); ssh_bind_free(m_bind);
m_bind = nullptr; m_bind = nullptr;
} }
} }
bool SshProxy::init() bool SshProxy::init() {
{ m_host_ip = g_ssh_env.bind_ip;
m_host_ip = g_ssh_env.bind_ip;
m_host_port = g_ssh_env.bind_port; m_host_port = g_ssh_env.bind_port;
m_bind = ssh_bind_new(); m_bind = ssh_bind_new();
if (!m_bind) if (!m_bind) {
{
EXLOGE("[ssh] can not create bind.\n"); EXLOGE("[ssh] can not create bind.\n");
return false; return false;
} }
if (SSH_OK != ssh_bind_options_set(m_bind, SSH_BIND_OPTIONS_BINDADDR, m_host_ip.c_str())) if (SSH_OK != ssh_bind_options_set(m_bind, SSH_BIND_OPTIONS_BINDADDR, m_host_ip.c_str())) {
{
EXLOGE("[ssh] can not set bind option: SSH_BIND_OPTIONS_BINDADDR.\n"); EXLOGE("[ssh] can not set bind option: SSH_BIND_OPTIONS_BINDADDR.\n");
return false; return false;
} }
if (SSH_OK != ssh_bind_options_set(m_bind, SSH_BIND_OPTIONS_BINDPORT, &m_host_port)) if (SSH_OK != ssh_bind_options_set(m_bind, SSH_BIND_OPTIONS_BINDPORT, &m_host_port)) {
{
EXLOGE("[ssh] can not set bind option: SSH_BIND_OPTIONS_BINDPORT.\n"); EXLOGE("[ssh] can not set bind option: SSH_BIND_OPTIONS_BINDPORT.\n");
return false; return false;
} }
@ -53,15 +46,13 @@ bool SshProxy::init()
ex_astr key_file; ex_astr key_file;
ex_wstr2astr(_key_file, key_file); ex_wstr2astr(_key_file, key_file);
EXLOGV("[ssh] try to load ssh-server-key: %s\n", key_file.c_str()); EXLOGI("[ssh] loading ssh-server-key: %s\n", key_file.c_str());
if (SSH_OK != ssh_bind_options_set(m_bind, SSH_BIND_OPTIONS_RSAKEY, key_file.c_str())) if (SSH_OK != ssh_bind_options_set(m_bind, SSH_BIND_OPTIONS_RSAKEY, key_file.c_str())) {
{
EXLOGE("[ssh] can not set bind option: SSH_BIND_OPTIONS_RSAKEY.\n"); EXLOGE("[ssh] can not set bind option: SSH_BIND_OPTIONS_RSAKEY.\n");
return false; return false;
} }
if (ssh_bind_listen(m_bind) < 0) if (ssh_bind_listen(m_bind) < 0) {
{
EXLOGE("[ssh] can not listen on port %d: %s\n", m_host_port, ssh_get_error(m_bind)); EXLOGE("[ssh] can not listen on port %d: %s\n", m_host_port, ssh_get_error(m_bind));
return false; return false;
} }
@ -69,8 +60,7 @@ bool SshProxy::init()
return true; return true;
} }
void SshProxy::timer() void SshProxy::timer() {
{
// timer() will be called per one second by tp_core main thread. // timer() will be called per one second by tp_core main thread.
m_timer_counter_check_noop++; m_timer_counter_check_noop++;
@ -78,18 +68,15 @@ void SshProxy::timer()
{ {
ExThreadSmartLock locker(m_lock); ExThreadSmartLock locker(m_lock);
for (auto it = m_sessions.begin(); it != m_sessions.end();) for (auto it = m_sessions.begin(); it != m_sessions.end();) {
{
// 检查通道是否已经关闭 // 检查通道是否已经关闭
it->first->check_channels(); it->first->check_channels();
// 检查会话是否已经关闭,如果会话已经完全关闭,则销毁之 // 检查会话是否已经关闭,如果会话已经完全关闭,则销毁之
if (it->first->closed()) if (it->first->closed()) {
{
delete it->first; delete it->first;
m_sessions.erase(it++); m_sessions.erase(it++);
} }
else else {
{
++it; ++it;
} }
} }
@ -99,15 +86,13 @@ void SshProxy::timer()
} }
// check no-op per 5 seconds. // check no-op per 5 seconds.
if (m_timer_counter_check_noop >= 5) if (m_timer_counter_check_noop >= 5) {
{
auto t_now = (ex_u32) time(nullptr); auto t_now = (ex_u32) time(nullptr);
m_timer_counter_check_noop = 0; m_timer_counter_check_noop = 0;
ExThreadSmartLock locker(m_lock); ExThreadSmartLock locker(m_lock);
for (auto &session : m_sessions) for (auto& session : m_sessions) {
{
session.first->save_record(); session.first->save_record();
if (0 != m_noop_timeout_sec) if (0 != m_noop_timeout_sec)
session.first->check_noop_timeout(t_now, m_noop_timeout_sec); session.first->check_noop_timeout(t_now, m_noop_timeout_sec);
@ -115,21 +100,16 @@ void SshProxy::timer()
} }
} }
void SshProxy::set_cfg(ex_u32 noop_timeout) void SshProxy::set_cfg(ex_u32 noop_timeout) {
{
m_noop_timeout_sec = noop_timeout; m_noop_timeout_sec = noop_timeout;
} }
void SshProxy::kill_sessions(const ex_astrs &sessions) void SshProxy::kill_sessions(const ex_astrs& sessions) {
{
ExThreadSmartLock locker(m_lock); ExThreadSmartLock locker(m_lock);
for (auto &session : m_sessions) for (auto& session : m_sessions) {
{ for (const auto& sid : sessions) {
for (const auto &sid : sessions) if (session.first->sid() == sid) {
{
if (session.first->sid() == sid)
{
EXLOGW("[ssh] kill session %s\n", sid.c_str()); EXLOGW("[ssh] kill session %s\n", sid.c_str());
session.first->check_noop_timeout(0, 0); // 立即结束 session.first->check_noop_timeout(0, 0); // 立即结束
break; break;
@ -138,14 +118,12 @@ void SshProxy::kill_sessions(const ex_astrs &sessions)
} }
} }
void SshProxy::_thread_loop() void SshProxy::_thread_loop() {
{
EXLOGI("[ssh] TeleportServer-SSH ready on %s:%d\n", m_host_ip.c_str(), m_host_port); EXLOGI("[ssh] TeleportServer-SSH ready on %s:%d\n", m_host_ip.c_str(), m_host_port);
m_listener_running = true; m_listener_running = true;
for (;;) for (;;) {
{
ssh_session rs_tp2cli = ssh_new(); ssh_session rs_tp2cli = ssh_new();
// #ifdef EX_DEBUG // #ifdef EX_DEBUG
@ -153,39 +131,36 @@ void SshProxy::_thread_loop()
// ssh_options_set(rs_tp2cli, SSH_OPTIONS_LOG_VERBOSITY, &flag); // ssh_options_set(rs_tp2cli, SSH_OPTIONS_LOG_VERBOSITY, &flag);
// #endif // #endif
if (ssh_bind_accept(m_bind, rs_tp2cli) != SSH_OK) if (ssh_bind_accept(m_bind, rs_tp2cli) != SSH_OK) {
{
EXLOGE("[ssh] accepting a connection failed: %s.\n", ssh_get_error(m_bind)); EXLOGE("[ssh] accepting a connection failed: %s.\n", ssh_get_error(m_bind));
continue; continue;
} }
EXLOGD("[ssh] ssh_bind_accept() returned...\n"); EXLOGD("[ssh] ssh_bind_accept() returned...\n");
if (m_need_stop) if (m_need_stop) {
{
ssh_free(rs_tp2cli); ssh_free(rs_tp2cli);
break; break;
} }
struct sockaddr_storage sock_client{}; struct sockaddr_storage sock_client{};
char ip[32] = { 0 }; char ip[32] = {0};
int len = sizeof(ip); int len = sizeof(ip);
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
getpeername(ssh_get_fd(rs_tp2cli), (struct sockaddr *) &sock_client, &len); getpeername(ssh_get_fd(rs_tp2cli), (struct sockaddr *) &sock_client, &len);
#else #else
getpeername(ssh_get_fd(rs_tp2cli), (struct sockaddr *) &sock_client, (unsigned int *) &len); getpeername(ssh_get_fd(rs_tp2cli), (struct sockaddr*) &sock_client, (unsigned int*) &len);
#endif #endif
auto addr = (sockaddr_in *) &sock_client; auto addr = (sockaddr_in*) &sock_client;
if (0 != ex_ip4_name(addr, ip, sizeof(ip))) if (0 != ex_ip4_name(addr, ip, sizeof(ip))) {
{
EXLOGW("[ssh] can not parse client address into IP and port.\n"); EXLOGW("[ssh] can not parse client address into IP and port.\n");
} }
uint32_t dbg_id = m_dbg_id++; uint32_t dbg_id = m_dbg_id++;
auto session = new SshSession(this, rs_tp2cli, dbg_id, ip, addr->sin_port); auto session = new SshSession(this, rs_tp2cli, dbg_id, ip, addr->sin_port);
EXLOGW("[ssh] ------ NEW SSH SESSION [%s from %s:%d] ------\n", session->dbg_name().c_str(), ip, addr->sin_port); EXLOGW("[ssh] ------ NEW SSH SESSION [%s from %s:%d] ------\n", session->dbg_name().c_str(), ip, addr->sin_port);
{ {
@ -201,15 +176,13 @@ void SshProxy::_thread_loop()
ExThreadSmartLock locker(m_lock); ExThreadSmartLock locker(m_lock);
for (auto &session : m_sessions) for (auto& session : m_sessions) {
{
session.first->check_noop_timeout(0, 0); session.first->check_noop_timeout(0, 0);
} }
} }
// 等待所有session完成关闭清理操作工作线程退出 // 等待所有session完成关闭清理操作工作线程退出
for (;;) for (;;) {
{
// tp_core退出时会先停止timer线程所以这里需要自己调用timer()来进行session状态检查 // tp_core退出时会先停止timer线程所以这里需要自己调用timer()来进行session状态检查
timer(); timer();
@ -225,12 +198,10 @@ void SshProxy::_thread_loop()
EXLOGV("[ssh] main-loop end.\n"); EXLOGV("[ssh] main-loop end.\n");
} }
void SshProxy::_on_stop() void SshProxy::_on_stop() {
{
ExThreadBase::_on_stop(); ExThreadBase::_on_stop();
if (m_is_running) if (m_is_running) {
{
// 用一个变通的方式来结束阻塞中的监听,就是连接一下它。 // 用一个变通的方式来结束阻塞中的监听,就是连接一下它。
ex_astr host_ip = m_host_ip; ex_astr host_ip = m_host_ip;
if (host_ip == "0.0.0.0") if (host_ip == "0.0.0.0")
@ -250,8 +221,7 @@ void SshProxy::_on_stop()
ex_sleep_ms(500); ex_sleep_ms(500);
} }
while (m_listener_running) while (m_listener_running) {
{
ex_sleep_ms(1000); ex_sleep_ms(1000);
} }
} }

View File

@ -7,15 +7,15 @@ TppSshRec::TppSshRec() {
m_cmd_cache.reserve(MAX_SIZE_PER_FILE); m_cmd_cache.reserve(MAX_SIZE_PER_FILE);
memset(&m_head, 0, sizeof(TS_RECORD_HEADER)); memset(&m_head, 0, sizeof(TS_RECORD_HEADER));
memcpy((ex_u8 *) (&m_head.info.magic), TPP_RECORD_MAGIC, sizeof(ex_u32)); memcpy((ex_u8*) (&m_head.info.magic), TPP_RECORD_MAGIC, sizeof(ex_u32));
m_head.info.ver = 0x04; m_head.info.ver = 0x04;
m_head.info.type = TS_TPPR_TYPE_SSH; m_head.info.type = TS_TPPR_TYPE_SSH;
m_header_changed = false; m_header_changed = false;
m_save_full_header = false; m_save_full_header = false;
m_file_info = NULL; m_file_info = nullptr;
m_file_data = NULL; m_file_data = nullptr;
m_file_cmd = NULL; m_file_cmd = nullptr;
} }
@ -23,10 +23,10 @@ TppSshRec::~TppSshRec() {
end(); end();
} }
bool TppSshRec::_on_begin(const TPP_CONNECT_INFO *info) { bool TppSshRec::_on_begin(const TPP_CONNECT_INFO* info) {
if (NULL == info) if (nullptr == info)
return false; return false;
m_head.basic.timestamp = (ex_u64) time(NULL); m_head.basic.timestamp = (ex_u64) time(nullptr);
m_head.basic.protocol_type = (ex_u16) info->protocol_type; m_head.basic.protocol_type = (ex_u16) info->protocol_type;
m_head.basic.protocol_sub_type = (ex_u16) info->protocol_sub_type; m_head.basic.protocol_sub_type = (ex_u16) info->protocol_sub_type;
m_head.basic.conn_port = (ex_u16) info->conn_port; m_head.basic.conn_port = (ex_u16) info->conn_port;
@ -44,11 +44,11 @@ bool TppSshRec::_on_end() {
// 如果还有剩下未写入的数据,写入文件中。 // 如果还有剩下未写入的数据,写入文件中。
save_record(); save_record();
if (m_file_info != NULL) if (m_file_info != nullptr)
fclose(m_file_info); fclose(m_file_info);
if (m_file_data != NULL) if (m_file_data != nullptr)
fclose(m_file_data); fclose(m_file_data);
if (m_file_cmd != NULL) if (m_file_cmd != nullptr)
fclose(m_file_cmd); fclose(m_file_cmd);
return true; return true;
@ -59,8 +59,8 @@ void TppSshRec::save_record() {
_save_to_cmd_file(); _save_to_cmd_file();
} }
void TppSshRec::record(ex_u8 type, const ex_u8 *data, size_t size) { void TppSshRec::record(ex_u8 type, const ex_u8* data, size_t size) {
if (data == NULL || 0 == size) if (data == nullptr || 0 == size)
return; return;
if (sizeof(TS_RECORD_PKG) + size + m_cache.size() > MAX_SIZE_PER_FILE) if (sizeof(TS_RECORD_PKG) + size + m_cache.size() > MAX_SIZE_PER_FILE)
@ -77,7 +77,7 @@ void TppSshRec::record(ex_u8 type, const ex_u8 *data, size_t size) {
m_header_changed = true; m_header_changed = true;
} }
m_cache.append((ex_u8 *) &pkg, sizeof(TS_RECORD_PKG)); m_cache.append((ex_u8*) &pkg, sizeof(TS_RECORD_PKG));
m_cache.append(data, size); m_cache.append(data, size);
//m_head.info.packages++; //m_head.info.packages++;
@ -94,11 +94,11 @@ void TppSshRec::record_win_size_change(int width, int height) {
TS_RECORD_WIN_SIZE pkg = {0}; TS_RECORD_WIN_SIZE pkg = {0};
pkg.width = (ex_u16) width; pkg.width = (ex_u16) width;
pkg.height = (ex_u16) height; pkg.height = (ex_u16) height;
record(TS_RECORD_TYPE_SSH_TERM_SIZE, (ex_u8 *) &pkg, sizeof(TS_RECORD_WIN_SIZE)); record(TS_RECORD_TYPE_SSH_TERM_SIZE, (ex_u8*) &pkg, sizeof(TS_RECORD_WIN_SIZE));
} }
// 为了录像回放和命令历史能够对应(比如点击命令直接跳到录像的对应时点),仿照录像数据包的方式记录相对时间偏移,而不是绝对时间。 // 为了录像回放和命令历史能够对应(比如点击命令直接跳到录像的对应时点),仿照录像数据包的方式记录相对时间偏移,而不是绝对时间。
void TppSshRec::record_command(int flag, const ex_astr &cmd) { void TppSshRec::record_command(int flag, const ex_astr& cmd) {
char szTime[100] = {0}; char szTime[100] = {0};
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
// SYSTEMTIME st; // SYSTEMTIME st;
@ -109,7 +109,7 @@ void TppSshRec::record_command(int flag, const ex_astr &cmd) {
// struct tm *p; // struct tm *p;
// time(&timep); // time(&timep);
// p = localtime(&timep); // p = localtime(&timep);
// if (p == NULL) // if (p == nullptr)
// return; // return;
// sprintf(szTime, "[%04d-%02d-%02d %02d:%02d:%02d %d] ", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, flag); // sprintf(szTime, "[%04d-%02d-%02d %02d:%02d:%02d %d] ", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, flag);
#endif #endif
@ -120,23 +120,23 @@ void TppSshRec::record_command(int flag, const ex_astr &cmd) {
if (m_cmd_cache.size() + cmd.length() + lenTime > MAX_SIZE_PER_FILE) if (m_cmd_cache.size() + cmd.length() + lenTime > MAX_SIZE_PER_FILE)
_save_to_cmd_file(); _save_to_cmd_file();
m_cmd_cache.append((ex_u8 *) szTime, lenTime); m_cmd_cache.append((ex_u8*) szTime, lenTime);
m_cmd_cache.append((ex_u8 *) cmd.c_str(), cmd.length()); m_cmd_cache.append((ex_u8*) cmd.c_str(), cmd.length());
m_cmd_cache.append((ex_u8 *) "\r\n", 2); m_cmd_cache.append((ex_u8*) "\r\n", 2);
} }
bool TppSshRec::_save_to_info_file() { bool TppSshRec::_save_to_info_file() {
if (!m_header_changed) if (!m_header_changed)
return true; return true;
if (m_file_info == NULL) { if (m_file_info == nullptr) {
ex_wstr fname = m_base_path; ex_wstr fname = m_base_path;
if(!ex_path_join(fname, false, m_base_fname.c_str(), NULL)) if (!ex_path_join(fname, false, m_base_fname.c_str(), nullptr))
return false; return false;
fname += L".tpr"; fname += L".tpr";
m_file_info = ex_fopen(fname, L"wb"); m_file_info = ex_fopen(fname, L"wb");
if (NULL == m_file_info) { if (nullptr == m_file_info) {
EXLOGE("[ssh] can not open record info-file for write.\n"); EXLOGE("[ssh] can not open record info-file for write.\n");
return false; return false;
} }
@ -150,7 +150,8 @@ bool TppSshRec::_save_to_info_file() {
fwrite(&m_head, ts_record_header_size, 1, m_file_info); fwrite(&m_head, ts_record_header_size, 1, m_file_info);
fflush(m_file_info); fflush(m_file_info);
m_save_full_header = false; m_save_full_header = false;
} else { }
else {
fwrite(&m_head.info, ts_record_header_info_size, 1, m_file_info); fwrite(&m_head.info, ts_record_header_info_size, 1, m_file_info);
fflush(m_file_info); fflush(m_file_info);
} }
@ -162,14 +163,14 @@ bool TppSshRec::_save_to_data_file() {
if (m_cache.size() == 0) if (m_cache.size() == 0)
return true; return true;
if (m_file_data == NULL) { if (m_file_data == nullptr) {
ex_wstr fname = m_base_path; ex_wstr fname = m_base_path;
if(!ex_path_join(fname, false, m_base_fname.c_str(), NULL)) if (!ex_path_join(fname, false, m_base_fname.c_str(), nullptr))
return false; return false;
fname += L".dat"; fname += L".dat";
m_file_data = ex_fopen(fname, L"wb"); m_file_data = ex_fopen(fname, L"wb");
if (NULL == m_file_data) { if (nullptr == m_file_data) {
EXLOGE("[ssh] can not open record data-file for write.\n"); EXLOGE("[ssh] can not open record data-file for write.\n");
return false; return false;
} }
@ -188,14 +189,14 @@ bool TppSshRec::_save_to_cmd_file() {
if (m_cmd_cache.size() == 0) if (m_cmd_cache.size() == 0)
return true; return true;
if (NULL == m_file_cmd) { if (nullptr == m_file_cmd) {
ex_wstr fname = m_base_path; ex_wstr fname = m_base_path;
if (!ex_path_join(fname, false, m_base_fname.c_str(), NULL)) if (!ex_path_join(fname, false, m_base_fname.c_str(), nullptr))
return false; return false;
fname += L"-cmd.txt"; fname += L"-cmd.txt";
m_file_cmd = ex_fopen(fname, L"wb"); m_file_cmd = ex_fopen(fname, L"wb");
if (NULL == m_file_cmd) { if (nullptr == m_file_cmd) {
EXLOGE("[ssh] can not open record cmd-file for write.\n"); EXLOGE("[ssh] can not open record cmd-file for write.\n");
return false; return false;
} }

File diff suppressed because it is too large Load Diff

View File

@ -14,14 +14,13 @@
#include "ssh_channel_pair.h" #include "ssh_channel_pair.h"
#define TEST_SSH_SESSION_000000 // #define TEST_SSH_SESSION_000000
#define TS_SSH_CHANNEL_TYPE_UNKNOWN 0 #define TS_SSH_CHANNEL_TYPE_UNKNOWN 0
#define TS_SSH_CHANNEL_TYPE_SHELL 1 #define TS_SSH_CHANNEL_TYPE_SHELL 1
#define TS_SSH_CHANNEL_TYPE_SFTP 2 #define TS_SSH_CHANNEL_TYPE_SFTP 2
enum SSH_SESSION_STATUS enum SSH_SESSION_STATUS {
{
SSH_SESSION_STATE_CLOSED = 0, SSH_SESSION_STATE_CLOSED = 0,
SSH_SESSION_STATE_STARTING, SSH_SESSION_STATE_STARTING,
SSH_SESSION_STATE_AUTHING, SSH_SESSION_STATE_AUTHING,
@ -35,35 +34,25 @@ class SshProxy;
class SshSession; class SshSession;
class SshSession : class SshSession :
public ExThreadBase public ExThreadBase {
{
public: public:
SshSession(SshProxy *proxy, ssh_session rs_tp2cli, uint32_t dbg_id, const char *client_ip, uint16_t client_port); SshSession(SshProxy* proxy, ssh_session rs_tp2cli, uint32_t dbg_id, const char* client_ip, uint16_t client_port);
virtual ~SshSession(); virtual ~SshSession();
// uint32_t dbg_id() const const std::string& dbg_name() const {
// {
// return m_dbg_id;
// }
const std::string &dbg_name() const
{
return m_dbg_name; return m_dbg_name;
} }
const std::string &dbg_client() const const std::string& dbg_client() const {
{
return m_dbg_client; return m_dbg_client;
} }
const std::string &dbg_server() const const std::string& dbg_server() const {
{
return m_dbg_server; return m_dbg_server;
} }
const std::string &sid() const std::string& sid() {
{
return m_sid; return m_sid;
} }
@ -76,13 +65,11 @@ public:
void keep_alive(); void keep_alive();
bool closed() const bool closed() const {
{
return m_state == SSH_SESSION_STATE_CLOSED; return m_state == SSH_SESSION_STATE_CLOSED;
} }
ssh_session get_peer_raw_session(ssh_session session) ssh_session get_peer_raw_session(ssh_session session) {
{
if (session == m_rs_tp2cli) if (session == m_rs_tp2cli)
return m_rs_tp2srv; return m_rs_tp2srv;
else if (session == m_rs_tp2srv) else if (session == m_rs_tp2srv)
@ -95,9 +82,11 @@ public:
// 通道管理 // 通道管理
// -------------------------- // --------------------------
void set_channel_tp2srv_callbacks(ssh_channel ch_tp2srv); void set_channel_tp2srv_callbacks(ssh_channel ch_tp2srv);
bool make_channel_pair(ssh_channel ch_tp2cli, ssh_channel ch_tp2srv); bool make_channel_pair(ssh_channel ch_tp2cli, ssh_channel ch_tp2srv);
SshChannelPair *get_channel_pair(ssh_channel ch); SshChannelPair* get_channel_pair(ssh_channel ch);
void check_channels(); void check_channels();
protected: protected:
@ -113,57 +102,57 @@ protected:
private: private:
void _close_channels(); void _close_channels();
int _do_auth(const char *user, const char *secret); int _do_auth(const char* user, const char* secret);
void _set_last_error(int err_code); void _set_last_error(int err_code);
bool _send(ssh_channel channel_to, int is_stderr, void *data, uint32_t len); bool _send(ssh_channel channel_to, int is_stderr, void* data, uint32_t len);
static int _on_auth_password_request(ssh_session session, const char *user, const char *password, void *userdata); static int _on_auth_password_request(ssh_session session, const char* user, const char* password, void* userdata);
static ssh_channel _on_new_channel_request(ssh_session session, void *userdata); static ssh_channel _on_new_channel_request(ssh_session session, void* userdata);
static int _on_client_pty_request(ssh_session session, ssh_channel channel, const char *term, int x, int y, int px, int py, void *userdata); static int _on_client_pty_request(ssh_session session, ssh_channel channel, const char* term, int x, int y, int px, int py, void* userdata);
static int _on_client_shell_request(ssh_session session, ssh_channel channel, void *userdata); static int _on_client_shell_request(ssh_session session, ssh_channel channel, void* userdata);
static void _on_client_channel_close(ssh_session session, ssh_channel channel, void *userdata); static void _on_client_channel_close(ssh_session session, ssh_channel channel, void* userdata);
static int _on_client_channel_data(ssh_session session, ssh_channel channel, void *data, unsigned int len, int is_stderr, void *userdata); static int _on_client_channel_data(ssh_session session, ssh_channel channel, void* data, unsigned int len, int is_stderr, void* userdata);
static int _on_client_pty_win_change(ssh_session session, ssh_channel channel, int width, int height, int pxwidth, int pwheight, void *userdata); static int _on_client_pty_win_change(ssh_session session, ssh_channel channel, int width, int height, int pxwidth, int pwheight, void* userdata);
static int _on_client_channel_subsystem_request(ssh_session session, ssh_channel channel, const char *subsystem, void *userdata); static int _on_client_channel_subsystem_request(ssh_session session, ssh_channel channel, const char* subsystem, void* userdata);
static int _on_client_channel_exec_request(ssh_session session, ssh_channel channel, const char *command, void *userdata); static int _on_client_channel_exec_request(ssh_session session, ssh_channel channel, const char* command, void* userdata);
static int _on_server_channel_data(ssh_session session, ssh_channel channel, void *data, unsigned int len, int is_stderr, void *userdata); static int _on_server_channel_data(ssh_session session, ssh_channel channel, void* data, unsigned int len, int is_stderr, void* userdata);
static void _on_server_channel_close(ssh_session session, ssh_channel channel, void *userdata); static void _on_server_channel_close(ssh_session session, ssh_channel channel, void* userdata);
private: private:
SshProxy *m_proxy; SshProxy* m_proxy;
SSH_SESSION_STATUS m_state; SSH_SESSION_STATUS m_state;
ssh_session m_rs_tp2cli; ssh_session m_rs_tp2cli;
ssh_session m_rs_tp2srv; ssh_session m_rs_tp2srv;
ExThreadLock m_lock; ExThreadLock m_lock;
uint32_t m_dbg_id; uint32_t m_dbg_id;
std::string m_dbg_name; std::string m_dbg_name;
std::string m_dbg_client; std::string m_dbg_client;
std::string m_dbg_server; std::string m_dbg_server;
TPP_CONNECT_INFO *m_conn_info; TPP_CONNECT_INFO* m_conn_info;
std::string m_sid; std::string m_sid;
std::string m_conn_ip; std::string m_conn_ip;
uint16_t m_conn_port; uint16_t m_conn_port;
std::string m_acc_name; std::string m_acc_name;
std::string m_acc_secret; std::string m_acc_secret;
uint32_t m_flags; uint32_t m_flags;
int m_auth_type; int m_auth_type;
bool m_allow_user_input_password; bool m_allow_user_input_password;
bool m_first_auth; bool m_first_auth;
// 远程主机认证是否通过 // 远程主机认证是否通过
@ -171,25 +160,17 @@ private:
// 发生了不可逆的错误,需要关闭整个会话(包括所有的通道) // 发生了不可逆的错误,需要关闭整个会话(包括所有的通道)
bool m_fault; bool m_fault;
// int m_ssh_ver;
// 一个ssh_session中可以打开多个ssh_channel
// tp_channels m_channels;
// 管理两端的通道对 // 管理两端的通道对
TPChannelPairs m_pairs; uint32_t m_pair_id; // for debug.
TPChannelPairs m_pairs;
// 用于快速查找 // 用于快速查找
channel_map m_channel_map; channel_map m_channel_map;
// 本会话中的所有通道(无论哪一端的) // 本会话中的所有通道(无论哪一端的)
std::list<ssh_channel> m_channels; std::list<ssh_channel> m_channels;
bool m_need_send_keepalive; bool m_need_send_keepalive;
bool m_recving_from_srv; // 是否正在从服务器接收数据? struct ssh_server_callbacks_struct m_srv_cb;
bool m_recving_from_cli; // 是否正在从客户端接收数据?
struct ssh_server_callbacks_struct m_srv_cb;
struct ssh_channel_callbacks_struct m_cli_channel_cb; struct ssh_channel_callbacks_struct m_cli_channel_cb;
struct ssh_channel_callbacks_struct m_srv_channel_cb; struct ssh_channel_callbacks_struct m_srv_channel_cb;
}; };

View File

@ -2,37 +2,30 @@
TppSshEnv g_ssh_env; TppSshEnv g_ssh_env;
TppSshEnv::TppSshEnv() TppSshEnv::TppSshEnv() noexcept:
{ bind_port(0) {
} }
TppSshEnv::~TppSshEnv() TppSshEnv::~TppSshEnv() = default;
{
}
bool TppSshEnv::_on_init(TPP_INIT_ARGS *args) bool TppSshEnv::_on_init(TPP_INIT_ARGS* args) {
{
ex_path_join(replay_path, false, L"ssh", NULL); ex_path_join(replay_path, false, L"ssh", NULL);
auto ps = args->cfg->GetSection(L"protocol-ssh"); auto ps = args->cfg->GetSection(L"protocol-ssh");
if (!ps) if (!ps) {
{
EXLOGE("[ssh] invalid config(2).\n"); EXLOGE("[ssh] invalid config(2).\n");
return false; return false;
} }
ex_wstr tmp; ex_wstr tmp;
if (!ps->GetStr(L"bind-ip", tmp)) if (!ps->GetStr(L"bind-ip", tmp)) {
{
bind_ip = TS_SSH_PROXY_HOST; bind_ip = TS_SSH_PROXY_HOST;
} }
else else {
{
ex_wstr2astr(tmp, bind_ip); ex_wstr2astr(tmp, bind_ip);
} }
if (!ps->GetInt(L"bind-port", bind_port)) if (!ps->GetInt(L"bind-port", bind_port)) {
{
bind_port = TS_SSH_PROXY_PORT; bind_port = TS_SSH_PROXY_PORT;
} }

View File

@ -3,18 +3,18 @@
#include "../../common/base_env.h" #include "../../common/base_env.h"
class TppSshEnv : public TppEnvBase class TppSshEnv : public TppEnvBase {
{
public: public:
TppSshEnv(); TppSshEnv() noexcept;
~TppSshEnv();
~TppSshEnv() override;
public: public:
ex_astr bind_ip; ex_astr bind_ip;
int bind_port; int bind_port;
private: private:
bool _on_init(TPP_INIT_ARGS *args); bool _on_init(TPP_INIT_ARGS* args) override;
}; };
extern TppSshEnv g_ssh_env; extern TppSshEnv g_ssh_env;

View File

@ -4,8 +4,7 @@
#include <teleport_const.h> #include <teleport_const.h>
#include <json/json.h> #include <json/json.h>
TPP_API ex_rv tpp_init(TPP_INIT_ARGS *init_args) TPP_API ex_rv tpp_init(TPP_INIT_ARGS* init_args) {
{
#ifdef EX_OS_UNIX #ifdef EX_OS_UNIX
ssh_threads_set_callbacks(ssh_threads_get_pthread()); ssh_threads_set_callbacks(ssh_threads_get_pthread());
ssh_init(); ssh_init();
@ -19,8 +18,7 @@ TPP_API ex_rv tpp_init(TPP_INIT_ARGS *init_args)
return 0; return 0;
} }
TPP_API ex_rv tpp_start(void) TPP_API ex_rv tpp_start(void) {
{
if (!g_ssh_proxy.init()) if (!g_ssh_proxy.init())
return TPE_FAILED; return TPE_FAILED;
if (!g_ssh_proxy.start()) if (!g_ssh_proxy.start())
@ -29,26 +27,23 @@ TPP_API ex_rv tpp_start(void)
return 0; return 0;
} }
TPP_API ex_rv tpp_stop(void) TPP_API ex_rv tpp_stop(void) {
{
g_ssh_proxy.stop(); g_ssh_proxy.stop();
ssh_finalize(); ssh_finalize();
return 0; return 0;
} }
TPP_API void tpp_timer(void) TPP_API void tpp_timer(void) {
{
// be called per one second. // be called per one second.
g_ssh_proxy.timer(); g_ssh_proxy.timer();
} }
static ex_rv tpp_cmd_set_runtime_config(const char *param) static ex_rv tpp_cmd_set_runtime_config(const char* param) {
{ Json::Value jp;
Json::Value jp; Json::CharReaderBuilder jcrb;
Json::CharReaderBuilder jcrb;
std::unique_ptr<Json::CharReader> const jreader(jcrb.newCharReader()); std::unique_ptr<Json::CharReader> const jreader(jcrb.newCharReader());
const char *str_json_begin = param; const char* str_json_begin = param;
ex_astr err; ex_astr err;
if (!jreader->parse(str_json_begin, param + strlen(param), &jp, &err)) if (!jreader->parse(str_json_begin, param + strlen(param), &jp, &err))
return TPE_JSON_FORMAT; return TPE_JSON_FORMAT;
@ -68,12 +63,11 @@ static ex_rv tpp_cmd_set_runtime_config(const char *param)
return TPE_PARAM; return TPE_PARAM;
} }
static ex_rv tpp_cmd_kill_sessions(const char *param) static ex_rv tpp_cmd_kill_sessions(const char* param) {
{ Json::Value jp;
Json::Value jp;
Json::CharReaderBuilder reader_builder; Json::CharReaderBuilder reader_builder;
const char *str_json_begin = param; const char* str_json_begin = param;
ex_astr err; ex_astr err;
std::unique_ptr<Json::CharReader> const json_reader(reader_builder.newCharReader()); std::unique_ptr<Json::CharReader> const json_reader(reader_builder.newCharReader());
if (!json_reader->parse(str_json_begin, param + strlen(param), &jp, &err)) if (!json_reader->parse(str_json_begin, param + strlen(param), &jp, &err))
@ -84,10 +78,8 @@ static ex_rv tpp_cmd_kill_sessions(const char *param)
ex_astrs ss; ex_astrs ss;
for (const auto &item : jp) for (const auto& item : jp) {
{ if (!item.isString()) {
if (!item.isString())
{
return TPE_PARAM; return TPE_PARAM;
} }
@ -99,18 +91,13 @@ static ex_rv tpp_cmd_kill_sessions(const char *param)
return TPE_PARAM; return TPE_PARAM;
} }
TPP_API ex_rv tpp_command(ex_u32 cmd, const char *param) TPP_API ex_rv tpp_command(ex_u32 cmd, const char* param) {
{
if (!param || strlen(param) == 0) if (!param || strlen(param) == 0)
return TPE_PARAM; return TPE_PARAM;
switch (cmd) switch (cmd) {
{ case TPP_CMD_SET_RUNTIME_CFG:return tpp_cmd_set_runtime_config(param);
case TPP_CMD_SET_RUNTIME_CFG: case TPP_CMD_KILL_SESSIONS:return tpp_cmd_kill_sessions(param);
return tpp_cmd_set_runtime_config(param); default:return TPE_UNKNOWN_CMD;
case TPP_CMD_KILL_SESSIONS:
return tpp_cmd_kill_sessions(param);
default:
return TPE_UNKNOWN_CMD;
} }
} }

View File

@ -313,6 +313,9 @@ $app.on_table_host_render_created = function (render) {
case TP_SESS_STAT_ERR_UNSUPPORT_PROTOCOL: case TP_SESS_STAT_ERR_UNSUPPORT_PROTOCOL:
msg = '协议不支持'; msg = '协议不支持';
break; break;
case TP_SESS_STAT_ERR_CREATE_CHANNEL:
msg = '无法创建数据通道';
break;
case TP_SESS_STAT_ERR_BAD_PKG: case TP_SESS_STAT_ERR_BAD_PKG:
case TP_SESS_STAT_ERR_START_BAD_PKG: case TP_SESS_STAT_ERR_START_BAD_PKG:
msg = '数据格式错误'; msg = '数据格式错误';

View File

@ -324,6 +324,9 @@ $app.on_table_session_render_created = function (render) {
case TP_SESS_STAT_ERR_UNSUPPORT_PROTOCOL: case TP_SESS_STAT_ERR_UNSUPPORT_PROTOCOL:
msg = '协议不支持'; msg = '协议不支持';
break; break;
case TP_SESS_STAT_ERR_CREATE_CHANNEL:
msg = '无法创建数据通道';
break;
case TP_SESS_STAT_ERR_BAD_PKG: case TP_SESS_STAT_ERR_BAD_PKG:
case TP_SESS_STAT_ERR_START_BAD_PKG: case TP_SESS_STAT_ERR_START_BAD_PKG:
msg = '数据格式错误'; msg = '数据格式错误';

View File

@ -38,23 +38,26 @@ var TP_OS_TYPE_LINUX = 2;
// ======================================================= // =======================================================
// 远程连接会话状态 // 远程连接会话状态
// ======================================================= // =======================================================
var TP_SESS_STAT_RUNNING = 0; // 会话开始了,尚未结束,还在连接过程中 var TP_SESS_STAT_RUNNING = 0; // 会话开始了,尚未结束,还在连接过程中
var TP_SESS_STAT_END = 9999; // 会话成功结束 var TP_SESS_STAT_ERR_AUTH_DENIED = 1; // 会话结束,因为认证失败
var TP_SESS_STAT_ERR_AUTH_DENIED = 1; // 会话结束,因为认证失败 var TP_SESS_STAT_ERR_CONNECT = 2; // 会话结束,因为无法连接到远程主机
var TP_SESS_STAT_ERR_CONNECT = 2; // 会话结束,因为无法连接到远程主机 var TP_SESS_STAT_ERR_BAD_SSH_KEY = 3; // 会话结束因为无法识别SSH私钥
var TP_SESS_STAT_ERR_BAD_SSH_KEY = 3; // 会话结束因为无法识别SSH私钥 var TP_SESS_STAT_ERR_INTERNAL = 4; // 会话结束,因为内部错误
var TP_SESS_STAT_ERR_INTERNAL = 4; // 会话结束,因为内部错误 var TP_SESS_STAT_ERR_UNSUPPORT_PROTOCOL = 5; // 会话结束,因为协议不支持(RDP)
var TP_SESS_STAT_ERR_UNSUPPORT_PROTOCOL = 5; // 会话结束,因为协议不支持(RDP) var TP_SESS_STAT_ERR_BAD_PKG = 6; // 会话结束,因为收到错误的报文
var TP_SESS_STAT_ERR_BAD_PKG = 6; // 会话结束,因为收到错误的报文 var TP_SESS_STAT_ERR_RESET = 7; // 会话结束因为teleport核心服务重置了
var TP_SESS_STAT_ERR_RESET = 7; // 会话结束因为teleport核心服务重置了 var TP_SESS_STAT_ERR_IO = 8; // 会话结束,因为网络中断
var TP_SESS_STAT_ERR_IO = 8; // 会话结束,因为网络中断 var TP_SESS_STAT_ERR_SESSION = 9; // 会话结束因为无效的会话ID
var TP_SESS_STAT_ERR_SESSION = 9; // 会话结束因为无效的会话ID var TP_SESS_STAT_ERR_AUTH_TYPE = 10; // 会话结束,因为服务端不支持此认证方式
var TP_SESS_STAT_ERR_AUTH_TYPE = 10; // // 会话结束,因为服务端不支持此认证方式 var TP_SESS_STAT_ERR_CREATE_CHANNEL = 11; // 会话结束,因为创建通道失败
var TP_SESS_STAT_STARTED = 100; // 已经连接成功了,开始记录录像了
var TP_SESS_STAT_ERR_START_INTERNAL = 104; // 会话结束,因为内部错误 var TP_SESS_STAT_STARTED = 100; // 已经连接成功了,开始记录录像了
var TP_SESS_STAT_ERR_START_BAD_PKG = 106; // 会话结束,因为收到错误的报文 var TP_SESS_STAT_ERR_START_INTERNAL = 104; // 会话结束,因为内部错误
var TP_SESS_STAT_ERR_START_RESET = 107; // 会话结束因为teleport核心服务重置了 var TP_SESS_STAT_ERR_START_BAD_PKG = 106; // 会话结束,因为收到错误的报文
var TP_SESS_STAT_ERR_START_IO = 108; // 会话结束,因为网络中断 var TP_SESS_STAT_ERR_START_RESET = 107; // 会话结束因为teleport核心服务重置了
var TP_SESS_STAT_ERR_START_IO = 108; // 会话结束,因为网络中断
var TP_SESS_STAT_END = 9999; // 会话成功结束
// ========================================================================== // ==========================================================================
// 对象类型 // 对象类型

View File

@ -7,6 +7,7 @@ import sys
import threading import threading
import time import time
import traceback import traceback
import builtins
__all__ = ['log'] __all__ = ['log']
@ -14,6 +15,7 @@ USE_TPWEB_LOG = False
try: try:
import tpweb import tpweb
USE_TPWEB_LOG = True USE_TPWEB_LOG = True
except ImportError: except ImportError:
pass pass
@ -627,6 +629,4 @@ del Logger
# log._test() # log._test()
# print('test built-in `print` function.') # print('test built-in `print` function.')
import builtins
builtins.__dict__['print'] = log.log_print builtins.__dict__['print'] = log.log_print

View File

@ -2,11 +2,11 @@
from enum import IntEnum, unique from enum import IntEnum, unique
TP_LOGIN_AUTH_SYS_DEFAULT = 0 # 系统默认(根据系统配置进行) TP_LOGIN_AUTH_SYS_DEFAULT = 0 # 系统默认(根据系统配置进行)
TP_LOGIN_AUTH_USERNAME_PASSWORD = 0x0001 # 用户名+密码 TP_LOGIN_AUTH_USERNAME_PASSWORD = 0x0001 # 用户名+密码
TP_LOGIN_AUTH_USERNAME_PASSWORD_CAPTCHA = 0x0002 # 用户名+密码+验证码 TP_LOGIN_AUTH_USERNAME_PASSWORD_CAPTCHA = 0x0002 # 用户名+密码+验证码
TP_LOGIN_AUTH_USERNAME_OATH = 0x0004 # 用户名+OATH TP_LOGIN_AUTH_USERNAME_OATH = 0x0004 # 用户名+OATH
TP_LOGIN_AUTH_USERNAME_PASSWORD_OATH = 0x0008 # 用户名+密码+OATH TP_LOGIN_AUTH_USERNAME_PASSWORD_OATH = 0x0008 # 用户名+密码+OATH
APP_MODE_NORMAL = 1 APP_MODE_NORMAL = 1
APP_MODE_MAINTENANCE = 2 APP_MODE_MAINTENANCE = 2
@ -67,7 +67,7 @@ TP_OS_TYPE_LINUX = 2
# 远程连接会话状态 # 远程连接会话状态
# ======================================================= # =======================================================
TP_SESS_STAT_RUNNING = 0 # 会话开始了,尚未结束 TP_SESS_STAT_RUNNING = 0 # 会话开始了,尚未结束
TP_SESS_STAT_END = 9999 # 会话成功结束
TP_SESS_STAT_ERR_AUTH_DENIED = 1 # 会话结束,因为认证失败 TP_SESS_STAT_ERR_AUTH_DENIED = 1 # 会话结束,因为认证失败
TP_SESS_STAT_ERR_CONNECT = 2 # 会话结束,因为无法连接到远程主机 TP_SESS_STAT_ERR_CONNECT = 2 # 会话结束,因为无法连接到远程主机
TP_SESS_STAT_ERR_BAD_SSH_KEY = 3 # 会话结束因为无法识别SSH私钥 TP_SESS_STAT_ERR_BAD_SSH_KEY = 3 # 会话结束因为无法识别SSH私钥
@ -77,12 +77,18 @@ TP_SESS_STAT_ERR_BAD_PKG = 6 # 会话结束,因为收到错误的报文
TP_SESS_STAT_ERR_RESET = 7 # 会话结束因为teleport核心服务重置了 TP_SESS_STAT_ERR_RESET = 7 # 会话结束因为teleport核心服务重置了
TP_SESS_STAT_ERR_IO = 8 # 会话结束,因为网络中断 TP_SESS_STAT_ERR_IO = 8 # 会话结束,因为网络中断
TP_SESS_STAT_ERR_SESSION = 9 # 会话结束因为无效的会话ID TP_SESS_STAT_ERR_SESSION = 9 # 会话结束因为无效的会话ID
TP_SESS_STAT_ERR_AUTH_TYPE = 10 # 会话结束,因为服务端不支持此认证方式
TP_SESS_STAT_ERR_CREATE_CHANNEL = 11 # 会话结束,因为创建通道失败
TP_SESS_STAT_STARTED = 100 # 已经连接成功了,开始记录录像了 TP_SESS_STAT_STARTED = 100 # 已经连接成功了,开始记录录像了
TP_SESS_STAT_ERR_START_INTERNAL = 104 # 会话结束,因为内部错误 TP_SESS_STAT_ERR_START_INTERNAL = 104 # 会话结束,因为内部错误
TP_SESS_STAT_ERR_START_BAD_PKG = 106 # 会话结束,因为收到错误的报文 TP_SESS_STAT_ERR_START_BAD_PKG = 106 # 会话结束,因为收到错误的报文
TP_SESS_STAT_ERR_START_RESET = 107 # 会话结束因为teleport核心服务重置了 TP_SESS_STAT_ERR_START_RESET = 107 # 会话结束因为teleport核心服务重置了
TP_SESS_STAT_ERR_START_IO = 108 # 会话结束,因为网络中断 TP_SESS_STAT_ERR_START_IO = 108 # 会话结束,因为网络中断
TP_SESS_STAT_END = 9999 # 会话成功结束
# ========================================================================== # ==========================================================================
# 分组类型 # 分组类型
# ========================================================================== # ==========================================================================