mirror of https://github.com/tp4a/teleport
重构核心服务SSH模块,修正以下问题:
1. 某些情况下会卡在登录流程(通道中创建shell操作与收到服务端数据操作造成死锁); 2. 某些情况下连接断开了,但web界面仍然显示使用中(没有正确处理断开事件,没有更新数据库); 3. cat一个大文件会很慢,有时会导致连接断开(每个数据包都完整解析导致处理时间过长); 4. 连接/认证过程出错(密码错误、协议不支持、远程连接超时等等),均会提示用户重新输入密码(改为断开连接,避免造成误解);dev
parent
b7d9f6f0d8
commit
f26c71d52d
|
@ -4,67 +4,65 @@
|
|||
#include "ex_types.h"
|
||||
#include "ex_thread.h"
|
||||
|
||||
#define EX_LOG_LEVEL_DEBUG 0
|
||||
#define EX_LOG_LEVEL_VERBOSE 1
|
||||
#define EX_LOG_LEVEL_INFO 2
|
||||
#define EX_LOG_LEVEL_WARN 3
|
||||
#define EX_LOG_LEVEL_ERROR 4
|
||||
#define EX_LOG_LEVEL_DEBUG 0
|
||||
#define EX_LOG_LEVEL_VERBOSE 1
|
||||
#define EX_LOG_LEVEL_INFO 2
|
||||
#define EX_LOG_LEVEL_WARN 3
|
||||
#define EX_LOG_LEVEL_ERROR 4
|
||||
|
||||
#define EX_LOG_FILE_MAX_SIZE 1024*1024*10
|
||||
#define EX_LOG_FILE_MAX_COUNT 10
|
||||
#define EX_LOG_FILE_MAX_SIZE 1024*1024*10
|
||||
#define EX_LOG_FILE_MAX_COUNT 10
|
||||
|
||||
class ExLogger
|
||||
{
|
||||
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);
|
||||
void log_a(int level, const char* fmt, va_list valist);
|
||||
void log_w(int level, const wchar_t* fmt, va_list valist);
|
||||
bool write_a(const char* buf);
|
||||
bool write_w(const wchar_t* buf);
|
||||
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_w(int level, const wchar_t *fmt, va_list valist);
|
||||
bool write_a(const char *buf);
|
||||
bool write_w(const wchar_t *buf);
|
||||
|
||||
protected:
|
||||
bool _open_file();
|
||||
bool _rotate_file(void); // 将现有日志文件改名备份,然后新开一个日志文件
|
||||
bool _open_file();
|
||||
|
||||
// 将现有日志文件改名备份,然后新开一个日志文件
|
||||
bool _rotate_file();
|
||||
|
||||
public:
|
||||
ExThreadLock lock;
|
||||
int min_level;
|
||||
bool debug_mode;
|
||||
bool to_console;
|
||||
ExThreadLock lock;
|
||||
int min_level;
|
||||
bool debug_mode;
|
||||
bool to_console;
|
||||
|
||||
#ifdef EX_OS_WIN32
|
||||
HANDLE console_handle;
|
||||
HANDLE console_handle;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
ex_u32 m_filesize;
|
||||
ex_u32 m_max_filesize;
|
||||
ex_u8 m_max_count;
|
||||
ex_wstr m_path;
|
||||
ex_wstr m_filename;
|
||||
ex_wstr m_fullname;
|
||||
ex_u32 m_filesize;
|
||||
ex_u32 m_max_filesize;
|
||||
ex_u8 m_max_count;
|
||||
ex_wstr m_path;
|
||||
ex_wstr m_filename;
|
||||
ex_wstr m_fullname;
|
||||
|
||||
#ifdef EX_OS_WIN32
|
||||
HANDLE m_file;
|
||||
HANDLE m_file;
|
||||
#else
|
||||
FILE* m_file;
|
||||
FILE *m_file;
|
||||
#endif
|
||||
};
|
||||
|
||||
//extern ExLogger g_ex_logger;
|
||||
|
||||
// extern void* ex_logger;
|
||||
|
||||
void EXLOG_USE_LOGGER(ExLogger* logger);
|
||||
void EXLOG_USE_LOGGER(ExLogger *logger);
|
||||
|
||||
void EXLOG_LEVEL(int min_level);
|
||||
void EXLOG_DEBUG(bool debug_mode);
|
||||
|
||||
// 设定日志文件名及路径,如未指定路径,则为可执行程序所在目录下的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);
|
||||
|
||||
|
@ -82,20 +80,20 @@ void ex_printf_e_lasterror(const wchar_t* fmt, ...);
|
|||
#endif
|
||||
|
||||
|
||||
void ex_printf_d(const char* fmt, ...);
|
||||
void ex_printf_v(const char* fmt, ...);
|
||||
void ex_printf_i(const char* fmt, ...);
|
||||
void ex_printf_w(const char* fmt, ...);
|
||||
void ex_printf_e(const char* fmt, ...);
|
||||
void ex_printf_d(const char *fmt, ...);
|
||||
void ex_printf_v(const char *fmt, ...);
|
||||
void ex_printf_i(const char *fmt, ...);
|
||||
void ex_printf_w(const char *fmt, ...);
|
||||
void ex_printf_e(const char *fmt, ...);
|
||||
|
||||
void ex_printf_d(const wchar_t* fmt, ...);
|
||||
void ex_printf_v(const wchar_t* fmt, ...);
|
||||
void ex_printf_i(const wchar_t* fmt, ...);
|
||||
void ex_printf_w(const wchar_t* fmt, ...);
|
||||
void ex_printf_e(const wchar_t* fmt, ...);
|
||||
void ex_printf_d(const wchar_t *fmt, ...);
|
||||
void ex_printf_v(const wchar_t *fmt, ...);
|
||||
void ex_printf_i(const wchar_t *fmt, ...);
|
||||
void ex_printf_w(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 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 wchar_t *fmt, ...);
|
||||
|
||||
|
||||
#endif // __EX_LOG_H__
|
||||
|
|
|
@ -81,7 +81,6 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* 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.
|
||||
|
|
|
@ -206,6 +206,6 @@ int ex_atomic_inc(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__
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define __LIB_EX_TYPE_H__
|
||||
|
||||
#include "ex_platform.h"
|
||||
#include <cstdint>
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
@ -31,7 +32,7 @@ typedef int EX_BOOL;
|
|||
typedef std::vector<ex_u8> ex_bin;
|
||||
typedef std::vector<char> ex_chars;
|
||||
|
||||
typedef ex_u32 ex_rv;
|
||||
typedef uint32_t ex_rv;
|
||||
|
||||
|
||||
#if defined(EX_OS_WIN32)
|
||||
|
|
|
@ -32,7 +32,6 @@ void ex_sleep_ms(int ms);
|
|||
|
||||
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_astr& filename, const char* mode);
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <ex/ex_log.h>
|
||||
#include <ex/ex_path.h>
|
||||
#include <ex/ex_thread.h>
|
||||
//#include <ex/ex_thread.h>
|
||||
//#include <vector>
|
||||
//#include <deque>
|
||||
|
@ -16,119 +17,125 @@
|
|||
|
||||
#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;
|
||||
}
|
||||
|
||||
void EXLOG_LEVEL(int min_level)
|
||||
{
|
||||
if(NULL != g_exlog)
|
||||
g_exlog->min_level = min_level;
|
||||
void EXLOG_LEVEL(int min_level) {
|
||||
if (nullptr != g_exlog)
|
||||
g_exlog->min_level = min_level;
|
||||
}
|
||||
|
||||
void EXLOG_DEBUG(bool debug_mode)
|
||||
{
|
||||
if (NULL != g_exlog)
|
||||
g_exlog->debug_mode = debug_mode;
|
||||
void EXLOG_DEBUG(bool debug_mode) {
|
||||
if (nullptr != g_exlog)
|
||||
g_exlog->debug_mode = debug_mode;
|
||||
}
|
||||
|
||||
void EXLOG_CONSOLE(bool output_to_console)
|
||||
{
|
||||
if(NULL != g_exlog)
|
||||
g_exlog->to_console = output_to_console;
|
||||
void EXLOG_CONSOLE(bool output_to_console) {
|
||||
if (nullptr != g_exlog)
|
||||
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*/)
|
||||
{
|
||||
if(NULL == g_exlog)
|
||||
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)
|
||||
return;
|
||||
|
||||
ex_wstr _path;
|
||||
if (NULL == log_path)
|
||||
{
|
||||
ex_exec_file(_path);
|
||||
ex_dirname(_path);
|
||||
ex_path_join(_path, false, L"log", NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
_path = log_path;
|
||||
}
|
||||
ex_wstr _path;
|
||||
if (nullptr == log_path) {
|
||||
ex_exec_file(_path);
|
||||
ex_dirname(_path);
|
||||
ex_path_join(_path, false, L"log", nullptr);
|
||||
}
|
||||
else {
|
||||
_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
|
||||
console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
#endif
|
||||
|
||||
min_level = EX_LOG_LEVEL_INFO;
|
||||
debug_mode = false;
|
||||
to_console = true;
|
||||
min_level = EX_LOG_LEVEL_INFO;
|
||||
debug_mode = false;
|
||||
to_console = true;
|
||||
|
||||
m_file = NULL;
|
||||
m_filesize = 0;
|
||||
m_file = nullptr;
|
||||
m_filesize = 0;
|
||||
}
|
||||
|
||||
ExLogger::~ExLogger()
|
||||
{
|
||||
if (NULL != m_file)
|
||||
{
|
||||
ExLogger::~ExLogger() {
|
||||
if (nullptr != m_file) {
|
||||
#ifdef EX_OS_WIN32
|
||||
CloseHandle(m_file);
|
||||
CloseHandle(m_file);
|
||||
#else
|
||||
fclose(m_file);
|
||||
fclose(m_file);
|
||||
#endif
|
||||
m_file = NULL;
|
||||
}
|
||||
m_file = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void ExLogger::log_a(int level, const char* fmt, va_list valist)
|
||||
{
|
||||
if (NULL == fmt)
|
||||
return;
|
||||
void ExLogger::log_a(int level, const char* fmt, va_list valist) {
|
||||
if (nullptr == fmt)
|
||||
return;
|
||||
|
||||
if (0 == strlen(fmt))
|
||||
return;
|
||||
if (0 == strlen(fmt))
|
||||
return;
|
||||
|
||||
char szTmp[4096] = { 0 };
|
||||
size_t offset = 0;
|
||||
const char* _level = "";
|
||||
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)
|
||||
{
|
||||
szTmp[0] = '[';
|
||||
szTmp[1] = 'E';
|
||||
szTmp[2] = ']';
|
||||
szTmp[3] = ' ';
|
||||
offset = 4;
|
||||
}
|
||||
char prefix[100] = {0};
|
||||
#ifdef EX_OS_WIN32
|
||||
SYSTEMTIME st;
|
||||
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);
|
||||
// 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);
|
||||
#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
|
||||
vsnprintf_s(szTmp+offset, 4096-offset, 4095-offset, fmt, valist);
|
||||
if(to_console)
|
||||
{
|
||||
if (NULL != console_handle)
|
||||
{
|
||||
printf_s("%s", szTmp);
|
||||
fflush(stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(debug_mode)
|
||||
OutputDebugStringA(szTmp);
|
||||
}
|
||||
}
|
||||
vsnprintf_s(szTmp+offset, 4096-offset, 4095-offset, fmt, valist);
|
||||
if(to_console)
|
||||
{
|
||||
if (nullptr != console_handle)
|
||||
{
|
||||
printf_s("%s", szTmp);
|
||||
fflush(stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(debug_mode)
|
||||
OutputDebugStringA(szTmp);
|
||||
}
|
||||
}
|
||||
#else
|
||||
vsnprintf(szTmp+offset, 4095-offset, fmt, valist);
|
||||
if(to_console)
|
||||
{
|
||||
vsnprintf(szTmp + offset, 4095 - offset, fmt, valist);
|
||||
if (to_console) {
|
||||
// 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.
|
||||
// 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);
|
||||
wprintf(L"%ls", _tmp.c_str());
|
||||
fflush(stdout);
|
||||
|
||||
// printf("%s", szTmp);
|
||||
// fflush(stdout);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
write_a(szTmp);
|
||||
write_a(szTmp);
|
||||
}
|
||||
|
||||
void ExLogger::log_w(int level, const wchar_t* fmt, va_list valist)
|
||||
{
|
||||
if (NULL == fmt || 0 == wcslen(fmt))
|
||||
return;
|
||||
void ExLogger::log_w(int level, const wchar_t* fmt, va_list valist) {
|
||||
if (nullptr == fmt || 0 == wcslen(fmt))
|
||||
return;
|
||||
|
||||
wchar_t szTmp[4096] = { 0 };
|
||||
size_t offset = 0;
|
||||
|
||||
if (level == EX_LOG_LEVEL_ERROR)
|
||||
{
|
||||
szTmp[0] = L'[';
|
||||
szTmp[1] = L'E';
|
||||
szTmp[2] = L']';
|
||||
szTmp[3] = L' ';
|
||||
offset = 4;
|
||||
}
|
||||
const char* _level = "";
|
||||
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]";
|
||||
|
||||
char prefix[100] = {0};
|
||||
#ifdef EX_OS_WIN32
|
||||
_vsnwprintf_s(szTmp+offset, 4096-offset, 4095-offset, fmt, valist);
|
||||
if(to_console)
|
||||
{
|
||||
if (NULL != console_handle)
|
||||
{
|
||||
wprintf_s(_T("%s"), szTmp);
|
||||
fflush(stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(debug_mode)
|
||||
OutputDebugStringW(szTmp);
|
||||
}
|
||||
}
|
||||
SYSTEMTIME st;
|
||||
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);
|
||||
// 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);
|
||||
#else
|
||||
vswprintf(szTmp+offset, 4095-offset, fmt, valist);
|
||||
if(to_console)
|
||||
{
|
||||
wprintf(L"%ls", szTmp);
|
||||
fflush(stdout);
|
||||
}
|
||||
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
|
||||
|
||||
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) \
|
||||
void fn(const char* fmt, ...) \
|
||||
{ \
|
||||
if(NULL == g_exlog) \
|
||||
if(nullptr == g_exlog) \
|
||||
return; \
|
||||
if (g_exlog->min_level > level) \
|
||||
return; \
|
||||
ExThreadSmartLock locker(g_exlog->lock); \
|
||||
va_list valist; \
|
||||
va_start(valist, fmt); \
|
||||
g_exlog->log_a(level, fmt, valist); \
|
||||
va_end(valist); \
|
||||
if (g_exlog->min_level > level) \
|
||||
return; \
|
||||
ExThreadSmartLock locker(g_exlog->lock); \
|
||||
va_list valist; \
|
||||
va_start(valist, fmt); \
|
||||
g_exlog->log_a(level, fmt, valist); \
|
||||
va_end(valist); \
|
||||
}
|
||||
|
||||
#define EX_PRINTF_XW(fn, level) \
|
||||
void fn(const wchar_t* fmt, ...) \
|
||||
{ \
|
||||
if(NULL == g_exlog) \
|
||||
if(nullptr == g_exlog) \
|
||||
return; \
|
||||
if (g_exlog->min_level > level) \
|
||||
return; \
|
||||
ExThreadSmartLock locker(g_exlog->lock); \
|
||||
va_list valist; \
|
||||
va_start(valist, fmt); \
|
||||
g_exlog->log_w(level, fmt, valist); \
|
||||
va_end(valist); \
|
||||
if (g_exlog->min_level > level) \
|
||||
return; \
|
||||
ExThreadSmartLock locker(g_exlog->lock); \
|
||||
va_list valist; \
|
||||
va_start(valist, fmt); \
|
||||
g_exlog->log_w(level, fmt, valist); \
|
||||
va_end(valist); \
|
||||
}
|
||||
|
||||
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_i, EX_LOG_LEVEL_INFO)
|
||||
|
||||
EX_PRINTF_XA(ex_printf_w, EX_LOG_LEVEL_WARN)
|
||||
|
||||
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_v, EX_LOG_LEVEL_VERBOSE)
|
||||
|
||||
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_e, EX_LOG_LEVEL_ERROR)
|
||||
|
||||
|
||||
#ifdef EX_OS_WIN32
|
||||
void ex_printf_e_lasterror(const char* fmt, ...)
|
||||
{
|
||||
ExThreadSmartLock locker(g_exlog->lock);
|
||||
ExThreadSmartLock locker(g_exlog->lock);
|
||||
|
||||
va_list valist;
|
||||
va_start(valist, fmt);
|
||||
g_exlog->log_a(EX_LOG_LEVEL_ERROR, fmt, valist);
|
||||
va_end(valist);
|
||||
va_list valist;
|
||||
va_start(valist, fmt);
|
||||
g_exlog->log_a(EX_LOG_LEVEL_ERROR, fmt, valist);
|
||||
va_end(valist);
|
||||
|
||||
//=========================================
|
||||
//=========================================
|
||||
|
||||
LPVOID lpMsgBuf;
|
||||
DWORD dw = GetLastError();
|
||||
LPVOID lpMsgBuf;
|
||||
DWORD dw = GetLastError();
|
||||
|
||||
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPSTR)&lpMsgBuf, 0, NULL);
|
||||
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
nullptr, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPSTR)&lpMsgBuf, 0, nullptr);
|
||||
|
||||
ex_printf_e(" - WinErr(%d): %s\n", dw, (LPSTR)lpMsgBuf);
|
||||
LocalFree(lpMsgBuf);
|
||||
ex_printf_e(" - WinErr(%d): %s\n", dw, (LPSTR)lpMsgBuf);
|
||||
LocalFree(lpMsgBuf);
|
||||
}
|
||||
|
||||
void ex_printf_e_lasterror(const wchar_t* fmt, ...)
|
||||
{
|
||||
ExThreadSmartLock locker(g_exlog->lock);
|
||||
ExThreadSmartLock locker(g_exlog->lock);
|
||||
|
||||
va_list valist;
|
||||
va_start(valist, fmt);
|
||||
g_exlog->log_w(EX_LOG_LEVEL_ERROR, fmt, valist);
|
||||
va_end(valist);
|
||||
va_list valist;
|
||||
va_start(valist, fmt);
|
||||
g_exlog->log_w(EX_LOG_LEVEL_ERROR, fmt, valist);
|
||||
va_end(valist);
|
||||
|
||||
//=========================================
|
||||
//=========================================
|
||||
|
||||
LPVOID lpMsgBuf;
|
||||
DWORD dw = GetLastError();
|
||||
LPVOID lpMsgBuf;
|
||||
DWORD dw = GetLastError();
|
||||
|
||||
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPSTR)&lpMsgBuf, 0, NULL);
|
||||
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
nullptr, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPSTR)&lpMsgBuf, 0, nullptr);
|
||||
|
||||
ex_printf_e(" - WinErr(%d): %s\n", dw, (LPSTR)lpMsgBuf);
|
||||
LocalFree(lpMsgBuf);
|
||||
ex_printf_e(" - WinErr(%d): %s\n", dw, (LPSTR)lpMsgBuf);
|
||||
LocalFree(lpMsgBuf);
|
||||
}
|
||||
#endif
|
||||
|
||||
void ex_printf_bin(const ex_u8* bin_data, size_t bin_size, const char* fmt, ...)
|
||||
{
|
||||
if(NULL == g_exlog)
|
||||
void ex_printf_bin(const ex_u8* bin_data, size_t bin_size, const char* fmt, ...) {
|
||||
if (nullptr == g_exlog)
|
||||
return;
|
||||
if (!g_exlog->debug_mode)
|
||||
return;
|
||||
if (!g_exlog->debug_mode)
|
||||
return;
|
||||
|
||||
ExThreadSmartLock locker(g_exlog->lock);
|
||||
ExThreadSmartLock locker(g_exlog->lock);
|
||||
|
||||
|
||||
|
||||
if (NULL == fmt)
|
||||
if (nullptr == fmt)
|
||||
return;
|
||||
if (0 == strlen(fmt))
|
||||
return;
|
||||
|
||||
char szTmp[128] = { 0 };
|
||||
// size_t offset = 0;
|
||||
char szTmp[128] = {0};
|
||||
|
||||
va_list valist;
|
||||
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
|
||||
va_end(valist);
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// 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);
|
||||
ex_printf_d("%s (%d/0x%02x Bytes)\n", szTmp, bin_size, bin_size);
|
||||
|
||||
const ex_u8* line = bin_data;
|
||||
size_t thisline = 0;
|
||||
size_t offset = 0;
|
||||
unsigned int i = 0;
|
||||
const ex_u8* line = bin_data;
|
||||
size_t offset = 0;
|
||||
while (offset < bin_size) {
|
||||
size_t _offset = 0;
|
||||
memset(szTmp, 0, 128);
|
||||
|
||||
// char szTmp[128] = { 0 };
|
||||
size_t _offset = 0;
|
||||
snprintf(szTmp + _offset, 128 - _offset, "%06x ", (int) offset);
|
||||
_offset += 8;
|
||||
|
||||
while (offset < bin_size)
|
||||
{
|
||||
memset(szTmp, 0, 128);
|
||||
_offset = 0;
|
||||
size_t this_line = bin_size - offset;
|
||||
if (this_line > 16)
|
||||
this_line = 16;
|
||||
|
||||
snprintf(szTmp + _offset, 128 - _offset, "%06x ", (int)offset);
|
||||
_offset += 8;
|
||||
size_t i = 0;
|
||||
for (; i < this_line; i++) {
|
||||
snprintf(szTmp + _offset, 128 - _offset, "%02x ", line[i]);
|
||||
_offset += 3;
|
||||
}
|
||||
|
||||
thisline = bin_size - offset;
|
||||
if (thisline > 16)
|
||||
thisline = 16;
|
||||
snprintf(szTmp + _offset, 128 - _offset, " ");
|
||||
_offset += 2;
|
||||
|
||||
for (i = 0; i < thisline; i++)
|
||||
{
|
||||
snprintf(szTmp + _offset, 128 - _offset, "%02x ", line[i]);
|
||||
_offset += 3;
|
||||
}
|
||||
for (; i < 16; i++) {
|
||||
snprintf(szTmp + _offset, 128 - _offset, " ");
|
||||
_offset += 3;
|
||||
}
|
||||
|
||||
snprintf(szTmp + _offset, 128 - _offset, " ");
|
||||
_offset += 2;
|
||||
for (i = 0; i < this_line; i++) {
|
||||
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, " ");
|
||||
_offset += 3;
|
||||
}
|
||||
snprintf(szTmp + _offset, 128 - _offset, "\n");
|
||||
|
||||
for (i = 0; i < thisline; i++)
|
||||
{
|
||||
snprintf(szTmp + _offset, 128 - _offset, "%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
|
||||
_offset += 1;
|
||||
}
|
||||
ex_printf_d("%s", szTmp);
|
||||
|
||||
snprintf(szTmp + _offset, 128 - _offset, "\n");
|
||||
_offset += 1;
|
||||
offset += this_line;
|
||||
line += this_line;
|
||||
}
|
||||
|
||||
ex_printf_d("%s", szTmp);
|
||||
|
||||
offset += thisline;
|
||||
line += thisline;
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
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)
|
||||
{
|
||||
m_max_filesize = max_filesize;
|
||||
m_max_count = 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_count = max_count;
|
||||
|
||||
m_filename = log_name;
|
||||
m_filename = log_name;
|
||||
|
||||
m_path = log_path;
|
||||
ex_abspath(m_path);
|
||||
m_path = log_path;
|
||||
ex_abspath(m_path);
|
||||
|
||||
ex_mkdirs(m_path);
|
||||
ex_mkdirs(m_path);
|
||||
|
||||
m_fullname = m_path;
|
||||
ex_path_join(m_fullname, false, log_name.c_str(), NULL);
|
||||
m_fullname = m_path;
|
||||
ex_path_join(m_fullname, false, log_name.c_str(), nullptr);
|
||||
|
||||
return _open_file();
|
||||
return _open_file();
|
||||
}
|
||||
|
||||
|
||||
bool ExLogger::_open_file()
|
||||
{
|
||||
if (m_file)
|
||||
{
|
||||
bool ExLogger::_open_file() {
|
||||
if (m_file) {
|
||||
#ifdef EX_OS_WIN32
|
||||
CloseHandle(m_file);
|
||||
CloseHandle(m_file);
|
||||
#else
|
||||
fclose(m_file);
|
||||
fclose(m_file);
|
||||
#endif
|
||||
m_file = NULL;
|
||||
}
|
||||
m_file = nullptr;
|
||||
}
|
||||
|
||||
#ifdef EX_OS_WIN32
|
||||
// 注意:这里必须使用 CreateFile() 来打开日志文件,使用FILE指针无法传递给动态库进行操作。
|
||||
m_file = CreateFileW(m_fullname.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (INVALID_HANDLE_VALUE == m_file)
|
||||
{
|
||||
m_file = NULL;
|
||||
return false;
|
||||
}
|
||||
// 注意:这里必须使用 CreateFile() 来打开日志文件,使用FILE指针无法传递给动态库进行操作。
|
||||
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)
|
||||
{
|
||||
m_file = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
SetFilePointer(m_file, 0, NULL, FILE_END);
|
||||
m_filesize = GetFileSize(m_file, NULL);
|
||||
SetFilePointer(m_file, 0, nullptr, FILE_END);
|
||||
m_filesize = GetFileSize(m_file, nullptr);
|
||||
#else
|
||||
ex_astr _fullname;
|
||||
ex_wstr2astr(m_fullname, _fullname);
|
||||
m_file = fopen(_fullname.c_str(), "a");
|
||||
ex_astr _fullname;
|
||||
ex_wstr2astr(m_fullname, _fullname);
|
||||
m_file = fopen(_fullname.c_str(), "a");
|
||||
|
||||
if (NULL == m_file)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (nullptr == m_file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek(m_file, 0, SEEK_END);
|
||||
m_filesize = (ex_u32)ftell(m_file);
|
||||
fseek(m_file, 0, SEEK_END);
|
||||
m_filesize = (ex_u32) ftell(m_file);
|
||||
#endif
|
||||
|
||||
return _rotate_file();
|
||||
return _rotate_file();
|
||||
}
|
||||
|
||||
bool ExLogger::_rotate_file(void)
|
||||
{
|
||||
if (m_filesize < m_max_filesize)
|
||||
return true;
|
||||
bool ExLogger::_rotate_file() {
|
||||
if (m_filesize < m_max_filesize)
|
||||
return true;
|
||||
|
||||
if (m_file)
|
||||
{
|
||||
if (m_file) {
|
||||
#ifdef EX_OS_WIN32
|
||||
CloseHandle(m_file);
|
||||
CloseHandle(m_file);
|
||||
#else
|
||||
fclose(m_file);
|
||||
fclose(m_file);
|
||||
#endif
|
||||
m_file = NULL;
|
||||
}
|
||||
m_file = nullptr;
|
||||
}
|
||||
|
||||
// make a name for backup file.
|
||||
wchar_t _tmpname[64] = { 0 };
|
||||
// make a name for backup file.
|
||||
wchar_t _tmpname[64] = {0};
|
||||
#ifdef EX_OS_WIN32
|
||||
SYSTEMTIME 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);
|
||||
SYSTEMTIME 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);
|
||||
#else
|
||||
time_t timep;
|
||||
time(&timep);
|
||||
struct tm *p = localtime(&timep);
|
||||
if (p == NULL)
|
||||
return false;
|
||||
time_t timep;
|
||||
time(&timep);
|
||||
struct tm* p = localtime(&timep);
|
||||
if (p == nullptr)
|
||||
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
|
||||
|
||||
ex_wstr _new_fullname(m_path);
|
||||
ex_path_join(_new_fullname, false, _tmpname, NULL);
|
||||
ex_wstr _new_fullname(m_path);
|
||||
ex_path_join(_new_fullname, false, _tmpname, nullptr);
|
||||
|
||||
#ifdef EX_OS_WIN32
|
||||
if (!MoveFileW(m_fullname.c_str(), _new_fullname.c_str()))
|
||||
{
|
||||
EXLOGE_WIN("can not rename log file, remove old one and try again.");
|
||||
DeleteFileW(_new_fullname.c_str());
|
||||
if (!MoveFileW(m_fullname.c_str(), _new_fullname.c_str()))
|
||||
return false;
|
||||
}
|
||||
if (!MoveFileW(m_fullname.c_str(), _new_fullname.c_str()))
|
||||
{
|
||||
EXLOGE_WIN("can not rename log file, remove old one and try again.");
|
||||
DeleteFileW(_new_fullname.c_str());
|
||||
if (!MoveFileW(m_fullname.c_str(), _new_fullname.c_str()))
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
ex_astr _a_fullname;
|
||||
ex_astr _a_new_fullname;
|
||||
ex_wstr2astr(m_fullname, _a_fullname);
|
||||
ex_wstr2astr(_new_fullname, _a_new_fullname);
|
||||
ex_astr _a_fullname;
|
||||
ex_astr _a_new_fullname;
|
||||
ex_wstr2astr(m_fullname, _a_fullname);
|
||||
ex_wstr2astr(_new_fullname, _a_new_fullname);
|
||||
|
||||
if (rename(_a_fullname.c_str(), _a_new_fullname.c_str()) != 0)
|
||||
{
|
||||
remove(_a_new_fullname.c_str());
|
||||
if (0 != (rename(_a_fullname.c_str(), _a_new_fullname.c_str())))
|
||||
return false;
|
||||
}
|
||||
if (rename(_a_fullname.c_str(), _a_new_fullname.c_str()) != 0) {
|
||||
remove(_a_new_fullname.c_str());
|
||||
if (0 != (rename(_a_fullname.c_str(), _a_new_fullname.c_str())))
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return _open_file();
|
||||
return _open_file();
|
||||
}
|
||||
|
||||
bool ExLogger::write_a(const char* buf)
|
||||
{
|
||||
if (NULL == m_file)
|
||||
return false;
|
||||
bool ExLogger::write_a(const char* buf) {
|
||||
if (nullptr == m_file)
|
||||
return false;
|
||||
|
||||
size_t len = strlen(buf);
|
||||
size_t len = strlen(buf);
|
||||
|
||||
if (len > EX_LOG_CONTENT_MAX_LEN)
|
||||
return false;
|
||||
if (len > EX_LOG_CONTENT_MAX_LEN)
|
||||
return false;
|
||||
|
||||
char szTime[100] = { 0 };
|
||||
#ifdef EX_OS_WIN32
|
||||
SYSTEMTIME st;
|
||||
GetLocalTime(&st);
|
||||
sprintf_s(szTime, 100, "[%04d-%02d-%02d %02d:%02d:%02d] ", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
|
||||
|
||||
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);
|
||||
WriteFile(m_file, buf, len, &dwWritten, nullptr);
|
||||
m_filesize += len;
|
||||
FlushFileBuffers(m_file);
|
||||
#else
|
||||
time_t timep;
|
||||
struct tm *p;
|
||||
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;
|
||||
fwrite(buf, len, 1, m_file);
|
||||
m_filesize += len;
|
||||
fflush(m_file);
|
||||
#endif
|
||||
|
||||
|
||||
return _rotate_file();
|
||||
return _rotate_file();
|
||||
}
|
||||
|
||||
bool ExLogger::write_w(const wchar_t* buf)
|
||||
{
|
||||
ex_astr _buf;
|
||||
ex_wstr2astr(buf, _buf, EX_CODEPAGE_UTF8);
|
||||
return write_a(_buf.c_str());
|
||||
bool ExLogger::write_w(const wchar_t* buf) {
|
||||
ex_astr _buf;
|
||||
ex_wstr2astr(buf, _buf, EX_CODEPAGE_UTF8);
|
||||
return write_a(_buf.c_str());
|
||||
}
|
||||
|
|
|
@ -214,11 +214,17 @@ int ex_atomic_dec(volatile int *pt) {
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
ex_u64 ex_get_thread_id() {
|
||||
#ifdef EX_OS_WIN32
|
||||
return GetCurrentThreadId();
|
||||
uint64_t ex_get_thread_id()
|
||||
{
|
||||
#if defined(EX_OS_WIN32)
|
||||
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
|
||||
return (ex_u64) pthread_self();
|
||||
# error "unsupport platform."
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -3,19 +3,20 @@
|
|||
#include <ex/ex_str.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
|
||||
const char *_lc_default = "en_US.UTF-8";
|
||||
const char *_lc_ctype = NULL;
|
||||
char *_loc = NULL;
|
||||
if (NULL == lc_ctype)
|
||||
const char *_lc_ctype = nullptr;
|
||||
char *_loc = nullptr;
|
||||
if (nullptr == lc_ctype)
|
||||
_lc_ctype = _lc_default;
|
||||
else
|
||||
_lc_ctype = lc_ctype;
|
||||
|
||||
_loc = setlocale(LC_CTYPE, _lc_ctype);
|
||||
|
||||
if (NULL == _loc)
|
||||
if (nullptr == _loc)
|
||||
return EX_FALSE;
|
||||
// if(0 != strcmp(_loc, _lc_ctype))
|
||||
// return EX_FALSE;
|
||||
|
@ -27,50 +28,61 @@ EX_BOOL ex_initialize(const char *lc_ctype) {
|
|||
}
|
||||
|
||||
|
||||
void ex_free(void *buffer) {
|
||||
if (NULL == buffer)
|
||||
void ex_free(void *buffer)
|
||||
{
|
||||
if (nullptr == buffer)
|
||||
return;
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
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 *ex_memmem(const ex_u8 *haystack, size_t haystacklen, const ex_u8 *needle, size_t needlelen)
|
||||
{
|
||||
const ex_u8 *cursor = nullptr;
|
||||
const ex_u8 *last_possible_needle_location = haystack + haystacklen - needlelen;
|
||||
|
||||
/** Easy answers */
|
||||
if (needlelen > haystacklen) return (NULL);
|
||||
if (needle == NULL) return (NULL);
|
||||
if (haystack == NULL) return (NULL);
|
||||
if (needlelen == 0) return (NULL);
|
||||
if (haystacklen == 0) return (NULL);
|
||||
if (needlelen > haystacklen)
|
||||
return (nullptr);
|
||||
if (needle == nullptr)
|
||||
return (nullptr);
|
||||
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)
|
||||
return cursor;
|
||||
}
|
||||
return (NULL);
|
||||
return (nullptr);
|
||||
}
|
||||
|
||||
void ex_mem_reverse(ex_u8 *p, size_t l) {
|
||||
ex_u8 temp = 0;
|
||||
size_t i = 0, j = 0;
|
||||
void ex_mem_reverse(ex_u8 *p, size_t l)
|
||||
{
|
||||
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];
|
||||
p[i] = p[j];
|
||||
p[j] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
void ex_printf(const char *fmt, ...) {
|
||||
if (NULL == fmt || 0 == strlen(fmt))
|
||||
void ex_printf(const char *fmt, ...)
|
||||
{
|
||||
if (nullptr == fmt || 0 == strlen(fmt))
|
||||
return;
|
||||
|
||||
va_list valist;
|
||||
va_start(valist, fmt);
|
||||
//_ts_printf_a(TS_COLOR_GRAY, TS_COLOR_BLACK, fmt, valist);
|
||||
|
||||
char _tmp[4096] = {0};
|
||||
char _tmp[4096] = { 0 };
|
||||
#ifdef EX_OS_WIN32
|
||||
vsnprintf_s(_tmp, 4096, 4095, fmt, valist);
|
||||
printf_s("%s", _tmp);
|
||||
|
@ -84,14 +96,15 @@ void ex_printf(const char *fmt, ...) {
|
|||
va_end(valist);
|
||||
}
|
||||
|
||||
void ex_wprintf(const wchar_t *fmt, ...) {
|
||||
if (NULL == fmt || 0 == wcslen(fmt))
|
||||
void ex_wprintf(const wchar_t *fmt, ...)
|
||||
{
|
||||
if (nullptr == fmt || 0 == wcslen(fmt))
|
||||
return;
|
||||
|
||||
va_list valist;
|
||||
va_start(valist, fmt);
|
||||
|
||||
wchar_t _tmp[4096] = {0};
|
||||
wchar_t _tmp[4096] = { 0 };
|
||||
#ifdef EX_OS_WIN32
|
||||
_vsnwprintf_s(_tmp, 4096, 4095, fmt, valist);
|
||||
wprintf_s(L"%s", _tmp);
|
||||
|
@ -109,7 +122,8 @@ void ex_wprintf(const wchar_t *fmt, ...) {
|
|||
va_end(valist);
|
||||
}
|
||||
|
||||
ex_u64 ex_get_tick_count(void) {
|
||||
ex_u64 ex_get_tick_count(void)
|
||||
{
|
||||
#ifdef EX_OS_WIN32
|
||||
# if (_WIN32_WINNT >= 0x0600)
|
||||
return GetTickCount64();
|
||||
|
@ -132,7 +146,8 @@ ex_u64 ex_get_tick_count(void) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void ex_sleep_ms(int ms) {
|
||||
void ex_sleep_ms(int ms)
|
||||
{
|
||||
#ifdef EX_OS_WIN32
|
||||
Sleep(ms);
|
||||
#else
|
||||
|
@ -140,8 +155,9 @@ void ex_sleep_ms(int ms) {
|
|||
#endif
|
||||
}
|
||||
|
||||
EX_BOOL ex_localtime_now(int *t, struct tm *dt) {
|
||||
// if (NULL == dt)
|
||||
EX_BOOL ex_localtime_now(int *t, struct tm *dt)
|
||||
{
|
||||
// if (nullptr == dt)
|
||||
// return EX_FALSE;
|
||||
|
||||
//struct tm *_tmp;
|
||||
|
@ -152,34 +168,35 @@ EX_BOOL ex_localtime_now(int *t, struct tm *dt) {
|
|||
_time32(&timep);
|
||||
if (0 != _localtime32_s(&_tmp, &timep))
|
||||
return EX_FALSE;
|
||||
if(NULL != dt)
|
||||
if(nullptr != dt)
|
||||
memcpy(dt, &_tmp, sizeof(struct tm));
|
||||
#else
|
||||
struct tm *_tmp;
|
||||
time_t timep;
|
||||
time_t timep;
|
||||
time(&timep);
|
||||
_tmp = localtime(&timep); //get server's time
|
||||
if (_tmp == NULL)
|
||||
if (_tmp == nullptr)
|
||||
return EX_FALSE;
|
||||
if (NULL != dt)
|
||||
if (nullptr != dt)
|
||||
memcpy(dt, _tmp, sizeof(struct tm));
|
||||
#endif
|
||||
|
||||
if (NULL != t)
|
||||
if (nullptr != t)
|
||||
*t = (int) timep;
|
||||
|
||||
return EX_TRUE;
|
||||
}
|
||||
|
||||
FILE *ex_fopen(const ex_wstr &filename, const wchar_t *mode) {
|
||||
FILE *f = NULL;
|
||||
FILE *ex_fopen(const ex_wstr &filename, const wchar_t *mode)
|
||||
{
|
||||
FILE *f = nullptr;
|
||||
#ifdef EX_OS_WIN32
|
||||
errno_t err = 0;
|
||||
err = _wfopen_s(&f, filename.c_str(), mode);
|
||||
if (0 == err)
|
||||
return f;
|
||||
else
|
||||
return NULL;
|
||||
return nullptr;
|
||||
#else
|
||||
ex_astr _fname;
|
||||
ex_wstr2astr(filename, _fname);
|
||||
|
@ -190,32 +207,35 @@ FILE *ex_fopen(const ex_wstr &filename, const wchar_t *mode) {
|
|||
#endif
|
||||
}
|
||||
|
||||
FILE* ex_fopen(const ex_astr& filename, const char* mode) {
|
||||
FILE *f = NULL;
|
||||
FILE *ex_fopen(const ex_astr &filename, const char *mode)
|
||||
{
|
||||
FILE *f = nullptr;
|
||||
#ifdef EX_OS_WIN32
|
||||
errno_t err = 0;
|
||||
err = fopen_s(&f, filename.c_str(), mode);
|
||||
if (0 == err)
|
||||
return f;
|
||||
else
|
||||
return NULL;
|
||||
errno_t err = 0;
|
||||
err = fopen_s(&f, filename.c_str(), mode);
|
||||
if (0 == err)
|
||||
return f;
|
||||
else
|
||||
return nullptr;
|
||||
#else
|
||||
f = fopen(filename.c_str(), mode);
|
||||
return f;
|
||||
f = fopen(filename.c_str(), mode);
|
||||
return f;
|
||||
#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;
|
||||
|
||||
FILE *f = ex_fopen(strFileName, L"rb");
|
||||
if (f == NULL)
|
||||
if (f == nullptr)
|
||||
return false;
|
||||
|
||||
fseek(f, 0L, SEEK_END);
|
||||
unsigned long ulFileSize = (unsigned long) ftell(f);
|
||||
if (-1 == ulFileSize) {
|
||||
if (-1 == ulFileSize)
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
@ -230,22 +250,27 @@ bool ex_read_text_file(const ex_wstr &strFileName, ex_astr& file_content) {
|
|||
|
||||
fclose(f);
|
||||
|
||||
if(ulRead != ulFileSize) {
|
||||
if (ulRead != ulFileSize)
|
||||
{
|
||||
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];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
file_content = &tmp[0];
|
||||
}
|
||||
|
||||
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");
|
||||
if (f == NULL)
|
||||
if (f == nullptr)
|
||||
return false;
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
EX_DYLIB_HANDLE ex_dlopen(const wchar_t *dylib_path) {
|
||||
EX_DYLIB_HANDLE handle = NULL;
|
||||
EX_DYLIB_HANDLE ex_dlopen(const wchar_t *dylib_path)
|
||||
{
|
||||
EX_DYLIB_HANDLE handle = nullptr;
|
||||
|
||||
#ifdef EX_OS_WIN32
|
||||
handle = LoadLibraryExW(dylib_path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
|
||||
if (NULL == handle)
|
||||
handle = LoadLibraryExW(dylib_path, nullptr, LOAD_WITH_ALTERED_SEARCH_PATH);
|
||||
if (nullptr == handle)
|
||||
{
|
||||
EXLOGE_WIN(L"LoadLibraryEx('%ls') failed.\n", dylib_path);
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
#else
|
||||
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");
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
handle = dlopen(path.c_str(), RTLD_NOW | RTLD_GLOBAL);
|
||||
|
||||
if (NULL == handle) {
|
||||
if (nullptr == handle)
|
||||
{
|
||||
EXLOGE("dlopen() failed: %s.\n", dlerror());
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void ex_dlclose(EX_DYLIB_HANDLE dylib) {
|
||||
void ex_dlclose(EX_DYLIB_HANDLE dylib)
|
||||
{
|
||||
#ifdef EX_OS_WIN32
|
||||
FreeLibrary(dylib);
|
||||
#else
|
||||
|
@ -294,7 +323,7 @@ void ex_dlclose(EX_DYLIB_HANDLE dylib) {
|
|||
// static const char fmt[] = "%u.%u.%u.%u";
|
||||
// char tmp[32];
|
||||
// int l;
|
||||
//
|
||||
//
|
||||
// l = snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]);
|
||||
// if (l <= 0 || (size_t) l >= size) {
|
||||
// return -1;
|
||||
|
@ -303,178 +332,193 @@ void ex_dlclose(EX_DYLIB_HANDLE dylib) {
|
|||
// dst[size - 1] = '\0';
|
||||
// return 0;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// int ex_ip4_name(const struct sockaddr_in *src, char *dst, size_t 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";
|
||||
int i;
|
||||
struct in_addr *addr = (struct in_addr *)src;
|
||||
u_long a = ntohl(addr->s_addr);
|
||||
const char *orig_dst = dst;
|
||||
const char digits[] = "0123456789";
|
||||
int i;
|
||||
struct in_addr *addr = (struct in_addr *) src;
|
||||
u_long a = ntohl(addr->s_addr);
|
||||
const char *orig_dst = dst;
|
||||
|
||||
if (size < EX_IPV4_NAME_LEN) {
|
||||
//errno = ENOSPC;
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < 4; ++i) {
|
||||
int n = (a >> (24 - i * 8)) & 0xFF;
|
||||
int non_zerop = 0;
|
||||
if (size < EX_IPV4_NAME_LEN)
|
||||
{
|
||||
//errno = ENOSPC;
|
||||
return nullptr;
|
||||
}
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
int n = (a >> (24 - i * 8)) & 0xFF;
|
||||
int non_zerop = 0;
|
||||
|
||||
if (non_zerop || n / 100 > 0) {
|
||||
*dst++ = digits[n / 100];
|
||||
n %= 100;
|
||||
non_zerop = 1;
|
||||
}
|
||||
if (non_zerop || n / 10 > 0) {
|
||||
*dst++ = digits[n / 10];
|
||||
n %= 10;
|
||||
non_zerop = 1;
|
||||
}
|
||||
*dst++ = digits[n];
|
||||
if (i != 3)
|
||||
*dst++ = '.';
|
||||
}
|
||||
*dst++ = '\0';
|
||||
return orig_dst;
|
||||
if (non_zerop || n / 100 > 0)
|
||||
{
|
||||
*dst++ = digits[n / 100];
|
||||
n %= 100;
|
||||
non_zerop = 1;
|
||||
}
|
||||
if (non_zerop || n / 10 > 0)
|
||||
{
|
||||
*dst++ = digits[n / 10];
|
||||
n %= 10;
|
||||
non_zerop = 1;
|
||||
}
|
||||
*dst++ = digits[n];
|
||||
if (i != 3)
|
||||
*dst++ = '.';
|
||||
}
|
||||
*dst++ = '\0';
|
||||
return orig_dst;
|
||||
}
|
||||
|
||||
#define IN6ADDRSZ 16
|
||||
#define IN6ADDRSZ 16
|
||||
#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
|
||||
* 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.
|
||||
* Keep this in mind if you think this function should have been coded
|
||||
* to use pointer overlays. All the world's not a VAX.
|
||||
*/
|
||||
char tmp[EX_IPV6_NAME_LEN];
|
||||
char *tp;
|
||||
struct {
|
||||
long base;
|
||||
long len;
|
||||
} best, cur;
|
||||
u_long words[IN6ADDRSZ / INT16SZ];
|
||||
int i;
|
||||
/*
|
||||
* 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
|
||||
* 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
|
||||
* to use pointer overlays. All the world's not a VAX.
|
||||
*/
|
||||
char tmp[EX_IPV6_NAME_LEN];
|
||||
char *tp;
|
||||
struct
|
||||
{
|
||||
long base;
|
||||
long len;
|
||||
} best, cur;
|
||||
u_long words[IN6ADDRSZ / INT16SZ];
|
||||
int i;
|
||||
|
||||
/* Preprocess:
|
||||
* Copy the input (bytewise) array into a wordwise array.
|
||||
* Find the longest run of 0x00's in src[] for :: shorthanding.
|
||||
*/
|
||||
memset(words, 0, sizeof(words));
|
||||
for (i = 0; i < IN6ADDRSZ; i++)
|
||||
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
|
||||
/* Preprocess:
|
||||
* Copy the input (bytewise) array into a wordwise array.
|
||||
* Find the longest run of 0x00's in src[] for :: shorthanding.
|
||||
*/
|
||||
memset(words, 0, sizeof(words));
|
||||
for (i = 0; i < IN6ADDRSZ; i++)
|
||||
{
|
||||
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
|
||||
}
|
||||
|
||||
best.base = -1;
|
||||
cur.base = -1;
|
||||
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
|
||||
{
|
||||
if (words[i] == 0)
|
||||
{
|
||||
if (cur.base == -1) {
|
||||
best.base = -1;
|
||||
cur.base = -1;
|
||||
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
|
||||
{
|
||||
if (words[i] == 0)
|
||||
{
|
||||
if (cur.base == -1)
|
||||
{
|
||||
cur.base = i;
|
||||
cur.len = 1;
|
||||
cur.len = 1;
|
||||
}
|
||||
else{
|
||||
else
|
||||
{
|
||||
cur.len++;
|
||||
}
|
||||
}
|
||||
else if (cur.base != -1)
|
||||
{
|
||||
if (best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
cur.base = -1;
|
||||
}
|
||||
}
|
||||
if ((cur.base != -1) && (best.base == -1 || cur.len > best.len))
|
||||
best = cur;
|
||||
if (best.base != -1 && best.len < 2)
|
||||
best.base = -1;
|
||||
}
|
||||
else if (cur.base != -1)
|
||||
{
|
||||
if (best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
cur.base = -1;
|
||||
}
|
||||
}
|
||||
if ((cur.base != -1) && (best.base == -1 || cur.len > best.len))
|
||||
best = cur;
|
||||
if (best.base != -1 && best.len < 2)
|
||||
best.base = -1;
|
||||
|
||||
/* Format the result.
|
||||
*/
|
||||
tp = tmp;
|
||||
size_t tmp_size = 0;
|
||||
size_t offset = 0;
|
||||
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
|
||||
{
|
||||
/* Are we inside the best run of 0x00's?
|
||||
*/
|
||||
if (best.base != -1 && i >= best.base && i < (best.base + best.len))
|
||||
{
|
||||
if (i == best.base) {
|
||||
*tp++ = ':';
|
||||
offset += 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
/* Format the result.
|
||||
*/
|
||||
tp = tmp;
|
||||
size_t tmp_size = 0;
|
||||
size_t offset = 0;
|
||||
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
|
||||
{
|
||||
/* Are we inside the best run of 0x00's?
|
||||
*/
|
||||
if (best.base != -1 && i >= best.base && i < (best.base + best.len))
|
||||
{
|
||||
if (i == best.base)
|
||||
{
|
||||
*tp++ = ':';
|
||||
offset += 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Are we following an initial run of 0x00s or any real hex?
|
||||
*/
|
||||
if (i != 0) {
|
||||
*tp++ = ':';
|
||||
offset += 1;
|
||||
}
|
||||
/* Are we following an initial run of 0x00s or any real hex?
|
||||
*/
|
||||
if (i != 0)
|
||||
{
|
||||
*tp++ = ':';
|
||||
offset += 1;
|
||||
}
|
||||
|
||||
/* Is this address an encapsulated IPv4?
|
||||
*/
|
||||
if (i == 6 && best.base == 0 &&
|
||||
(best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
|
||||
{
|
||||
if (!_inet_ntop_v4(src + 12, tp, sizeof(tmp) - (tp - tmp)))
|
||||
{
|
||||
//errno = ENOSPC;
|
||||
return (NULL);
|
||||
}
|
||||
tmp_size = strlen(tp);
|
||||
tp += tmp_size;
|
||||
offset += tmp_size;
|
||||
break;
|
||||
}
|
||||
//tp += ex_strformat(tp, "%lX", words[i]);
|
||||
tmp_size = ex_strformat(tp, EX_IPV6_NAME_LEN-offset, "%lX", words[i]);
|
||||
tp += tmp_size;
|
||||
offset += tmp_size;
|
||||
}
|
||||
/* Is this address an encapsulated IPv4?
|
||||
*/
|
||||
if (i == 6 && best.base == 0 &&
|
||||
(best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
|
||||
{
|
||||
if (!_inet_ntop_v4(src + 12, tp, sizeof(tmp) - (tp - tmp)))
|
||||
{
|
||||
//errno = ENOSPC;
|
||||
return (nullptr);
|
||||
}
|
||||
tmp_size = strlen(tp);
|
||||
tp += tmp_size;
|
||||
offset += tmp_size;
|
||||
break;
|
||||
}
|
||||
//tp += ex_strformat(tp, "%lX", words[i]);
|
||||
tmp_size = ex_strformat(tp, EX_IPV6_NAME_LEN - offset, "%lX", words[i]);
|
||||
tp += tmp_size;
|
||||
offset += tmp_size;
|
||||
}
|
||||
|
||||
/* Was it a trailing run of 0x00's?
|
||||
*/
|
||||
if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
|
||||
*tp++ = ':';
|
||||
*tp++ = '\0';
|
||||
/* Was it a trailing run of 0x00's?
|
||||
*/
|
||||
if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
|
||||
*tp++ = ':';
|
||||
*tp++ = '\0';
|
||||
|
||||
/* Check for overflow, copy, and we're done.
|
||||
*/
|
||||
if ((size_t)(tp - tmp) > size)
|
||||
{
|
||||
//errno = ENOSPC;
|
||||
return (NULL);
|
||||
}
|
||||
//return strcpy(dst, tmp);
|
||||
return ex_strcpy(dst, size, tmp);
|
||||
//return (NULL);
|
||||
/* Check for overflow, copy, and we're done.
|
||||
*/
|
||||
if ((size_t) (tp - tmp) > size)
|
||||
{
|
||||
//errno = ENOSPC;
|
||||
return (nullptr);
|
||||
}
|
||||
//return strcpy(dst, tmp);
|
||||
return ex_strcpy(dst, size, tmp);
|
||||
//return (nullptr);
|
||||
}
|
||||
|
||||
const char* ex_inet_ntop(int af, const void *src, char *dst, size_t size) {
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return _inet_ntop_v4(src, dst, size);
|
||||
case AF_INET6:
|
||||
return _inet_ntop_v6((const ex_u8*)src, dst, size);
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return NULL;
|
||||
}
|
||||
const char *ex_inet_ntop(int af, const void *src, char *dst, size_t size)
|
||||
{
|
||||
switch (af)
|
||||
{
|
||||
case AF_INET:
|
||||
return _inet_ntop_v4(src, dst, size);
|
||||
case AF_INET6:
|
||||
return _inet_ntop_v6((const ex_u8 *) src, dst, size);
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
return 0;
|
||||
int ex_ip4_name(const struct sockaddr_in *src, char *dst, size_t size)
|
||||
{
|
||||
if (nullptr == _inet_ntop_v4((const unsigned char *) &(src->sin_addr), dst, size))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,142 +11,143 @@
|
|||
//=======================================================
|
||||
// Urlprotocol相关
|
||||
//=======================================================
|
||||
#define TP_URLPROTO_APP_NAME "teleport"
|
||||
#define TP_URLPROTO_APP_NAME "teleport"
|
||||
|
||||
//=======================================================
|
||||
// 远程连接认证方式
|
||||
//=======================================================
|
||||
#define TP_AUTH_TYPE_NONE 0
|
||||
#define TP_AUTH_TYPE_PASSWORD 1
|
||||
#define TP_AUTH_TYPE_PRIVATE_KEY 2
|
||||
#define TP_AUTH_TYPE_NONE 0
|
||||
#define TP_AUTH_TYPE_PASSWORD 1
|
||||
#define TP_AUTH_TYPE_PRIVATE_KEY 2
|
||||
|
||||
//=======================================================
|
||||
// 远程连接协议
|
||||
//=======================================================
|
||||
#define TP_PROTOCOL_TYPE_RDP 1
|
||||
#define TP_PROTOCOL_TYPE_SSH 2
|
||||
#define TP_PROTOCOL_TYPE_TELNET 3
|
||||
#define TP_PROTOCOL_TYPE_RDP 1
|
||||
#define TP_PROTOCOL_TYPE_SSH 2
|
||||
#define TP_PROTOCOL_TYPE_TELNET 3
|
||||
|
||||
//=======================================================
|
||||
// 远程连接子协议
|
||||
//=======================================================
|
||||
#define TP_PROTOCOL_TYPE_RDP_DESKTOP 100
|
||||
#define TP_PROTOCOL_TYPE_SSH_SHELL 200
|
||||
#define TP_PROTOCOL_TYPE_SSH_SFTP 201
|
||||
#define TP_PROTOCOL_TYPE_TELNET_SHELL 300
|
||||
#define TP_PROTOCOL_TYPE_RDP_DESKTOP 100
|
||||
#define TP_PROTOCOL_TYPE_SSH_SHELL 200
|
||||
#define TP_PROTOCOL_TYPE_SSH_SFTP 201
|
||||
#define TP_PROTOCOL_TYPE_TELNET_SHELL 300
|
||||
|
||||
|
||||
//=======================================================
|
||||
// 远程主机操作系统
|
||||
//=======================================================
|
||||
#define TP_OS_TYPE_WINDOWS 1
|
||||
#define TP_OS_TYPE_LINUX 2
|
||||
#define TP_OS_TYPE_WINDOWS 1
|
||||
#define TP_OS_TYPE_LINUX 2
|
||||
|
||||
//=======================================================
|
||||
// 远程连接会话状态
|
||||
//=======================================================
|
||||
#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_CONNECT 2 // 会话结束,因为无法连接到远程主机
|
||||
#define TP_SESS_STAT_ERR_BAD_SSH_KEY 3 // 会话结束,因为无法识别SSH私钥
|
||||
#define TP_SESS_STAT_ERR_INTERNAL 4 // 会话结束,因为内部错误
|
||||
#define TP_SESS_STAT_ERR_UNSUPPORT_PROTOCOL 5 // 会话结束,因为协议不支持(RDP)
|
||||
#define TP_SESS_STAT_ERR_BAD_PKG 6 // 会话结束,因为收到错误的报文
|
||||
#define TP_SESS_STAT_ERR_RESET 7 // 会话结束,因为teleport核心服务重置了
|
||||
#define TP_SESS_STAT_ERR_IO 8 // 会话结束,因为网络中断
|
||||
#define TP_SESS_STAT_ERR_SESSION 9 // 会话结束,因为无效的会话ID
|
||||
#define TP_SESS_STAT_ERR_AUTH_TYPE 10 // 会话结束,因为不被允许的认证方式
|
||||
#define TP_SESS_STAT_RUNNING 0 // 会话开始了,正在连接
|
||||
#define TP_SESS_STAT_ERR_AUTH_DENIED 1 // 会话结束,因为认证失败
|
||||
#define TP_SESS_STAT_ERR_CONNECT 2 // 会话结束,因为无法连接到远程主机
|
||||
#define TP_SESS_STAT_ERR_BAD_SSH_KEY 3 // 会话结束,因为无法识别SSH私钥
|
||||
#define TP_SESS_STAT_ERR_INTERNAL 4 // 会话结束,因为内部错误
|
||||
#define TP_SESS_STAT_ERR_UNSUPPORT_PROTOCOL 5 // 会话结束,因为协议不支持(RDP)
|
||||
#define TP_SESS_STAT_ERR_BAD_PKG 6 // 会话结束,因为收到错误的报文
|
||||
#define TP_SESS_STAT_ERR_RESET 7 // 会话结束,因为teleport核心服务重置了
|
||||
#define TP_SESS_STAT_ERR_IO 8 // 会话结束,因为网络中断
|
||||
#define TP_SESS_STAT_ERR_SESSION 9 // 会话结束,因为无效的会话ID
|
||||
#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_ERR_START_INTERNAL 104 // 会话结束,因为内部错误
|
||||
#define TP_SESS_STAT_ERR_START_BAD_PKG 106 // 会话结束,因为收到错误的报文
|
||||
#define TP_SESS_STAT_ERR_START_RESET 107 // 会话结束,因为teleport核心服务重置了
|
||||
#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_REAL_TIME 0x00000002 // 允许实时监控
|
||||
#define TP_FLAG_RECORD_REPLAY 0x00000001 // 允许记录历史(录像回放)
|
||||
#define TP_FLAG_RECORD_REAL_TIME 0x00000002 // 允许实时监控
|
||||
// RDP相关
|
||||
#define TP_FLAG_RDP_DESKTOP 0x00000001 // 允许远程桌面
|
||||
#define TP_FLAG_RDP_CLIPBOARD 0x00000002 // 允许剪贴板
|
||||
#define TP_FLAG_RDP_DISK 0x00000004 // 允许磁盘映射
|
||||
#define TP_FLAG_RDP_APP 0x00000008 // 允许远程APP(尚未实现)
|
||||
#define TP_FLAG_RDP_CONSOLE 0x00001000 //允许连接到管理员会话(RDP的console选项)
|
||||
#define TP_FLAG_RDP_DESKTOP 0x00000001 // 允许远程桌面
|
||||
#define TP_FLAG_RDP_CLIPBOARD 0x00000002 // 允许剪贴板
|
||||
#define TP_FLAG_RDP_DISK 0x00000004 // 允许磁盘映射
|
||||
#define TP_FLAG_RDP_APP 0x00000008 // 允许远程APP(尚未实现)
|
||||
#define TP_FLAG_RDP_CONSOLE 0x00001000 // 允许连接到管理员会话(RDP的console选项)
|
||||
// SSH相关
|
||||
#define TP_FLAG_SSH_SHELL 0x00000001 // 允许SHELL
|
||||
#define TP_FLAG_SSH_SFTP 0x00000002 // 允许SFTP
|
||||
#define TP_FLAG_SSH_X11 0x00000004 // 允许X11转发(尚未实现)
|
||||
#define TP_FLAG_SSH_EXEC 0x00000008 // 允许exec执行远程命令(尚未实现)
|
||||
#define TP_FLAG_SSH_TUNNEL 0x00000010 // allow ssh tunnel. (not impl.)
|
||||
#define TP_FLAG_SSH_SHELL 0x00000001 // 允许SHELL
|
||||
#define TP_FLAG_SSH_SFTP 0x00000002 // 允许SFTP
|
||||
#define TP_FLAG_SSH_X11 0x00000004 // 允许X11转发(尚未实现)
|
||||
#define TP_FLAG_SSH_EXEC 0x00000008 // 允许exec执行远程命令(尚未实现)
|
||||
#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_LOGIN 2 // 需要登录
|
||||
#define TPE_PRIVILEGE 3 // 没有操作权限
|
||||
#define TPE_NOT_IMPLEMENT 7 // 功能尚未实现
|
||||
#define TPE_EXISTS 8 // 目标已经存在
|
||||
#define TPE_NOT_EXISTS 9 // 目标不存在
|
||||
#define TPE_NEED_MORE_DATA 1 // 需要更多数据(不一定是错误)
|
||||
#define TPE_NEED_LOGIN 2 // 需要登录
|
||||
#define TPE_PRIVILEGE 3 // 没有操作权限
|
||||
#define TPE_NOT_IMPLEMENT 7 // 功能尚未实现
|
||||
#define TPE_EXISTS 8 // 目标已经存在
|
||||
#define TPE_NOT_EXISTS 9 // 目标不存在
|
||||
|
||||
// 100~299是通用错误值
|
||||
|
||||
#define TPE_FAILED 100 // 内部错误
|
||||
#define TPE_NETWORK 101 // 网络错误
|
||||
#define TPE_DATABASE 102 // 数据库操作失败
|
||||
#define TPE_FAILED 100 // 内部错误
|
||||
#define TPE_NETWORK 101 // 网络错误
|
||||
#define TPE_DATABASE 102 // 数据库操作失败
|
||||
|
||||
// HTTP请求相关错误
|
||||
#define TPE_HTTP_METHOD 120 // 无效的请求方法(不是GET/POST等),或者错误的请求方法(例如需要POST,却使用GET方式请求)
|
||||
#define TPE_HTTP_URL_ENCODE 121 // URL编码错误(无法解码)
|
||||
//#define TPE_HTTP_URI 122 // 无效的URI
|
||||
#define TPE_HTTP_METHOD 120 // 无效的请求方法(不是GET/POST等),或者错误的请求方法(例如需要POST,却使用GET方式请求)
|
||||
#define TPE_HTTP_URL_ENCODE 121 // URL编码错误(无法解码)
|
||||
//#define TPE_HTTP_URI 122 // 无效的URI
|
||||
|
||||
#define TPE_UNKNOWN_CMD 124 // 未知的命令
|
||||
#define TPE_JSON_FORMAT 125 // 错误的JSON格式(需要JSON格式数据,但是却无法按JSON格式解码)
|
||||
#define TPE_PARAM 126 // 参数错误
|
||||
#define TPE_INVALID_DATA 127 // 数据错误
|
||||
#define TPE_UNEXPECTED_DATA 128 // 不是期望的数据
|
||||
#define TPE_UNKNOWN_CMD 124 // 未知的命令
|
||||
#define TPE_JSON_FORMAT 125 // 错误的JSON格式(需要JSON格式数据,但是却无法按JSON格式解码)
|
||||
#define TPE_PARAM 126 // 参数错误
|
||||
#define TPE_INVALID_DATA 127 // 数据错误
|
||||
#define TPE_UNEXPECTED_DATA 128 // 不是期望的数据
|
||||
|
||||
// #define TPE_OPENFILE_ERROR 0x1007 // 无法打开文件
|
||||
// #define TPE_GETTEMPPATH_ERROR 0x1007
|
||||
#define TPE_OPENFILE 300
|
||||
// #define TPE_OPENFILE_ERROR 0x1007 // 无法打开文件
|
||||
// #define TPE_GETTEMPPATH_ERROR 0x1007
|
||||
#define TPE_OPENFILE 300
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// WEB服务专用错误值
|
||||
//-------------------------------------------------------
|
||||
#define TPE_CAPTCHA_EXPIRED 10000 // 验证码已过期
|
||||
#define TPE_CAPTCHA_MISMATCH 10001 // 验证码错误
|
||||
#define TPE_OATH_MISMATCH 10002 // 身份验证器动态验证码错误
|
||||
#define TPE_SYS_MAINTENANCE 10003 // 系统维护中
|
||||
#define TPE_CAPTCHA_EXPIRED 10000 // 验证码已过期
|
||||
#define TPE_CAPTCHA_MISMATCH 10001 // 验证码错误
|
||||
#define TPE_OATH_MISMATCH 10002 // 身份验证器动态验证码错误
|
||||
#define TPE_SYS_MAINTENANCE 10003 // 系统维护中
|
||||
|
||||
#define TPE_USER_LOCKED 10100 // 用户已经被锁定(连续多次错误密码)
|
||||
#define TPE_USER_DISABLED 10101 // 用户已经被禁用
|
||||
#define TPE_USER_AUTH 10102 // 身份验证失败
|
||||
#define TPE_USER_LOCKED 10100 // 用户已经被锁定(连续多次错误密码)
|
||||
#define TPE_USER_DISABLED 10101 // 用户已经被禁用
|
||||
#define TPE_USER_AUTH 10102 // 身份验证失败
|
||||
|
||||
//-------------------------------------------------------
|
||||
// 助手程序专用错误值
|
||||
//-------------------------------------------------------
|
||||
#define TPE_NO_ASSIST 100000 // 未能检测到助手程序
|
||||
#define TPE_OLD_ASSIST 100001 // 助手程序版本太低
|
||||
#define TPE_START_CLIENT 100002 // 无法启动客户端程序(无法创建进程)
|
||||
#define TPE_NO_ASSIST 100000 // 未能检测到助手程序
|
||||
#define TPE_OLD_ASSIST 100001 // 助手程序版本太低
|
||||
#define TPE_START_CLIENT 100002 // 无法启动客户端程序(无法创建进程)
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// 核心服务专用错误值
|
||||
//-------------------------------------------------------
|
||||
#define TPE_NO_CORE_SERVER 200000 // 未能检测到核心服务
|
||||
|
||||
#define TPE_NO_CORE_SERVER 200000 // 未能检测到核心服务
|
||||
|
||||
|
||||
#endif // __TELEPORT_CONST_H__
|
||||
|
|
|
@ -1,48 +1,46 @@
|
|||
#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)
|
||||
{
|
||||
if (NULL == args)
|
||||
{
|
||||
EXLOGE("invalid init args(1).\n");
|
||||
return false;
|
||||
}
|
||||
bool TppEnvBase::init(TPP_INIT_ARGS* args) {
|
||||
if (nullptr == args) {
|
||||
EXLOGE("invalid init args(1).\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
EXLOG_USE_LOGGER(args->logger);
|
||||
EXLOG_USE_LOGGER(args->logger);
|
||||
|
||||
exec_path = args->exec_path;
|
||||
etc_path = args->etc_path;
|
||||
replay_path = args->replay_path;
|
||||
exec_path = args->exec_path;
|
||||
etc_path = args->etc_path;
|
||||
replay_path = args->replay_path;
|
||||
|
||||
get_connect_info = args->func_get_connect_info;
|
||||
free_connect_info = args->func_free_connect_info;
|
||||
session_begin = args->func_session_begin;
|
||||
session_update = args->func_session_update;
|
||||
session_end = args->func_session_end;
|
||||
get_connect_info = args->func_get_connect_info;
|
||||
free_connect_info = args->func_free_connect_info;
|
||||
session_begin = args->func_session_begin;
|
||||
session_update = args->func_session_update;
|
||||
session_end = args->func_session_end;
|
||||
|
||||
if (NULL == get_connect_info || NULL == free_connect_info || NULL == session_begin || NULL == session_update || NULL == session_end)
|
||||
{
|
||||
EXLOGE("invalid init args(2).\n");
|
||||
return false;
|
||||
}
|
||||
if (!get_connect_info || !free_connect_info || !session_begin || !session_update || !session_end) {
|
||||
EXLOGE("invalid init args(2).\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NULL == args->cfg)
|
||||
{
|
||||
EXLOGE("invalid init args(3).\n");
|
||||
return false;
|
||||
}
|
||||
if (nullptr == args->cfg) {
|
||||
EXLOGE("invalid init args(3).\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_on_init(args))
|
||||
{
|
||||
EXLOGE("invalid init args(4).\n");
|
||||
return false;
|
||||
}
|
||||
if (!_on_init(args)) {
|
||||
EXLOGE("invalid init args(4).\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -3,27 +3,27 @@
|
|||
|
||||
#include "protocol_interface.h"
|
||||
|
||||
class TppEnvBase
|
||||
{
|
||||
class TppEnvBase {
|
||||
public:
|
||||
TppEnvBase();
|
||||
virtual ~TppEnvBase();
|
||||
TppEnvBase();
|
||||
|
||||
bool init(TPP_INIT_ARGS* args);
|
||||
virtual ~TppEnvBase();
|
||||
|
||||
bool init(TPP_INIT_ARGS* args);
|
||||
|
||||
public:
|
||||
ex_wstr exec_path;
|
||||
ex_wstr etc_path; // 配置文件、SSH服务器的私钥文件的存放路径
|
||||
ex_wstr replay_path;
|
||||
ex_wstr exec_path;
|
||||
ex_wstr etc_path; // 配置文件、SSH服务器的私钥文件的存放路径
|
||||
ex_wstr replay_path;
|
||||
|
||||
TPP_GET_CONNNECT_INFO_FUNC get_connect_info;
|
||||
TPP_FREE_CONNECT_INFO_FUNC free_connect_info;
|
||||
TPP_SESSION_BEGIN_FUNC session_begin;
|
||||
TPP_SESSION_UPDATE_FUNC session_update;
|
||||
TPP_SESSION_END_FUNC session_end;
|
||||
TPP_GET_CONNECT_INFO_FUNC get_connect_info;
|
||||
TPP_FREE_CONNECT_INFO_FUNC free_connect_info;
|
||||
TPP_SESSION_BEGIN_FUNC session_begin;
|
||||
TPP_SESSION_UPDATE_FUNC session_update;
|
||||
TPP_SESSION_END_FUNC session_end;
|
||||
|
||||
protected:
|
||||
virtual bool _on_init(TPP_INIT_ARGS* args) = 0;
|
||||
virtual bool _on_init(TPP_INIT_ARGS* args) = 0;
|
||||
};
|
||||
|
||||
#endif // __TS_BASE_ENV_H__
|
||||
|
|
|
@ -14,87 +14,87 @@
|
|||
# define TPP_API
|
||||
#endif
|
||||
|
||||
#define TPP_CMD_INIT 0x00000000
|
||||
#define TPP_CMD_SET_RUNTIME_CFG 0x00000005
|
||||
#define TPP_CMD_KILL_SESSIONS 0x00000006
|
||||
#define TPP_CMD_INIT 0x00000000
|
||||
#define TPP_CMD_SET_RUNTIME_CFG 0x00000005
|
||||
#define TPP_CMD_KILL_SESSIONS 0x00000006
|
||||
|
||||
typedef struct TPP_CONNECT_INFO
|
||||
{
|
||||
char* sid;
|
||||
typedef struct TPP_CONNECT_INFO {
|
||||
char* sid;
|
||||
|
||||
// 与此连接信息相关的三个要素的ID
|
||||
int user_id;
|
||||
int host_id;
|
||||
int acc_id;
|
||||
// 与此连接信息相关的三个要素的ID
|
||||
int user_id;
|
||||
int host_id;
|
||||
int acc_id;
|
||||
|
||||
char* user_username; // 申请本次连接的用户名
|
||||
char* user_username; // 申请本次连接的用户名
|
||||
|
||||
char* host_ip; // 真正的远程主机IP(如果是直接连接模式,则与remote_host_ip相同)
|
||||
char* conn_ip; // 要连接的远程主机的IP(如果是端口映射模式,则为路由主机的IP)
|
||||
int conn_port; // 要连接的远程主机的端口(如果是端口映射模式,则为路由主机的端口)
|
||||
char* client_ip;
|
||||
char* host_ip; // 真正的远程主机IP(如果是直接连接模式,则与remote_host_ip相同)
|
||||
char* conn_ip; // 要连接的远程主机的IP(如果是端口映射模式,则为路由主机的IP)
|
||||
int conn_port; // 要连接的远程主机的端口(如果是端口映射模式,则为路由主机的端口)
|
||||
char* client_ip;
|
||||
|
||||
char* acc_username; // 远程主机的账号
|
||||
char* acc_secret; // 远程主机账号的密码(或者私钥)
|
||||
char* username_prompt; // for telnet
|
||||
char* password_prompt; // for telnet
|
||||
char* acc_username; // 远程主机的账号
|
||||
char* acc_secret; // 远程主机账号的密码(或者私钥)
|
||||
char* username_prompt; // for telnet
|
||||
char* password_prompt; // for telnet
|
||||
|
||||
int protocol_type;
|
||||
int protocol_sub_type;
|
||||
int protocol_flag;
|
||||
int record_flag;
|
||||
int auth_type;
|
||||
}TPP_CONNECT_INFO;
|
||||
int protocol_type;
|
||||
int protocol_sub_type;
|
||||
int protocol_flag;
|
||||
int record_flag;
|
||||
int auth_type;
|
||||
} TPP_CONNECT_INFO;
|
||||
|
||||
typedef TPP_CONNECT_INFO* (*TPP_GET_CONNNECT_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 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 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 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
|
||||
{
|
||||
ExLogger* logger;
|
||||
ex_wstr exec_path;
|
||||
ex_wstr etc_path;
|
||||
ex_wstr replay_path;
|
||||
ExIniFile* cfg;
|
||||
typedef struct TPP_INIT_ARGS {
|
||||
ExLogger* logger;
|
||||
ex_wstr exec_path;
|
||||
ex_wstr etc_path;
|
||||
ex_wstr replay_path;
|
||||
ExIniFile* cfg;
|
||||
|
||||
TPP_GET_CONNNECT_INFO_FUNC func_get_connect_info;
|
||||
TPP_FREE_CONNECT_INFO_FUNC func_free_connect_info;
|
||||
TPP_SESSION_BEGIN_FUNC func_session_begin;
|
||||
TPP_SESSION_UPDATE_FUNC func_session_update;
|
||||
TPP_SESSION_END_FUNC func_session_end;
|
||||
}TPP_INIT_ARGS;
|
||||
|
||||
// typedef struct TPP_SET_CFG_ARGS {
|
||||
// ex_u32 noop_timeout; // as second.
|
||||
// }TPP_SET_CFG_ARGS;
|
||||
TPP_GET_CONNECT_INFO_FUNC func_get_connect_info;
|
||||
TPP_FREE_CONNECT_INFO_FUNC func_free_connect_info;
|
||||
TPP_SESSION_BEGIN_FUNC func_session_begin;
|
||||
TPP_SESSION_UPDATE_FUNC func_session_update;
|
||||
TPP_SESSION_END_FUNC func_session_end;
|
||||
} TPP_INIT_ARGS;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
TPP_API ex_rv tpp_init(TPP_INIT_ARGS* init_args);
|
||||
TPP_API ex_rv tpp_start(void);
|
||||
TPP_API ex_rv tpp_stop(void);
|
||||
TPP_API void tpp_timer(void);
|
||||
// TPP_API void tpp_set_cfg(TPP_SET_CFG_ARGS* cfg_args);
|
||||
TPP_API ex_rv tpp_init(TPP_INIT_ARGS* init_args);
|
||||
TPP_API ex_rv tpp_start(void);
|
||||
TPP_API ex_rv tpp_stop(void);
|
||||
TPP_API void tpp_timer(void);
|
||||
|
||||
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
|
||||
}
|
||||
#endif
|
||||
|
||||
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_INIT_FUNC)(TPP_INIT_ARGS* init_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__
|
||||
|
|
|
@ -28,7 +28,7 @@ static ex_u8 g_run_type = RUN_UNKNOWN;
|
|||
|
||||
#define EOM_CORE_SERVICE_NAME L"Teleport Core Service"
|
||||
|
||||
static bool _run_daemon(void);
|
||||
static bool _run_daemon();
|
||||
|
||||
#ifdef EX_OS_WIN32
|
||||
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)
|
||||
return ts_main();
|
||||
|
@ -163,7 +163,7 @@ int _app_main(int argc, wchar_t** argv)
|
|||
|
||||
if (g_run_type == RUN_STOP) {
|
||||
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;
|
||||
ts_http_get(url, body);
|
||||
ex_printf("%s\n", body.c_str());
|
||||
|
@ -195,8 +195,8 @@ int _app_main(int argc, wchar_t** argv)
|
|||
#endif
|
||||
|
||||
static SERVICE_STATUS g_ServiceStatus = { 0 };
|
||||
static SERVICE_STATUS_HANDLE g_hServiceStatusHandle = NULL;
|
||||
HANDLE g_hWorkerThread = NULL;
|
||||
static SERVICE_STATUS_HANDLE g_hServiceStatusHandle = nullptr;
|
||||
HANDLE g_hWorkerThread = nullptr;
|
||||
|
||||
VOID WINAPI service_main(DWORD argc, wchar_t** argv);
|
||||
void WINAPI service_handler(DWORD fdwControl);
|
||||
|
@ -212,9 +212,9 @@ int main()
|
|||
wchar_t** _argv = ::CommandLineToArgvW(szCmdLine, &_argc); //拆分命令行参数字符串;
|
||||
|
||||
ret = _app_main(_argc, _argv);
|
||||
|
||||
|
||||
LocalFree(_argv);
|
||||
_argv = NULL;
|
||||
_argv = nullptr;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -224,8 +224,8 @@ static bool _run_daemon(void)
|
|||
SERVICE_TABLE_ENTRY DispatchTable[2];
|
||||
DispatchTable[0].lpServiceName = EOM_CORE_SERVICE_NAME;
|
||||
DispatchTable[0].lpServiceProc = service_main;
|
||||
DispatchTable[1].lpServiceName = NULL;
|
||||
DispatchTable[1].lpServiceProc = NULL;
|
||||
DispatchTable[1].lpServiceName = nullptr;
|
||||
DispatchTable[1].lpServiceProc = nullptr;
|
||||
|
||||
if (!StartServiceCtrlDispatcher(DispatchTable))
|
||||
{
|
||||
|
@ -262,7 +262,7 @@ static void WINAPI service_handler(DWORD fdwControl)
|
|||
if (g_hWorkerThread)
|
||||
{
|
||||
// TerminateThread(g_hWorkerThread, 1);
|
||||
// g_hWorkerThread = NULL;
|
||||
// g_hWorkerThread = nullptr;
|
||||
g_exit_flag = true;
|
||||
|
||||
g_ServiceStatus.dwWin32ExitCode = 0;
|
||||
|
@ -307,8 +307,8 @@ VOID WINAPI service_main(DWORD argc, wchar_t** argv)
|
|||
}
|
||||
|
||||
DWORD tid = 0;
|
||||
g_hWorkerThread = CreateThread(NULL, 0, service_thread_func, NULL, 0, &tid);
|
||||
if (NULL == g_hWorkerThread)
|
||||
g_hWorkerThread = CreateThread(nullptr, 0, service_thread_func, nullptr, 0, &tid);
|
||||
if (nullptr == g_hWorkerThread)
|
||||
{
|
||||
EXLOGE_WIN("CreateThread()");
|
||||
|
||||
|
@ -345,7 +345,7 @@ int main(int argc, char** argv)
|
|||
memset(&act, 0, sizeof(act));
|
||||
act.sa_sigaction = _sig_handler;
|
||||
act.sa_flags = SA_SIGINFO;
|
||||
sigaction(SIGINT, &act, NULL);
|
||||
sigaction(SIGINT, &act, nullptr);
|
||||
|
||||
wchar_t** wargv = ex_make_wargv(argc, argv);
|
||||
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)
|
||||
{
|
||||
EXLOGW("\n[core] received signal SIGINT, exit now.\n");
|
||||
EXLOGW("[core] received signal SIGINT, exit now.\n");
|
||||
g_exit_flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
static bool _run_daemon(void)
|
||||
static bool _run_daemon()
|
||||
{
|
||||
pid_t pid = fork();
|
||||
if (pid < 0)
|
||||
|
@ -382,7 +382,7 @@ static bool _run_daemon(void)
|
|||
{
|
||||
EXLOGE("[core] setsid() failed.\n");
|
||||
assert(0);
|
||||
exit(EXIT_FAILURE);
|
||||
// exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
umask(0);
|
||||
|
@ -399,14 +399,14 @@ static bool _run_daemon(void)
|
|||
}
|
||||
|
||||
// now I'm second children.
|
||||
int ret = chdir("/");
|
||||
chdir("/");
|
||||
close(STDIN_FILENO);
|
||||
|
||||
int stdfd = open("/dev/null", O_RDWR);
|
||||
int std_fd = open("/dev/null", O_RDWR);
|
||||
close(STDOUT_FILENO);
|
||||
close(STDERR_FILENO);
|
||||
dup2(stdfd, STDOUT_FILENO);
|
||||
dup2(stdfd, STDERR_FILENO);
|
||||
dup2(std_fd, STDOUT_FILENO);
|
||||
dup2(std_fd, STDERR_FILENO);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,126 +1,108 @@
|
|||
#include "tp_tpp_mgr.h"
|
||||
#include "ts_main.h"
|
||||
// #include "ts_session.h"
|
||||
// #include "ts_http_rpc.h"
|
||||
// #include "ts_web_rpc.h"
|
||||
#include "ts_env.h"
|
||||
|
||||
// #include <mbedtls/platform.h>
|
||||
// #include <mbedtls/debug.h>
|
||||
|
||||
TppManager g_tpp_mgr;
|
||||
|
||||
extern ExLogger g_ex_logger;
|
||||
|
||||
bool TppManager::load_tpp(const ex_wstr& libname)
|
||||
{
|
||||
ex_wstr filename;
|
||||
bool TppManager::load_tpp(const ex_wstr& libname) {
|
||||
ex_wstr filename;
|
||||
#ifdef EX_OS_WIN32
|
||||
filename = libname + L".dll";
|
||||
filename = libname + L".dll";
|
||||
#elif defined (EX_OS_LINUX)
|
||||
filename = L"lib";
|
||||
filename += libname;
|
||||
filename += L".so";
|
||||
filename += L".so";
|
||||
#elif defined (EX_OS_MACOS)
|
||||
filename = L"lib";
|
||||
filename = L"lib";
|
||||
filename += libname;
|
||||
filename += L".dylib";
|
||||
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());
|
||||
ex_wstr lib_file = g_env.m_exec_path;
|
||||
ex_path_join(lib_file, false, filename.c_str(), nullptr);
|
||||
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());
|
||||
if (NULL == lib->dylib)
|
||||
{
|
||||
EXLOGE(L"[core] load dylib `%ls` failed.\n", libfile.c_str());
|
||||
delete lib;
|
||||
return false;
|
||||
}
|
||||
lib->dylib = ex_dlopen(lib_file.c_str());
|
||||
if (nullptr == lib->dylib) {
|
||||
EXLOGE(L"[core] load dylib `%ls` failed.\n", lib_file.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");
|
||||
// lib->set_cfg = (TPP_SET_CFG_FUNC)GetProcAddress(lib->dylib, "tpp_set_cfg");
|
||||
lib->command = (TPP_COMMAND_FUNC)GetProcAddress(lib->dylib, "tpp_command");
|
||||
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");
|
||||
lib->command = (TPP_COMMAND_FUNC)GetProcAddress(lib->dylib, "tpp_command");
|
||||
#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");
|
||||
// lib->set_cfg = (TPP_SET_CFG_FUNC)dlsym(lib->dylib, "tpp_set_cfg");
|
||||
lib->command = (TPP_COMMAND_FUNC)dlsym(lib->dylib, "tpp_command");
|
||||
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");
|
||||
lib->command = (TPP_COMMAND_FUNC) dlsym(lib->dylib, "tpp_command");
|
||||
#endif
|
||||
|
||||
if (
|
||||
lib->init == NULL
|
||||
|| lib->start == NULL
|
||||
|| lib->stop == NULL
|
||||
|| lib->timer == NULL
|
||||
//|| lib->set_cfg == NULL
|
||||
|| lib->command == NULL
|
||||
)
|
||||
{
|
||||
EXLOGE(L"[core] load dylib `%ls` failed, can not locate all functions.\n", libfile.c_str());
|
||||
delete lib;
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
lib->init == nullptr
|
||||
|| lib->start == nullptr
|
||||
|| lib->stop == nullptr
|
||||
|| lib->timer == nullptr
|
||||
|| lib->command == nullptr
|
||||
) {
|
||||
EXLOGE(L"[core] load dylib `%ls` failed, can not locate all functions.\n", lib_file.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;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
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::stop_all() {
|
||||
for (auto& lib : m_libs) {
|
||||
lib->stop();
|
||||
}
|
||||
}
|
||||
|
||||
void TppManager::timer(void) {
|
||||
tpp_libs::iterator it = m_libs.begin();
|
||||
for (; it != m_libs.end(); ++it)
|
||||
{
|
||||
(*it)->timer();
|
||||
}
|
||||
void TppManager::timer() {
|
||||
for (auto& lib : m_libs) {
|
||||
lib->timer();
|
||||
}
|
||||
}
|
||||
|
||||
// void TppManager::set_config(int noop_timeout) {
|
||||
//
|
||||
//
|
||||
// TPP_SET_CFG_ARGS args;
|
||||
// args.noop_timeout = noop_timeout;
|
||||
//
|
||||
//
|
||||
// tpp_libs::iterator it = m_libs.begin();
|
||||
// for (; it != m_libs.end(); ++it)
|
||||
// {
|
||||
|
@ -129,16 +111,13 @@ void TppManager::timer(void) {
|
|||
// }
|
||||
|
||||
void TppManager::set_runtime_config(const ex_astr& sp) {
|
||||
tpp_libs::iterator it = m_libs.begin();
|
||||
for (; it != m_libs.end(); ++it) {
|
||||
(*it)->command(TPP_CMD_SET_RUNTIME_CFG, sp.c_str());
|
||||
}
|
||||
for (auto& lib : m_libs) {
|
||||
lib->command(TPP_CMD_SET_RUNTIME_CFG, sp.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void TppManager::kill_sessions(const ex_astr& sp) {
|
||||
tpp_libs::iterator it = m_libs.begin();
|
||||
for (; it != m_libs.end(); ++it) {
|
||||
(*it)->command(TPP_CMD_KILL_SESSIONS, sp.c_str());
|
||||
}
|
||||
for (auto& lib : m_libs) {
|
||||
lib->command(TPP_CMD_KILL_SESSIONS, sp.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,65 +1,65 @@
|
|||
#ifndef __TP_TPP_MGR_H__
|
||||
#define __TP_TPP_MGR_H__
|
||||
|
||||
#include "../common/protocol_interface.h"
|
||||
|
||||
#include <ex.h>
|
||||
|
||||
typedef struct TPP_LIB
|
||||
{
|
||||
TPP_LIB()
|
||||
{
|
||||
dylib = NULL;
|
||||
init = NULL;
|
||||
}
|
||||
~TPP_LIB()
|
||||
{
|
||||
if (NULL != dylib)
|
||||
ex_dlclose(dylib);
|
||||
dylib = NULL;
|
||||
}
|
||||
#ifndef __TP_TPP_MGR_H__
|
||||
#define __TP_TPP_MGR_H__
|
||||
|
||||
EX_DYLIB_HANDLE dylib;
|
||||
TPP_INIT_FUNC init;
|
||||
TPP_START_FUNC start;
|
||||
TPP_STOP_FUNC stop;
|
||||
TPP_TIMER_FUNC timer;
|
||||
// TPP_SET_CFG_FUNC set_cfg;
|
||||
#include "../common/protocol_interface.h"
|
||||
|
||||
TPP_COMMAND_FUNC command;
|
||||
}TPP_LIB;
|
||||
#include <ex.h>
|
||||
|
||||
typedef struct TPP_LIB {
|
||||
TPP_LIB() :
|
||||
dylib(nullptr),
|
||||
init(nullptr),
|
||||
start(nullptr),
|
||||
stop(nullptr),
|
||||
timer(nullptr),
|
||||
command(nullptr) {
|
||||
}
|
||||
|
||||
~TPP_LIB() {
|
||||
if (nullptr != dylib)
|
||||
ex_dlclose(dylib);
|
||||
dylib = nullptr;
|
||||
}
|
||||
|
||||
EX_DYLIB_HANDLE dylib;
|
||||
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;
|
||||
|
||||
class TppManager
|
||||
{
|
||||
class TppManager {
|
||||
public:
|
||||
TppManager()
|
||||
{
|
||||
}
|
||||
~TppManager()
|
||||
{
|
||||
tpp_libs::iterator it = m_libs.begin();
|
||||
for (; it != m_libs.end(); ++it)
|
||||
{
|
||||
delete (*it);
|
||||
}
|
||||
m_libs.clear();
|
||||
}
|
||||
TppManager() = default;
|
||||
|
||||
bool load_tpp(const ex_wstr& libfile);
|
||||
void stop_all(void);
|
||||
void timer(void); // ´óÔ¼1Ãëµ÷ÓÃÒ»´Î
|
||||
int count(void) { return m_libs.size(); }
|
||||
~TppManager() {
|
||||
for (auto lib : m_libs) {
|
||||
delete lib;
|
||||
}
|
||||
m_libs.clear();
|
||||
}
|
||||
|
||||
void set_config(int noop_timeout);
|
||||
void set_runtime_config(const ex_astr& sp);
|
||||
void kill_sessions(const ex_astr& sp);
|
||||
bool load_tpp(const ex_wstr& lib_file);
|
||||
|
||||
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:
|
||||
tpp_libs m_libs;
|
||||
tpp_libs m_libs;
|
||||
};
|
||||
|
||||
extern TppManager g_tpp_mgr;
|
||||
|
||||
#endif // __TP_TPP_MGR_H__
|
||||
#endif // __TP_TPP_MGR_H__
|
||||
|
|
|
@ -6,52 +6,53 @@
|
|||
#include "tp_tpp_mgr.h"
|
||||
|
||||
#include <mbedtls/platform.h>
|
||||
#include <mbedtls/debug.h>
|
||||
// #include <mbedtls/debug.h>
|
||||
|
||||
bool g_exit_flag = false;
|
||||
|
||||
TPP_CONNECT_INFO *tpp_get_connect_info(const char *sid) {
|
||||
TS_CONNECT_INFO sinfo;
|
||||
bool ret = g_session_mgr.get_connect_info(sid, sinfo);
|
||||
TPP_CONNECT_INFO* tpp_get_connect_info(const char* sid) {
|
||||
TS_CONNECT_INFO connect_info;
|
||||
|
||||
bool ret = g_session_mgr.get_connect_info(sid, connect_info);
|
||||
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);
|
||||
ex_strcpy(info->sid, sinfo.sid.length() + 1, sinfo.sid.c_str());
|
||||
info->user_username = (char *) calloc(1, sinfo.user_username.length() + 1);
|
||||
ex_strcpy(info->user_username, sinfo.user_username.length() + 1, sinfo.user_username.c_str());
|
||||
info->host_ip = (char *) calloc(1, sinfo.host_ip.length() + 1);
|
||||
ex_strcpy(info->host_ip, sinfo.host_ip.length() + 1, sinfo.host_ip.c_str());
|
||||
info->conn_ip = (char *) calloc(1, sinfo.conn_ip.length() + 1);
|
||||
ex_strcpy(info->conn_ip, sinfo.conn_ip.length() + 1, sinfo.conn_ip.c_str());
|
||||
info->client_ip = (char *) calloc(1, sinfo.client_ip.length() + 1);
|
||||
ex_strcpy(info->client_ip, sinfo.client_ip.length() + 1, sinfo.client_ip.c_str());
|
||||
info->acc_username = (char *) calloc(1, sinfo.acc_username.length() + 1);
|
||||
ex_strcpy(info->acc_username, sinfo.acc_username.length() + 1, sinfo.acc_username.c_str());
|
||||
info->acc_secret = (char *) calloc(1, sinfo.acc_secret.length() + 1);
|
||||
ex_strcpy(info->acc_secret, sinfo.acc_secret.length() + 1, sinfo.acc_secret.c_str());
|
||||
info->username_prompt = (char *) calloc(1, sinfo.username_prompt.length() + 1);
|
||||
ex_strcpy(info->username_prompt, sinfo.username_prompt.length() + 1, sinfo.username_prompt.c_str());
|
||||
info->password_prompt = (char *) calloc(1, sinfo.password_prompt.length() + 1);
|
||||
ex_strcpy(info->password_prompt, sinfo.password_prompt.length() + 1, sinfo.password_prompt.c_str());
|
||||
info->sid = (char*) calloc(1, connect_info.sid.length() + 1);
|
||||
ex_strcpy(info->sid, connect_info.sid.length() + 1, connect_info.sid.c_str());
|
||||
info->user_username = (char*) calloc(1, connect_info.user_username.length() + 1);
|
||||
ex_strcpy(info->user_username, connect_info.user_username.length() + 1, connect_info.user_username.c_str());
|
||||
info->host_ip = (char*) calloc(1, connect_info.host_ip.length() + 1);
|
||||
ex_strcpy(info->host_ip, connect_info.host_ip.length() + 1, connect_info.host_ip.c_str());
|
||||
info->conn_ip = (char*) calloc(1, connect_info.conn_ip.length() + 1);
|
||||
ex_strcpy(info->conn_ip, connect_info.conn_ip.length() + 1, connect_info.conn_ip.c_str());
|
||||
info->client_ip = (char*) calloc(1, connect_info.client_ip.length() + 1);
|
||||
ex_strcpy(info->client_ip, connect_info.client_ip.length() + 1, connect_info.client_ip.c_str());
|
||||
info->acc_username = (char*) calloc(1, connect_info.acc_username.length() + 1);
|
||||
ex_strcpy(info->acc_username, connect_info.acc_username.length() + 1, connect_info.acc_username.c_str());
|
||||
info->acc_secret = (char*) calloc(1, connect_info.acc_secret.length() + 1);
|
||||
ex_strcpy(info->acc_secret, connect_info.acc_secret.length() + 1, connect_info.acc_secret.c_str());
|
||||
info->username_prompt = (char*) calloc(1, connect_info.username_prompt.length() + 1);
|
||||
ex_strcpy(info->username_prompt, connect_info.username_prompt.length() + 1, connect_info.username_prompt.c_str());
|
||||
info->password_prompt = (char*) calloc(1, connect_info.password_prompt.length() + 1);
|
||||
ex_strcpy(info->password_prompt, connect_info.password_prompt.length() + 1, connect_info.password_prompt.c_str());
|
||||
|
||||
info->user_id = sinfo.user_id;
|
||||
info->host_id = sinfo.host_id;
|
||||
info->acc_id = sinfo.acc_id;
|
||||
info->conn_port = sinfo.conn_port;
|
||||
info->protocol_type = sinfo.protocol_type;
|
||||
info->protocol_sub_type = sinfo.protocol_sub_type;
|
||||
info->protocol_flag = sinfo.protocol_flag;
|
||||
info->record_flag = sinfo.record_flag;
|
||||
info->auth_type = sinfo.auth_type;
|
||||
info->user_id = connect_info.user_id;
|
||||
info->host_id = connect_info.host_id;
|
||||
info->acc_id = connect_info.acc_id;
|
||||
info->conn_port = connect_info.conn_port;
|
||||
info->protocol_type = connect_info.protocol_type;
|
||||
info->protocol_sub_type = connect_info.protocol_sub_type;
|
||||
info->protocol_flag = connect_info.protocol_flag;
|
||||
info->record_flag = connect_info.record_flag;
|
||||
info->auth_type = connect_info.auth_type;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
void tpp_free_connect_info(TPP_CONNECT_INFO *info) {
|
||||
if (NULL == info)
|
||||
void tpp_free_connect_info(TPP_CONNECT_INFO* info) {
|
||||
if (nullptr == info)
|
||||
return;
|
||||
|
||||
g_session_mgr.free_connect_info(info->sid);
|
||||
|
@ -68,190 +69,46 @@ void tpp_free_connect_info(TPP_CONNECT_INFO *info) {
|
|||
free(info);
|
||||
}
|
||||
|
||||
bool tpp_session_begin(const TPP_CONNECT_INFO *info, int *db_id) {
|
||||
if (NULL == info || NULL == db_id)
|
||||
bool tpp_session_begin(const TPP_CONNECT_INFO* info, int* db_id) {
|
||||
if (nullptr == info || nullptr == db_id)
|
||||
return false;
|
||||
|
||||
TS_CONNECT_INFO sinfo;
|
||||
sinfo.sid = info->sid;
|
||||
sinfo.user_id = info->user_id;
|
||||
sinfo.host_id = info->host_id;
|
||||
sinfo.acc_id = info->acc_id;
|
||||
sinfo.user_username = info->user_username;
|
||||
sinfo.host_ip = info->host_ip;
|
||||
sinfo.conn_ip = info->conn_ip;
|
||||
sinfo.client_ip = info->client_ip;
|
||||
sinfo.acc_username = info->acc_username;
|
||||
TS_CONNECT_INFO connect_info;
|
||||
connect_info.sid = info->sid;
|
||||
connect_info.user_id = info->user_id;
|
||||
connect_info.host_id = info->host_id;
|
||||
connect_info.acc_id = info->acc_id;
|
||||
connect_info.user_username = info->user_username;
|
||||
connect_info.host_ip = info->host_ip;
|
||||
connect_info.conn_ip = info->conn_ip;
|
||||
connect_info.client_ip = info->client_ip;
|
||||
connect_info.acc_username = info->acc_username;
|
||||
|
||||
sinfo.conn_port = info->conn_port;
|
||||
sinfo.protocol_type = info->protocol_type;
|
||||
sinfo.protocol_sub_type = info->protocol_sub_type;
|
||||
sinfo.auth_type = info->auth_type;
|
||||
connect_info.conn_port = info->conn_port;
|
||||
connect_info.protocol_type = info->protocol_type;
|
||||
connect_info.protocol_sub_type = info->protocol_sub_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) {
|
||||
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);
|
||||
}
|
||||
|
||||
// typedef struct TPP_LIB
|
||||
// {
|
||||
// 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() {
|
||||
ExIniFile& ini = g_env.get_ini();
|
||||
|
||||
int ts_main(void) {
|
||||
ExIniFile &ini = g_env.get_ini();
|
||||
|
||||
EXLOGI(L"\n");
|
||||
EXLOGI(L"###############################################################\n");
|
||||
EXLOGI("\n");
|
||||
EXLOGI("###############################################################\n");
|
||||
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;
|
||||
|
||||
// 枚举配置文件中的[protocol-xxx]小节,加载对应的协议动态库
|
||||
|
@ -259,18 +116,18 @@ int ts_main(void) {
|
|||
|
||||
do {
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!rpc.init() || !rpc.start()) {
|
||||
EXLOGE(L"[core] rpc init/start failed.\n");
|
||||
EXLOGE("[core] rpc init/start failed.\n");
|
||||
all_ok = false;
|
||||
break;
|
||||
}
|
||||
|
||||
ex_ini_sections::iterator it = secs.begin();
|
||||
auto it = secs.begin();
|
||||
for (; it != secs.end(); ++it) {
|
||||
if (it->first.length() > 9 && 0 == wcsncmp(it->first.c_str(), L"protocol-", 9)) {
|
||||
ex_wstr libname;
|
||||
|
@ -280,7 +137,7 @@ int ts_main(void) {
|
|||
bool enabled = false;
|
||||
it->second->GetBool(L"enabled", enabled, false);
|
||||
if (!enabled) {
|
||||
EXLOGV(L"[core] `%ls` not enabled.\n", libname.c_str());
|
||||
EXLOGW(L"[core] `%ls` not enabled.\n", libname.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -291,7 +148,7 @@ int ts_main(void) {
|
|||
}
|
||||
}
|
||||
|
||||
} while (0);
|
||||
} while (false);
|
||||
|
||||
if (0 == g_tpp_mgr.count()) {
|
||||
all_ok = false;
|
||||
|
@ -304,17 +161,19 @@ int ts_main(void) {
|
|||
if (!g_exit_flag) {
|
||||
ts_web_rpc_register_core();
|
||||
|
||||
EXLOGV("[core] ---- initialized, ready for service ----\n");
|
||||
EXLOGI("[core] ---- initialized, ready for service ----\n");
|
||||
while (!g_exit_flag) {
|
||||
ex_sleep_ms(1000);
|
||||
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();
|
||||
rpc.stop();
|
||||
g_session_mgr.stop();
|
||||
|
||||
EXLOGI("[core] done.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -3,13 +3,13 @@
|
|||
|
||||
#include "../common/protocol_interface.h"
|
||||
|
||||
int ts_main(void);
|
||||
int ts_main();
|
||||
|
||||
TPP_CONNECT_INFO* tpp_get_connect_info(const char* sid);
|
||||
void tpp_free_connect_info(TPP_CONNECT_INFO* info);
|
||||
bool tpp_session_begin(const TPP_CONNECT_INFO* info, int* db_id);
|
||||
bool tpp_session_update(int db_id, int protocol_sub_type, int state);
|
||||
bool tpp_session_end(const char* sid, int db_id, int ret);
|
||||
TPP_CONNECT_INFO* tpp_get_connect_info(const char* sid);
|
||||
void tpp_free_connect_info(TPP_CONNECT_INFO* info);
|
||||
bool tpp_session_begin(const TPP_CONNECT_INFO* info, int* db_id);
|
||||
bool tpp_session_update(int db_id, int protocol_sub_type, int state);
|
||||
bool tpp_session_end(const char* sid, int db_id, int ret);
|
||||
|
||||
|
||||
#endif // __TS_MAIN_H__
|
||||
|
|
|
@ -11,7 +11,7 @@ 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) {
|
||||
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;
|
||||
|
@ -19,7 +19,7 @@ TsSessionManager::~TsSessionManager() {
|
|||
m_connections.clear();
|
||||
}
|
||||
|
||||
void TsSessionManager::_thread_loop(void) {
|
||||
void TsSessionManager::_thread_loop() {
|
||||
for (;;) {
|
||||
ex_sleep_ms(1000);
|
||||
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会被移除
|
||||
|
||||
ExThreadSmartLock locker(m_lock);
|
||||
|
||||
ex_u64 _now = ex_get_tick_count();
|
||||
ts_connections::iterator it = m_connections.begin();
|
||||
auto it = m_connections.begin();
|
||||
for (; it != m_connections.end();) {
|
||||
//EXLOGD("[core] check expired connect info: [%s] %d, %d %d %d\n", it->first.c_str(), it->second->ref_count, int(_now), int(it->second->ticket_start), int(_now - it->second->ticket_start));
|
||||
if (it->second->ref_count == 0 && _now - 15000 > it->second->ticket_start) {
|
||||
|
@ -42,16 +42,17 @@ void TsSessionManager::_remove_expired_connect_info(void) {
|
|||
delete it->second;
|
||||
m_connections.erase(it++);
|
||||
EXLOGD("[core] there are %d connection info exists.\n", m_connections.size());
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
++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);
|
||||
|
||||
ts_connections::iterator it = m_connections.find(sid);
|
||||
auto it = m_connections.find(sid);
|
||||
if (it == m_connections.end())
|
||||
return false;
|
||||
|
||||
|
@ -79,10 +80,10 @@ bool TsSessionManager::get_connect_info(const ex_astr &sid, TS_CONNECT_INFO &inf
|
|||
return true;
|
||||
}
|
||||
|
||||
bool TsSessionManager::free_connect_info(const ex_astr &sid) {
|
||||
bool TsSessionManager::free_connect_info(const ex_astr& sid) {
|
||||
ExThreadSmartLock locker(m_lock);
|
||||
|
||||
ts_connections::iterator it = m_connections.find(sid);
|
||||
auto it = m_connections.find(sid);
|
||||
if (it == m_connections.end())
|
||||
return false;
|
||||
|
||||
|
@ -97,7 +98,8 @@ bool TsSessionManager::free_connect_info(const ex_astr &sid) {
|
|||
m_connections.erase(it);
|
||||
EXLOGD("[core] there are %d connection info exists.\n", m_connections.size());
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (it->second->ref_count == 1)
|
||||
it->second->ref_count = 0;
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
EXLOGD("[core] request session: account: [%s], protocol: [%d], auth-mode: [%d]\n", info->acc_username.c_str(),
|
||||
info->protocol_type, info->auth_type);
|
||||
EXLOGD(
|
||||
"[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;
|
||||
int retried = 0;
|
||||
|
@ -143,7 +148,7 @@ bool TsSessionManager::request_session(ex_astr &sid, TS_CONNECT_INFO *info) {
|
|||
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;
|
||||
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_starts(&sha);
|
||||
mbedtls_sha1_update(&sha, (const unsigned char *) &_tick, sizeof(ex_u64));
|
||||
mbedtls_sha1_update(&sha, (const unsigned char *) &_tid, sizeof(ex_u64));
|
||||
mbedtls_sha1_update(&sha, (const unsigned char *) info->conn_ip.c_str(), info->conn_ip.length());
|
||||
mbedtls_sha1_update(&sha, (const unsigned char *) info->client_ip.c_str(), info->client_ip.length());
|
||||
mbedtls_sha1_update(&sha, (const unsigned char *) info->acc_username.c_str(), info->acc_username.length());
|
||||
mbedtls_sha1_update(&sha, (const unsigned char*) &_tick, sizeof(ex_u64));
|
||||
mbedtls_sha1_update(&sha, (const unsigned char*) &_tid, sizeof(ex_u64));
|
||||
mbedtls_sha1_update(&sha, (const unsigned char*) info->conn_ip.c_str(), info->conn_ip.length());
|
||||
mbedtls_sha1_update(&sha, (const unsigned char*) info->client_ip.c_str(), info->client_ip.length());
|
||||
mbedtls_sha1_update(&sha, (const unsigned char*) info->acc_username.c_str(), info->acc_username.length());
|
||||
mbedtls_sha1_finish(&sha, sha_digist);
|
||||
mbedtls_sha1_free(&sha);
|
||||
|
||||
|
|
|
@ -6,68 +6,65 @@
|
|||
|
||||
#include <ex.h>
|
||||
|
||||
typedef struct TS_CONNECT_INFO
|
||||
{
|
||||
// TODO:
|
||||
//TPP_CONNECT_INFO conn;
|
||||
typedef struct TS_CONNECT_INFO {
|
||||
ex_astr sid;
|
||||
|
||||
ex_astr sid;
|
||||
// 与此连接信息相关的三个要素的ID
|
||||
int user_id;
|
||||
int host_id;
|
||||
int acc_id;
|
||||
|
||||
// 与此连接信息相关的三个要素的ID
|
||||
int user_id;
|
||||
int host_id;
|
||||
int acc_id;
|
||||
ex_astr user_username;// 申请本次连接的用户名
|
||||
|
||||
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 conn_ip;// 要连接的远程主机的IP(如果是端口映射模式,则为路由主机的IP)
|
||||
int conn_port;// 要连接的远程主机的端口(如果是端口映射模式,则为路由主机的端口)
|
||||
ex_astr client_ip;
|
||||
ex_astr acc_username; // 远程主机的账号
|
||||
ex_astr acc_secret; // 远程主机账号的密码(或者私钥)
|
||||
ex_astr username_prompt;// for telnet
|
||||
ex_astr password_prompt;// for telnet
|
||||
|
||||
ex_astr acc_username; // 远程主机的账号
|
||||
ex_astr acc_secret; // 远程主机账号的密码(或者私钥)
|
||||
ex_astr username_prompt;// for telnet
|
||||
ex_astr password_prompt;// for telnet
|
||||
int protocol_type;
|
||||
int protocol_sub_type;
|
||||
int protocol_flag;
|
||||
int record_flag;
|
||||
int auth_type;
|
||||
|
||||
int protocol_type;
|
||||
int protocol_sub_type;
|
||||
int protocol_flag;
|
||||
int record_flag;
|
||||
int auth_type;
|
||||
|
||||
int ref_count;// 这个连接信息的引用计数,如果创建的连接信息从来未被使用,则超过30秒后自动销毁
|
||||
ex_u64 ticket_start;// 此连接信息的创建时间(用于超时未使用就销毁的功能)
|
||||
}TS_CONNECT_INFO;
|
||||
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
|
||||
|
||||
class TsSessionManager : public ExThreadBase
|
||||
{
|
||||
class TsSessionManager : public ExThreadBase {
|
||||
public:
|
||||
TsSessionManager();
|
||||
~TsSessionManager();
|
||||
TsSessionManager();
|
||||
|
||||
// generate a sid for connection info.
|
||||
bool request_session(ex_astr& sid, TS_CONNECT_INFO* info);
|
||||
~TsSessionManager() override;
|
||||
|
||||
// 根据sid得到连接信息(并增加引用计数)
|
||||
bool get_connect_info(const ex_astr& sid, TS_CONNECT_INFO& info);
|
||||
// 减少引用计数,当引用计数为0时,删除之
|
||||
bool free_connect_info(const ex_astr& sid);
|
||||
// generate a sid for connection info.
|
||||
bool request_session(ex_astr& sid, TS_CONNECT_INFO* info);
|
||||
|
||||
// 根据sid得到连接信息(并增加引用计数)
|
||||
bool get_connect_info(const ex_astr& sid, TS_CONNECT_INFO& info);
|
||||
|
||||
// 减少引用计数,当引用计数为0时,删除之
|
||||
bool free_connect_info(const ex_astr& sid);
|
||||
|
||||
protected:
|
||||
void _thread_loop(void);
|
||||
void _thread_loop() override;
|
||||
|
||||
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会被移除
|
||||
void _remove_expired_connect_info(void);
|
||||
// 定时检查,超过30秒未进行连接的connect-info会被移除
|
||||
void _remove_expired_connect_info();
|
||||
|
||||
private:
|
||||
ExThreadLock m_lock;
|
||||
ts_connections m_connections;
|
||||
ExThreadLock m_lock;
|
||||
ts_connections m_connections;
|
||||
};
|
||||
|
||||
extern TsSessionManager g_session_mgr;
|
||||
|
|
|
@ -148,7 +148,7 @@ int ts_web_rpc_get_conn_info(int conn_id, TS_CONNECT_INFO& info)
|
|||
EXLOGE("got connection info from web-server, but not all info valid.\n");
|
||||
return TPE_PARAM;
|
||||
}
|
||||
|
||||
|
||||
int user_id;
|
||||
int host_id;
|
||||
int acc_id;
|
||||
|
@ -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;
|
||||
|
||||
ex_astr json_param;
|
||||
//json_param = json_writer.write(jreq);
|
||||
Json::StreamWriterBuilder jwb;
|
||||
std::unique_ptr<Json::StreamWriter> jwriter(jwb.newStreamWriter());
|
||||
ex_aoss os;
|
||||
|
@ -276,16 +275,13 @@ bool ts_web_rpc_session_begin(TS_CONNECT_INFO& info, int& record_id)
|
|||
return false;
|
||||
}
|
||||
|
||||
//Json::Reader jreader;
|
||||
Json::Value jret;
|
||||
|
||||
//if (!jreader.parse(body.c_str(), jret))
|
||||
Json::CharReaderBuilder jcrb;
|
||||
std::unique_ptr<Json::CharReader> const jreader(jcrb.newCharReader());
|
||||
const char *str_json_begin = body.c_str();
|
||||
ex_astr err;
|
||||
|
||||
//if (!jreader.parse(func_args.c_str(), jsRoot)) {
|
||||
if (!jreader->parse(str_json_begin, str_json_begin + body.length(), &jret, &err))
|
||||
return false;
|
||||
if (!jret.isObject())
|
||||
|
@ -346,7 +342,7 @@ bool ts_web_rpc_session_end(const char* sid, int record_id, int ret_code)
|
|||
ex_aoss os;
|
||||
jwriter->write(jreq, &os);
|
||||
json_param = os.str();
|
||||
|
||||
|
||||
ex_astr param;
|
||||
ts_url_encode(json_param.c_str(), param);
|
||||
|
||||
|
|
|
@ -4,78 +4,66 @@
|
|||
|
||||
#include <teleport_const.h>
|
||||
|
||||
SshChannelPair::SshChannelPair(SshSession *_owner, ssh_channel _rsc_tp2cli, ssh_channel _rsc_tp2srv) :
|
||||
m_owner(_owner),
|
||||
rsc_tp2cli(_rsc_tp2cli),
|
||||
rsc_tp2srv(_rsc_tp2srv)
|
||||
{
|
||||
SshChannelPair::SshChannelPair(SshSession* _owner, uint32_t dbg_id, ssh_channel _rsc_tp2cli, ssh_channel _rsc_tp2srv) :
|
||||
m_owner(_owner),
|
||||
m_dbg_id(dbg_id),
|
||||
type(TS_SSH_CHANNEL_TYPE_UNKNOWN),
|
||||
win_width(0),
|
||||
rsc_tp2cli(_rsc_tp2cli),
|
||||
rsc_tp2srv(_rsc_tp2srv) {
|
||||
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;
|
||||
db_id = 0;
|
||||
channel_id = 0;
|
||||
state = TP_SESS_STAT_RUNNING;
|
||||
db_id = 0;
|
||||
|
||||
win_width = 0;
|
||||
is_first_server_data = true;
|
||||
need_close = false;
|
||||
|
||||
m_is_cmd_mode = false;
|
||||
m_recv_prompt = false;
|
||||
m_client_last_char = 0;
|
||||
need_close = false;
|
||||
|
||||
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)
|
||||
return;
|
||||
|
||||
if (len == 1)
|
||||
{
|
||||
if (data[0] == 0x0d)
|
||||
{
|
||||
if (len == 1) {
|
||||
if (data[0] == 0x0d) {
|
||||
// 0x0d 回车键
|
||||
if (!m_cmd.empty())
|
||||
EXLOGD("[%s] CMD=[%s]\n", m_owner->dbg_name().c_str(), m_cmd.str().c_str());
|
||||
if (!m_cmd.empty()) {
|
||||
// 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_pty_stat = PTY_STAT_NORMAL_WAIT_PROMPT;
|
||||
// EXLOGD("------ turn to PTY_STAT_NORMAL_WAIT_PROMPT, input single RETURN.\n");
|
||||
return;
|
||||
}
|
||||
else if (data[0] == 0x03)
|
||||
{
|
||||
else if (data[0] == 0x03) {
|
||||
// 0x03 Ctrl-C
|
||||
m_pty_stat = PTY_STAT_NORMAL_WAIT_PROMPT;
|
||||
// EXLOGD("------ turn to PTY_STAT_NORMAL_WAIT_PROMPT, input Ctrl-C.\n");
|
||||
return;
|
||||
}
|
||||
else if (data[0] == 0x09)
|
||||
{
|
||||
else if (data[0] == 0x09) {
|
||||
// 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;
|
||||
// EXLOGD("------ turn to PTY_STAT_TAB_PRESSED, input TAB.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (data[0] == 0x7f)
|
||||
{
|
||||
else if (data[0] == 0x7f) {
|
||||
// 7f backspace 回删键
|
||||
m_pty_stat = PTY_STAT_WAIT_SERVER_ECHO;
|
||||
// EXLOGD("------ turn to PTY_STAT_WAIT_SERVER_ECHO, input BACKSPACE.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (len == 3)
|
||||
{
|
||||
if (data[0] == 0x1b && data[1] == 0x5b && (data[2] == 0x41 || data[2] == 0x42 || data[2] == 0x43 || data[2] == 0x44))
|
||||
{
|
||||
else if (len == 3) {
|
||||
if (data[0] == 0x1b && data[1] == 0x5b && (data[2] == 0x41 || data[2] == 0x42 || data[2] == 0x43 || data[2] == 0x44)) {
|
||||
// 1b 5b 41 (上箭头)
|
||||
// 1b 5b 42 (下箭头)
|
||||
// 1b 5b 43 (右箭头)
|
||||
|
@ -85,10 +73,8 @@ void SshChannelPair::process_pty_data_from_client(const uint8_t *data, uint32_t
|
|||
return;
|
||||
}
|
||||
}
|
||||
else if (len == 4)
|
||||
{
|
||||
if (data[0] == 0x1b && data[1] == 0x5b && data[2] == 0x33 && data[3] == 0x7e)
|
||||
{
|
||||
else if (len == 4) {
|
||||
if (data[0] == 0x1b && data[1] == 0x5b && data[2] == 0x33 && data[3] == 0x7e) {
|
||||
// 1b 5b 33 7e (删除一个字符)
|
||||
m_pty_stat = PTY_STAT_WAIT_SERVER_ECHO;
|
||||
// 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 (m_pty_stat != PTY_STAT_EXEC_MULTI_LINE_CMD)
|
||||
{
|
||||
if (len >= 512) {
|
||||
if (m_pty_stat != PTY_STAT_EXEC_MULTI_LINE_CMD) {
|
||||
m_pty_stat = PTY_STAT_NORMAL_WAIT_PROMPT;
|
||||
// EXLOGD("------ turn to PTY_STAT_NORMAL_WAIT_PROMPT, input too large.\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int return_count = 0;
|
||||
bool valid_input = true;
|
||||
int return_count = 0;
|
||||
bool valid_input = true;
|
||||
|
||||
int offset = 0;
|
||||
int offset = 0;
|
||||
int last_return_pos = 0;
|
||||
for (; offset < len;)
|
||||
{
|
||||
for (; offset < len;) {
|
||||
uint8_t ch = data[offset];
|
||||
|
||||
switch (ch)
|
||||
{
|
||||
switch (ch) {
|
||||
case 0x1b:
|
||||
if (offset + 1 < len)
|
||||
{
|
||||
if (data[offset + 1] == 0x5b)
|
||||
{
|
||||
if (offset + 1 < len) {
|
||||
if (data[offset + 1] == 0x5b) {
|
||||
valid_input = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case 0x0d:
|
||||
return_count++;
|
||||
case 0x0d:return_count++;
|
||||
last_return_pos = offset;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
default:break;
|
||||
}
|
||||
|
||||
if (!valid_input)
|
||||
|
@ -142,33 +120,29 @@ void SshChannelPair::process_pty_data_from_client(const uint8_t *data, uint32_t
|
|||
offset++;
|
||||
}
|
||||
|
||||
if (!valid_input)
|
||||
{
|
||||
if (m_pty_stat != PTY_STAT_EXEC_MULTI_LINE_CMD)
|
||||
{
|
||||
if (!valid_input) {
|
||||
if (m_pty_stat != PTY_STAT_EXEC_MULTI_LINE_CMD) {
|
||||
m_pty_stat = PTY_STAT_NORMAL_WAIT_PROMPT;
|
||||
// EXLOGD("------ turn to PTY_STAT_NORMAL_WAIT_PROMPT, input invalid.\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (return_count > 0)
|
||||
{
|
||||
std::string tmp_cmd((const char *) data, last_return_pos + 1);
|
||||
if (return_count > 0) {
|
||||
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());
|
||||
rec.record_command(1, tmp_cmd);
|
||||
|
||||
m_pty_stat = PTY_STAT_EXEC_MULTI_LINE_CMD;
|
||||
// EXLOGD("------ turn to PTY_STAT_EXEC_MULTI_LINE_CMD, maybe paste.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
m_pty_stat = PTY_STAT_WAIT_SERVER_ECHO;
|
||||
// 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)
|
||||
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
|
||||
|| m_pty_stat == PTY_STAT_TAB_WAIT_PROMPT
|
||||
|| m_pty_stat == PTY_STAT_MULTI_CMD_WAIT_PROMPT
|
||||
|| m_pty_stat == PTY_STAT_WAIT_SERVER_ECHO)
|
||||
{
|
||||
if (_contains_cmd_prompt(data, len))
|
||||
{
|
||||
|| m_pty_stat == PTY_STAT_WAIT_SERVER_ECHO) {
|
||||
if (_contains_cmd_prompt(data, len)) {
|
||||
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");
|
||||
m_pty_stat = PTY_STAT_WAIT_CLIENT_INPUT;
|
||||
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");
|
||||
m_pty_stat = PTY_STAT_WAIT_CLIENT_INPUT;
|
||||
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");
|
||||
m_pty_stat = PTY_STAT_EXEC_MULTI_LINE_CMD;
|
||||
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");
|
||||
m_pty_stat = PTY_STAT_WAIT_CLIENT_INPUT;
|
||||
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
|
||||
|| 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;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(
|
||||
m_pty_stat == PTY_STAT_WAIT_SERVER_ECHO
|
||||
|| m_pty_stat == PTY_STAT_EXEC_MULTI_LINE_CMD
|
||||
|| m_pty_stat == PTY_STAT_MULTI_CMD_WAIT_PROMPT
|
||||
|| m_pty_stat == PTY_STAT_TAB_WAIT_PROMPT
|
||||
|| m_pty_stat == PTY_STAT_TAB_PRESSED
|
||||
))
|
||||
{
|
||||
m_pty_stat == PTY_STAT_WAIT_SERVER_ECHO
|
||||
|| m_pty_stat == PTY_STAT_EXEC_MULTI_LINE_CMD
|
||||
|| m_pty_stat == PTY_STAT_MULTI_CMD_WAIT_PROMPT
|
||||
|| m_pty_stat == PTY_STAT_TAB_WAIT_PROMPT
|
||||
|| m_pty_stat == PTY_STAT_TAB_PRESSED
|
||||
)) {
|
||||
// EXLOGD("------ keep PTY_STAT, recv but not in ECHO or multi-cmd mode.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (len > 512)
|
||||
{
|
||||
if (len > 512) {
|
||||
// EXLOGD("------ keep PTY_STAT, recv too large.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理输入回显,合成最终的命令行字符串
|
||||
int offset = 0;
|
||||
int offset = 0;
|
||||
bool esc_mode = false;
|
||||
int esc_arg = 0;
|
||||
for (; offset < len;)
|
||||
{
|
||||
int esc_arg = 0;
|
||||
for (; offset < len;) {
|
||||
uint8_t ch = data[offset];
|
||||
|
||||
if (esc_mode)
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
if (esc_mode) {
|
||||
switch (ch) {
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
|
@ -259,30 +220,24 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t
|
|||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
esc_arg = esc_arg * 10 + (ch - '0');
|
||||
case '9':esc_arg = esc_arg * 10 + (ch - '0');
|
||||
break;
|
||||
|
||||
case 0x3f:
|
||||
case ';':
|
||||
case '>':
|
||||
m_cmd.reset();
|
||||
case '>':m_cmd.reset();
|
||||
return;
|
||||
|
||||
case 0x4b:
|
||||
{ // 'K'
|
||||
if (0 == esc_arg)
|
||||
{
|
||||
case 0x4b: { // 'K'
|
||||
if (0 == esc_arg) {
|
||||
// 删除光标到行尾的字符串
|
||||
m_cmd.erase_to_end();
|
||||
}
|
||||
else if (1 == esc_arg)
|
||||
{
|
||||
else if (1 == esc_arg) {
|
||||
// 删除从开始到光标处的字符串
|
||||
m_cmd.erase_to_begin();
|
||||
}
|
||||
else if (2 == esc_arg)
|
||||
{
|
||||
else if (2 == esc_arg) {
|
||||
// 删除整行
|
||||
m_cmd.reset();
|
||||
}
|
||||
|
@ -290,8 +245,7 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t
|
|||
esc_mode = false;
|
||||
break;
|
||||
}
|
||||
case 0x43:
|
||||
{// ^[C
|
||||
case 0x43: {// ^[C
|
||||
// 光标右移
|
||||
if (esc_arg == 0)
|
||||
esc_arg = 1;
|
||||
|
@ -299,8 +253,7 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t
|
|||
esc_mode = false;
|
||||
break;
|
||||
}
|
||||
case 0x44:
|
||||
{ // ^[D
|
||||
case 0x44: { // ^[D
|
||||
// 光标左移
|
||||
if (esc_arg == 0)
|
||||
esc_arg = 1;
|
||||
|
@ -309,8 +262,7 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t
|
|||
break;
|
||||
}
|
||||
|
||||
case 0x50:
|
||||
{
|
||||
case 0x50: {
|
||||
// 'P' 删除指定数量的字符
|
||||
if (esc_arg == 0)
|
||||
esc_arg = 1;
|
||||
|
@ -319,8 +271,7 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t
|
|||
break;
|
||||
}
|
||||
|
||||
case 0x40:
|
||||
{ // '@' 插入指定数量的空白字符
|
||||
case 0x40: { // '@' 插入指定数量的空白字符
|
||||
if (esc_arg == 0)
|
||||
esc_arg = 1;
|
||||
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;
|
||||
}
|
||||
|
||||
default:
|
||||
esc_mode = false;
|
||||
default:esc_mode = false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -337,25 +287,20 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t
|
|||
continue;
|
||||
}
|
||||
|
||||
switch (ch)
|
||||
{
|
||||
switch (ch) {
|
||||
case 0x07:
|
||||
// 响铃
|
||||
break;
|
||||
case 0x08:
|
||||
{
|
||||
case 0x08: {
|
||||
// 光标左移
|
||||
m_cmd.cursor_move_left(1);
|
||||
break;
|
||||
}
|
||||
case 0x1b:
|
||||
{
|
||||
if (offset + 1 < len)
|
||||
{
|
||||
if (data[offset + 1] == 0x5b)
|
||||
{
|
||||
case 0x1b: {
|
||||
if (offset + 1 < len) {
|
||||
if (data[offset + 1] == 0x5b) {
|
||||
esc_mode = true;
|
||||
esc_arg = 0;
|
||||
esc_arg = 0;
|
||||
|
||||
offset += 1;
|
||||
}
|
||||
|
@ -363,12 +308,9 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t
|
|||
|
||||
break;
|
||||
}
|
||||
case 0x0d:
|
||||
{
|
||||
if (offset + 1 < len && data[offset + 1] == 0x0a)
|
||||
{
|
||||
if (m_pty_stat == PTY_STAT_EXEC_MULTI_LINE_CMD)
|
||||
{
|
||||
case 0x0d: {
|
||||
if (offset + 1 < len && data[offset + 1] == 0x0a) {
|
||||
if (m_pty_stat == PTY_STAT_EXEC_MULTI_LINE_CMD) {
|
||||
if (!m_cmd.empty())
|
||||
EXLOGD("[%s] one of multi-cmd, CMD=[%s]\n", m_owner->dbg_name().c_str(), m_cmd.str().c_str());
|
||||
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;
|
||||
// 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;
|
||||
// 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;
|
||||
// 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;
|
||||
}
|
||||
default:
|
||||
m_cmd.replace(ch);
|
||||
if (m_pty_stat == PTY_STAT_WAIT_SERVER_ECHO)
|
||||
{
|
||||
default:m_cmd.replace(ch);
|
||||
if (m_pty_stat == PTY_STAT_WAIT_SERVER_ECHO) {
|
||||
m_pty_stat = PTY_STAT_WAIT_CLIENT_INPUT;
|
||||
// EXLOGD("------ turn to PTY_STAT_WAIT_CLIENT_INPUT, recv something.\n");
|
||||
}
|
||||
|
@ -405,15 +343,13 @@ void SshChannelPair::process_pty_data_from_server(const uint8_t *data, uint32_t
|
|||
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;
|
||||
// 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,它的位置
|
||||
// 应该位于倒数256字节范围内(这之后的数据可能是命令行提示符的内容了,不会太长的)。继续向前找,应该能够找到正
|
||||
// 序为 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_0x3b = false;
|
||||
bool found_Ps = false;
|
||||
bool found_Ps = false;
|
||||
bool found_0x5d = false;
|
||||
|
||||
int offset = static_cast<int>(len) - 1;
|
||||
|
||||
for (int i = 0; offset >= 0; i++)
|
||||
{
|
||||
for (int i = 0; offset >= 0; i++) {
|
||||
if (i > 256)
|
||||
return false;
|
||||
|
||||
if (found_0x5d)
|
||||
return (data[offset] == 0x1b);
|
||||
|
||||
if (found_Ps)
|
||||
{
|
||||
if (found_Ps) {
|
||||
found_0x5d = (data[offset] == 0x5d);
|
||||
if (!found_0x5d)
|
||||
return false;
|
||||
|
@ -456,8 +390,7 @@ bool SshChannelPair::_contains_cmd_prompt(const uint8_t *data, uint32_t len)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (found_0x3b)
|
||||
{
|
||||
if (found_0x3b) {
|
||||
found_Ps = (data[offset] == 0x30 || data[offset] == 0x31 || data[offset] == 0x32);
|
||||
if (!found_Ps)
|
||||
return false;
|
||||
|
@ -465,8 +398,7 @@ bool SshChannelPair::_contains_cmd_prompt(const uint8_t *data, uint32_t len)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!found_0x07)
|
||||
{
|
||||
if (!found_0x07) {
|
||||
found_0x07 = (data[offset] == 0x07);
|
||||
offset--;
|
||||
continue;
|
||||
|
@ -479,8 +411,7 @@ bool SshChannelPair::_contains_cmd_prompt(const uint8_t *data, uint32_t len)
|
|||
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
|
||||
// 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];
|
||||
|
||||
if (sftp_cmd == 0x01)
|
||||
{
|
||||
if (sftp_cmd == 0x01) {
|
||||
// 0x01 = 1 = SSH_FXP_INIT
|
||||
rec.record_command(0, "SFTP INITIALIZE\r\n");
|
||||
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)
|
||||
return;
|
||||
|
||||
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]);
|
||||
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]);
|
||||
// if (str1_len + 9 != pkg_len)
|
||||
// return;
|
||||
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]);
|
||||
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]);
|
||||
|
||||
|
||||
switch (sftp_cmd)
|
||||
{
|
||||
switch (sftp_cmd) {
|
||||
case 0x03:
|
||||
// 0x03 = 3 = SSH_FXP_OPEN
|
||||
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]);
|
||||
EXLOGD("[sftp-%s] SSH_FXP_LINK\n", m_owner->dbg_name().c_str());
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
default:return;
|
||||
}
|
||||
|
||||
int total_len = 5 + str1_len + 4;
|
||||
|
@ -570,16 +498,14 @@ void SshChannelPair::process_sftp_command(ssh_channel ch, const uint8_t *data, u
|
|||
if (total_len > pkg_len)
|
||||
return;
|
||||
|
||||
char msg[2048] = { 0 };
|
||||
if (str2_len == 0)
|
||||
{
|
||||
ex_astr str1((char *) ((ex_u8 *) data + 13), str1_len);
|
||||
char msg[2048] = {0};
|
||||
if (str2_len == 0) {
|
||||
ex_astr str1((char*) ((ex_u8*) data + 13), str1_len);
|
||||
ex_strformat(msg, 2048, "%d,%d,%s", sftp_cmd, 0, str1.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
ex_astr str1((char *) (str1_ptr + 4), str1_len);
|
||||
ex_astr str2((char *) (str2_ptr + 4), str2_len);
|
||||
else {
|
||||
ex_astr str1((char*) (str1_ptr + 4), str1_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());
|
||||
}
|
||||
|
||||
|
@ -587,21 +513,20 @@ void SshChannelPair::process_sftp_command(ssh_channel ch, const uint8_t *data, u
|
|||
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
|
||||
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;
|
||||
}
|
||||
else {
|
||||
channel_id = db_id;
|
||||
// EXLOGD("[ssh] [channel:%d] channel begin\n", cp->channel_id);
|
||||
}
|
||||
// else {
|
||||
// channel_id = db_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)) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -611,11 +536,10 @@ bool SshChannelPair::record_begin(const TPP_CONNECT_INFO *conn_info)
|
|||
return true;
|
||||
}
|
||||
|
||||
void SshChannelPair::record_end()
|
||||
{
|
||||
void SshChannelPair::record_end() {
|
||||
#ifndef TEST_SSH_SESSION_000000
|
||||
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)
|
||||
|
@ -626,7 +550,7 @@ void SshChannelPair::record_end()
|
|||
db_id = 0;
|
||||
}
|
||||
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
|
||||
}
|
||||
|
@ -636,17 +560,13 @@ void SshChannelPair::record_end()
|
|||
// SshCommand
|
||||
// ==================================================
|
||||
|
||||
SshCommand::SshCommand()
|
||||
{
|
||||
SshCommand::SshCommand() {
|
||||
m_cmd.clear();
|
||||
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());
|
||||
}
|
||||
|
|
|
@ -8,53 +8,46 @@
|
|||
|
||||
class SshSession;
|
||||
|
||||
class SshCommand
|
||||
{
|
||||
class SshCommand {
|
||||
public:
|
||||
SshCommand();
|
||||
|
||||
virtual ~SshCommand();
|
||||
|
||||
void reset()
|
||||
{
|
||||
void reset() {
|
||||
m_cmd.clear();
|
||||
m_pos = m_cmd.end();
|
||||
_dump("reset");
|
||||
}
|
||||
|
||||
std::string str()
|
||||
{
|
||||
std::string str() {
|
||||
if (empty())
|
||||
return "";
|
||||
else
|
||||
return std::string(m_cmd.begin(), m_cmd.end());
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
bool empty() const {
|
||||
return m_cmd.empty();
|
||||
}
|
||||
|
||||
void erase_to_end()
|
||||
{
|
||||
void erase_to_end() {
|
||||
// 删除光标到行尾的字符串
|
||||
m_cmd.erase(m_pos, m_cmd.end());
|
||||
m_pos = m_cmd.end();
|
||||
_dump("erase to end");
|
||||
}
|
||||
|
||||
void erase_to_begin()
|
||||
{
|
||||
void erase_to_begin() {
|
||||
// 删除从开始到光标处的字符串
|
||||
m_cmd.erase(m_cmd.begin(), m_pos);
|
||||
m_pos = m_cmd.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())
|
||||
m_pos++;
|
||||
else
|
||||
|
@ -63,11 +56,9 @@ public:
|
|||
_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())
|
||||
m_pos--;
|
||||
else
|
||||
|
@ -76,11 +67,9 @@ public:
|
|||
_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())
|
||||
m_pos = m_cmd.erase(m_pos);
|
||||
else
|
||||
|
@ -89,26 +78,21 @@ public:
|
|||
_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, ' ');
|
||||
}
|
||||
_dump("insert white space");
|
||||
}
|
||||
|
||||
void replace(uint8_t ch)
|
||||
{
|
||||
if (m_pos != m_cmd.end())
|
||||
{
|
||||
void replace(uint8_t ch) {
|
||||
if (m_pos != m_cmd.end()) {
|
||||
m_pos = m_cmd.erase(m_pos);
|
||||
m_pos = m_cmd.insert(m_pos, ch);
|
||||
m_pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
m_cmd.push_back(ch);
|
||||
//cmd_char_pos = cmd_char_list.end();
|
||||
m_pos = m_cmd.end();
|
||||
|
@ -116,17 +100,13 @@ public:
|
|||
_dump("replace char");
|
||||
}
|
||||
|
||||
void insert(const uint8_t *data, int len)
|
||||
{
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
if (m_pos == m_cmd.end())
|
||||
{
|
||||
void insert(const uint8_t* data, int len) {
|
||||
for (int i = 0; i < len; ++i) {
|
||||
if (m_pos == m_cmd.end()) {
|
||||
m_cmd.push_back(data[i]);
|
||||
m_pos = m_cmd.end();
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
m_pos = m_cmd.insert(m_pos, data[i]);
|
||||
m_pos++;
|
||||
}
|
||||
|
@ -134,15 +114,12 @@ public:
|
|||
_dump("insert chars");
|
||||
}
|
||||
|
||||
void insert(uint8_t ch)
|
||||
{
|
||||
if (m_pos == m_cmd.end())
|
||||
{
|
||||
void insert(uint8_t ch) {
|
||||
if (m_pos == m_cmd.end()) {
|
||||
m_cmd.push_back(ch);
|
||||
m_pos = m_cmd.end();
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
m_pos = m_cmd.insert(m_pos, ch);
|
||||
m_pos++;
|
||||
}
|
||||
|
@ -150,16 +127,15 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
void _dump(const char *msg);
|
||||
void _dump(const char* msg);
|
||||
|
||||
private:
|
||||
std::list<char> m_cmd;
|
||||
std::list<char> m_cmd;
|
||||
std::list<char>::iterator m_pos;
|
||||
};
|
||||
|
||||
// SSH命令解析,有限状态机状态值
|
||||
enum PTY_STAT
|
||||
{
|
||||
enum PTY_STAT {
|
||||
PTY_STAT_NORMAL_WAIT_PROMPT = 0,
|
||||
PTY_STAT_MULTI_CMD_WAIT_PROMPT,
|
||||
PTY_STAT_TAB_PRESSED,
|
||||
|
@ -170,35 +146,37 @@ enum PTY_STAT
|
|||
};
|
||||
|
||||
|
||||
class SshChannelPair
|
||||
{
|
||||
class SshChannelPair {
|
||||
friend class SshSession;
|
||||
|
||||
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();
|
||||
|
||||
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_client(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.
|
||||
bool record_begin(const TPP_CONNECT_INFO *conn_info);
|
||||
bool record_begin(const TPP_CONNECT_INFO* conn_info);
|
||||
|
||||
// stop record because channel closed.
|
||||
void record_end();
|
||||
|
||||
protected:
|
||||
bool _contains_cmd_prompt(const uint8_t *data, uint32_t len);
|
||||
bool _contains_cmd_prompt(const uint8_t* data, uint32_t len);
|
||||
|
||||
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 win_width; // window width, in char count.
|
||||
|
||||
ssh_channel rsc_tp2cli;
|
||||
ssh_channel rsc_tp2srv;
|
||||
|
@ -206,28 +184,18 @@ protected:
|
|||
uint32_t last_access_timestamp;
|
||||
|
||||
TppSshRec rec;
|
||||
int db_id;
|
||||
|
||||
int db_id;
|
||||
int state;
|
||||
int channel_id; // for debug only.
|
||||
|
||||
bool is_first_server_data;
|
||||
bool need_close;
|
||||
|
||||
// 是否处于命令行输入模式
|
||||
bool m_is_cmd_mode;
|
||||
bool m_recv_prompt;
|
||||
uint8_t m_client_last_char;
|
||||
SshCommand m_cmd;
|
||||
|
||||
// uint32_t m_input_flag;
|
||||
|
||||
// std::vector<uint8_t> m_last_input;
|
||||
|
||||
PTY_STAT m_pty_stat;
|
||||
};
|
||||
|
||||
typedef std::list<SshChannelPair *> TPChannelPairs;
|
||||
typedef std::map<ssh_channel, SshChannelPair *> channel_map;
|
||||
typedef std::list<SshChannelPair*> TPChannelPairs;
|
||||
typedef std::map<ssh_channel, SshChannelPair*> channel_map;
|
||||
|
||||
#endif //__SSH_CHANNEL_PAIR_H__
|
||||
|
|
|
@ -4,46 +4,39 @@
|
|||
SshProxy g_ssh_proxy;
|
||||
|
||||
SshProxy::SshProxy() noexcept:
|
||||
ExThreadBase("ssh-proxy-thread"),
|
||||
m_bind(nullptr),
|
||||
m_host_port(0)
|
||||
{
|
||||
ExThreadBase("ssh-proxy-thread"),
|
||||
m_bind(nullptr),
|
||||
m_host_port(0) {
|
||||
m_timer_counter_check_noop = 0;
|
||||
m_timer_counter_keep_alive = 0;
|
||||
m_noop_timeout_sec = 0;//900; // default to 15 minutes.
|
||||
m_listener_running = false;
|
||||
m_dbg_id = 0;
|
||||
m_noop_timeout_sec = 0;//900; // default to 15 minutes.
|
||||
m_listener_running = false;
|
||||
m_dbg_id = 0;
|
||||
}
|
||||
|
||||
SshProxy::~SshProxy()
|
||||
{
|
||||
if (m_bind)
|
||||
{
|
||||
SshProxy::~SshProxy() {
|
||||
if (m_bind) {
|
||||
ssh_bind_free(m_bind);
|
||||
m_bind = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool SshProxy::init()
|
||||
{
|
||||
m_host_ip = g_ssh_env.bind_ip;
|
||||
bool SshProxy::init() {
|
||||
m_host_ip = g_ssh_env.bind_ip;
|
||||
m_host_port = g_ssh_env.bind_port;
|
||||
|
||||
m_bind = ssh_bind_new();
|
||||
if (!m_bind)
|
||||
{
|
||||
if (!m_bind) {
|
||||
EXLOGE("[ssh] can not create bind.\n");
|
||||
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");
|
||||
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");
|
||||
return false;
|
||||
}
|
||||
|
@ -53,15 +46,13 @@ bool SshProxy::init()
|
|||
ex_astr key_file;
|
||||
ex_wstr2astr(_key_file, key_file);
|
||||
|
||||
EXLOGV("[ssh] try to load 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()))
|
||||
{
|
||||
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())) {
|
||||
EXLOGE("[ssh] can not set bind option: SSH_BIND_OPTIONS_RSAKEY.\n");
|
||||
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));
|
||||
return false;
|
||||
}
|
||||
|
@ -69,8 +60,7 @@ bool SshProxy::init()
|
|||
return true;
|
||||
}
|
||||
|
||||
void SshProxy::timer()
|
||||
{
|
||||
void SshProxy::timer() {
|
||||
// timer() will be called per one second by tp_core main thread.
|
||||
m_timer_counter_check_noop++;
|
||||
|
||||
|
@ -78,18 +68,15 @@ void SshProxy::timer()
|
|||
{
|
||||
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();
|
||||
// 检查会话是否已经关闭,如果会话已经完全关闭,则销毁之
|
||||
if (it->first->closed())
|
||||
{
|
||||
if (it->first->closed()) {
|
||||
delete it->first;
|
||||
m_sessions.erase(it++);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
@ -99,15 +86,13 @@ void SshProxy::timer()
|
|||
}
|
||||
|
||||
// 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);
|
||||
m_timer_counter_check_noop = 0;
|
||||
|
||||
ExThreadSmartLock locker(m_lock);
|
||||
|
||||
for (auto &session : m_sessions)
|
||||
{
|
||||
for (auto& session : m_sessions) {
|
||||
session.first->save_record();
|
||||
if (0 != 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;
|
||||
}
|
||||
|
||||
void SshProxy::kill_sessions(const ex_astrs &sessions)
|
||||
{
|
||||
void SshProxy::kill_sessions(const ex_astrs& sessions) {
|
||||
ExThreadSmartLock locker(m_lock);
|
||||
|
||||
for (auto &session : m_sessions)
|
||||
{
|
||||
for (const auto &sid : sessions)
|
||||
{
|
||||
if (session.first->sid() == sid)
|
||||
{
|
||||
for (auto& session : m_sessions) {
|
||||
for (const auto& sid : sessions) {
|
||||
if (session.first->sid() == sid) {
|
||||
EXLOGW("[ssh] kill session %s\n", sid.c_str());
|
||||
session.first->check_noop_timeout(0, 0); // 立即结束
|
||||
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);
|
||||
|
||||
m_listener_running = true;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
for (;;) {
|
||||
ssh_session rs_tp2cli = ssh_new();
|
||||
|
||||
// #ifdef EX_DEBUG
|
||||
|
@ -153,39 +131,36 @@ void SshProxy::_thread_loop()
|
|||
// ssh_options_set(rs_tp2cli, SSH_OPTIONS_LOG_VERBOSITY, &flag);
|
||||
// #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));
|
||||
continue;
|
||||
}
|
||||
EXLOGD("[ssh] ssh_bind_accept() returned...\n");
|
||||
|
||||
if (m_need_stop)
|
||||
{
|
||||
if (m_need_stop) {
|
||||
ssh_free(rs_tp2cli);
|
||||
break;
|
||||
}
|
||||
|
||||
struct sockaddr_storage sock_client{};
|
||||
|
||||
char ip[32] = { 0 };
|
||||
int len = sizeof(ip);
|
||||
char ip[32] = {0};
|
||||
int len = sizeof(ip);
|
||||
|
||||
|
||||
#ifdef EX_OS_WIN32
|
||||
getpeername(ssh_get_fd(rs_tp2cli), (struct sockaddr *) &sock_client, &len);
|
||||
#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
|
||||
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");
|
||||
}
|
||||
|
||||
uint32_t dbg_id = m_dbg_id++;
|
||||
auto session = new SshSession(this, rs_tp2cli, dbg_id, ip, addr->sin_port);
|
||||
uint32_t dbg_id = m_dbg_id++;
|
||||
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);
|
||||
|
||||
{
|
||||
|
@ -201,15 +176,13 @@ void SshProxy::_thread_loop()
|
|||
ExThreadSmartLock locker(m_lock);
|
||||
|
||||
|
||||
for (auto &session : m_sessions)
|
||||
{
|
||||
for (auto& session : m_sessions) {
|
||||
session.first->check_noop_timeout(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// 等待所有session完成关闭清理操作,工作线程退出
|
||||
for (;;)
|
||||
{
|
||||
for (;;) {
|
||||
// tp_core退出时会先停止timer线程,所以这里需要自己调用timer()来进行session状态检查
|
||||
timer();
|
||||
|
||||
|
@ -225,12 +198,10 @@ void SshProxy::_thread_loop()
|
|||
EXLOGV("[ssh] main-loop end.\n");
|
||||
}
|
||||
|
||||
void SshProxy::_on_stop()
|
||||
{
|
||||
void SshProxy::_on_stop() {
|
||||
ExThreadBase::_on_stop();
|
||||
|
||||
if (m_is_running)
|
||||
{
|
||||
if (m_is_running) {
|
||||
// 用一个变通的方式来结束阻塞中的监听,就是连接一下它。
|
||||
ex_astr host_ip = m_host_ip;
|
||||
if (host_ip == "0.0.0.0")
|
||||
|
@ -250,8 +221,7 @@ void SshProxy::_on_stop()
|
|||
ex_sleep_ms(500);
|
||||
}
|
||||
|
||||
while (m_listener_running)
|
||||
{
|
||||
while (m_listener_running) {
|
||||
ex_sleep_ms(1000);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,15 +7,15 @@ TppSshRec::TppSshRec() {
|
|||
m_cmd_cache.reserve(MAX_SIZE_PER_FILE);
|
||||
|
||||
memset(&m_head, 0, sizeof(TS_RECORD_HEADER));
|
||||
memcpy((ex_u8 *) (&m_head.info.magic), TPP_RECORD_MAGIC, sizeof(ex_u32));
|
||||
memcpy((ex_u8*) (&m_head.info.magic), TPP_RECORD_MAGIC, sizeof(ex_u32));
|
||||
m_head.info.ver = 0x04;
|
||||
m_head.info.type = TS_TPPR_TYPE_SSH;
|
||||
m_header_changed = false;
|
||||
m_save_full_header = false;
|
||||
|
||||
m_file_info = NULL;
|
||||
m_file_data = NULL;
|
||||
m_file_cmd = NULL;
|
||||
m_file_info = nullptr;
|
||||
m_file_data = nullptr;
|
||||
m_file_cmd = nullptr;
|
||||
|
||||
}
|
||||
|
||||
|
@ -23,10 +23,10 @@ TppSshRec::~TppSshRec() {
|
|||
end();
|
||||
}
|
||||
|
||||
bool TppSshRec::_on_begin(const TPP_CONNECT_INFO *info) {
|
||||
if (NULL == info)
|
||||
bool TppSshRec::_on_begin(const TPP_CONNECT_INFO* info) {
|
||||
if (nullptr == info)
|
||||
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_sub_type = (ex_u16) info->protocol_sub_type;
|
||||
m_head.basic.conn_port = (ex_u16) info->conn_port;
|
||||
|
@ -44,11 +44,11 @@ bool TppSshRec::_on_end() {
|
|||
// 如果还有剩下未写入的数据,写入文件中。
|
||||
save_record();
|
||||
|
||||
if (m_file_info != NULL)
|
||||
if (m_file_info != nullptr)
|
||||
fclose(m_file_info);
|
||||
if (m_file_data != NULL)
|
||||
if (m_file_data != nullptr)
|
||||
fclose(m_file_data);
|
||||
if (m_file_cmd != NULL)
|
||||
if (m_file_cmd != nullptr)
|
||||
fclose(m_file_cmd);
|
||||
|
||||
return true;
|
||||
|
@ -59,8 +59,8 @@ void TppSshRec::save_record() {
|
|||
_save_to_cmd_file();
|
||||
}
|
||||
|
||||
void TppSshRec::record(ex_u8 type, const ex_u8 *data, size_t size) {
|
||||
if (data == NULL || 0 == size)
|
||||
void TppSshRec::record(ex_u8 type, const ex_u8* data, size_t size) {
|
||||
if (data == nullptr || 0 == size)
|
||||
return;
|
||||
|
||||
if (sizeof(TS_RECORD_PKG) + size + m_cache.size() > MAX_SIZE_PER_FILE)
|
||||
|
@ -77,7 +77,7 @@ void TppSshRec::record(ex_u8 type, const ex_u8 *data, size_t size) {
|
|||
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_head.info.packages++;
|
||||
|
@ -94,11 +94,11 @@ void TppSshRec::record_win_size_change(int width, int height) {
|
|||
TS_RECORD_WIN_SIZE pkg = {0};
|
||||
pkg.width = (ex_u16) width;
|
||||
pkg.height = (ex_u16) height;
|
||||
record(TS_RECORD_TYPE_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};
|
||||
#ifdef EX_OS_WIN32
|
||||
// SYSTEMTIME st;
|
||||
|
@ -109,7 +109,7 @@ void TppSshRec::record_command(int flag, const ex_astr &cmd) {
|
|||
// struct tm *p;
|
||||
// time(&timep);
|
||||
// p = localtime(&timep);
|
||||
// if (p == NULL)
|
||||
// if (p == nullptr)
|
||||
// return;
|
||||
// sprintf(szTime, "[%04d-%02d-%02d %02d:%02d:%02d %d] ", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, flag);
|
||||
#endif
|
||||
|
@ -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)
|
||||
_save_to_cmd_file();
|
||||
|
||||
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 *) "\r\n", 2);
|
||||
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*) "\r\n", 2);
|
||||
}
|
||||
|
||||
bool TppSshRec::_save_to_info_file() {
|
||||
if (!m_header_changed)
|
||||
return true;
|
||||
|
||||
if (m_file_info == NULL) {
|
||||
if (m_file_info == nullptr) {
|
||||
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;
|
||||
|
||||
fname += L".tpr";
|
||||
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");
|
||||
return false;
|
||||
}
|
||||
|
@ -150,7 +150,8 @@ bool TppSshRec::_save_to_info_file() {
|
|||
fwrite(&m_head, ts_record_header_size, 1, m_file_info);
|
||||
fflush(m_file_info);
|
||||
m_save_full_header = false;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
fwrite(&m_head.info, ts_record_header_info_size, 1, m_file_info);
|
||||
fflush(m_file_info);
|
||||
}
|
||||
|
@ -162,14 +163,14 @@ bool TppSshRec::_save_to_data_file() {
|
|||
if (m_cache.size() == 0)
|
||||
return true;
|
||||
|
||||
if (m_file_data == NULL) {
|
||||
if (m_file_data == nullptr) {
|
||||
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;
|
||||
|
||||
fname += L".dat";
|
||||
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");
|
||||
return false;
|
||||
}
|
||||
|
@ -188,14 +189,14 @@ bool TppSshRec::_save_to_cmd_file() {
|
|||
if (m_cmd_cache.size() == 0)
|
||||
return true;
|
||||
|
||||
if (NULL == m_file_cmd) {
|
||||
if (nullptr == m_file_cmd) {
|
||||
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;
|
||||
|
||||
fname += L"-cmd.txt";
|
||||
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");
|
||||
return false;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -14,14 +14,13 @@
|
|||
|
||||
#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_SHELL 1
|
||||
#define TS_SSH_CHANNEL_TYPE_SFTP 2
|
||||
|
||||
enum SSH_SESSION_STATUS
|
||||
{
|
||||
enum SSH_SESSION_STATUS {
|
||||
SSH_SESSION_STATE_CLOSED = 0,
|
||||
SSH_SESSION_STATE_STARTING,
|
||||
SSH_SESSION_STATE_AUTHING,
|
||||
|
@ -35,35 +34,25 @@ class SshProxy;
|
|||
class SshSession;
|
||||
|
||||
class SshSession :
|
||||
public ExThreadBase
|
||||
{
|
||||
public ExThreadBase {
|
||||
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();
|
||||
|
||||
// uint32_t dbg_id() const
|
||||
// {
|
||||
// return m_dbg_id;
|
||||
// }
|
||||
|
||||
const std::string &dbg_name() const
|
||||
{
|
||||
const std::string& dbg_name() const {
|
||||
return m_dbg_name;
|
||||
}
|
||||
|
||||
const std::string &dbg_client() const
|
||||
{
|
||||
const std::string& dbg_client() const {
|
||||
return m_dbg_client;
|
||||
}
|
||||
|
||||
const std::string &dbg_server() const
|
||||
{
|
||||
const std::string& dbg_server() const {
|
||||
return m_dbg_server;
|
||||
}
|
||||
|
||||
const std::string &sid()
|
||||
{
|
||||
const std::string& sid() {
|
||||
return m_sid;
|
||||
}
|
||||
|
||||
|
@ -76,13 +65,11 @@ public:
|
|||
|
||||
void keep_alive();
|
||||
|
||||
bool closed() const
|
||||
{
|
||||
bool closed() const {
|
||||
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)
|
||||
return m_rs_tp2srv;
|
||||
else if (session == m_rs_tp2srv)
|
||||
|
@ -95,9 +82,11 @@ public:
|
|||
// 通道管理
|
||||
// --------------------------
|
||||
void set_channel_tp2srv_callbacks(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();
|
||||
|
||||
protected:
|
||||
|
@ -113,57 +102,57 @@ protected:
|
|||
private:
|
||||
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);
|
||||
|
||||
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:
|
||||
SshProxy *m_proxy;
|
||||
SshProxy* m_proxy;
|
||||
SSH_SESSION_STATUS m_state;
|
||||
ssh_session m_rs_tp2cli;
|
||||
ssh_session m_rs_tp2srv;
|
||||
ssh_session m_rs_tp2cli;
|
||||
ssh_session m_rs_tp2srv;
|
||||
|
||||
ExThreadLock m_lock;
|
||||
|
||||
uint32_t m_dbg_id;
|
||||
uint32_t m_dbg_id;
|
||||
std::string m_dbg_name;
|
||||
std::string m_dbg_client;
|
||||
std::string m_dbg_server;
|
||||
|
||||
TPP_CONNECT_INFO *m_conn_info;
|
||||
TPP_CONNECT_INFO* m_conn_info;
|
||||
|
||||
std::string m_sid;
|
||||
std::string m_conn_ip;
|
||||
uint16_t m_conn_port;
|
||||
uint16_t m_conn_port;
|
||||
std::string m_acc_name;
|
||||
std::string m_acc_secret;
|
||||
uint32_t m_flags;
|
||||
int m_auth_type;
|
||||
bool m_allow_user_input_password;
|
||||
uint32_t m_flags;
|
||||
int m_auth_type;
|
||||
bool m_allow_user_input_password;
|
||||
|
||||
bool m_first_auth;
|
||||
// 远程主机认证是否通过
|
||||
|
@ -171,25 +160,17 @@ private:
|
|||
// 发生了不可逆的错误,需要关闭整个会话(包括所有的通道)
|
||||
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;
|
||||
|
||||
|
||||
bool m_need_send_keepalive;
|
||||
|
||||
bool m_recving_from_srv; // 是否正在从服务器接收数据?
|
||||
bool m_recving_from_cli; // 是否正在从客户端接收数据?
|
||||
|
||||
struct ssh_server_callbacks_struct m_srv_cb;
|
||||
struct ssh_server_callbacks_struct m_srv_cb;
|
||||
struct ssh_channel_callbacks_struct m_cli_channel_cb;
|
||||
struct ssh_channel_callbacks_struct m_srv_channel_cb;
|
||||
};
|
||||
|
|
|
@ -2,37 +2,30 @@
|
|||
|
||||
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);
|
||||
|
||||
auto ps = args->cfg->GetSection(L"protocol-ssh");
|
||||
if (!ps)
|
||||
{
|
||||
if (!ps) {
|
||||
EXLOGE("[ssh] invalid config(2).\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ex_wstr tmp;
|
||||
if (!ps->GetStr(L"bind-ip", tmp))
|
||||
{
|
||||
if (!ps->GetStr(L"bind-ip", tmp)) {
|
||||
bind_ip = TS_SSH_PROXY_HOST;
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,18 +3,18 @@
|
|||
|
||||
#include "../../common/base_env.h"
|
||||
|
||||
class TppSshEnv : public TppEnvBase
|
||||
{
|
||||
class TppSshEnv : public TppEnvBase {
|
||||
public:
|
||||
TppSshEnv();
|
||||
~TppSshEnv();
|
||||
TppSshEnv() noexcept;
|
||||
|
||||
~TppSshEnv() override;
|
||||
|
||||
public:
|
||||
ex_astr bind_ip;
|
||||
int bind_port;
|
||||
int bind_port;
|
||||
|
||||
private:
|
||||
bool _on_init(TPP_INIT_ARGS *args);
|
||||
bool _on_init(TPP_INIT_ARGS* args) override;
|
||||
};
|
||||
|
||||
extern TppSshEnv g_ssh_env;
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
#include <teleport_const.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
|
||||
ssh_threads_set_callbacks(ssh_threads_get_pthread());
|
||||
ssh_init();
|
||||
|
@ -19,8 +18,7 @@ TPP_API ex_rv tpp_init(TPP_INIT_ARGS *init_args)
|
|||
return 0;
|
||||
}
|
||||
|
||||
TPP_API ex_rv tpp_start(void)
|
||||
{
|
||||
TPP_API ex_rv tpp_start(void) {
|
||||
if (!g_ssh_proxy.init())
|
||||
return TPE_FAILED;
|
||||
if (!g_ssh_proxy.start())
|
||||
|
@ -29,26 +27,23 @@ TPP_API ex_rv tpp_start(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
TPP_API ex_rv tpp_stop(void)
|
||||
{
|
||||
TPP_API ex_rv tpp_stop(void) {
|
||||
g_ssh_proxy.stop();
|
||||
ssh_finalize();
|
||||
return 0;
|
||||
}
|
||||
|
||||
TPP_API void tpp_timer(void)
|
||||
{
|
||||
TPP_API void tpp_timer(void) {
|
||||
// be called per one second.
|
||||
g_ssh_proxy.timer();
|
||||
}
|
||||
|
||||
static ex_rv tpp_cmd_set_runtime_config(const char *param)
|
||||
{
|
||||
Json::Value jp;
|
||||
Json::CharReaderBuilder jcrb;
|
||||
static ex_rv tpp_cmd_set_runtime_config(const char* param) {
|
||||
Json::Value jp;
|
||||
Json::CharReaderBuilder jcrb;
|
||||
std::unique_ptr<Json::CharReader> const jreader(jcrb.newCharReader());
|
||||
const char *str_json_begin = param;
|
||||
ex_astr err;
|
||||
const char* str_json_begin = param;
|
||||
ex_astr err;
|
||||
|
||||
if (!jreader->parse(str_json_begin, param + strlen(param), &jp, &err))
|
||||
return TPE_JSON_FORMAT;
|
||||
|
@ -68,12 +63,11 @@ static ex_rv tpp_cmd_set_runtime_config(const char *param)
|
|||
return TPE_PARAM;
|
||||
}
|
||||
|
||||
static ex_rv tpp_cmd_kill_sessions(const char *param)
|
||||
{
|
||||
Json::Value jp;
|
||||
static ex_rv tpp_cmd_kill_sessions(const char* param) {
|
||||
Json::Value jp;
|
||||
Json::CharReaderBuilder reader_builder;
|
||||
const char *str_json_begin = param;
|
||||
ex_astr err;
|
||||
const char* str_json_begin = param;
|
||||
ex_astr err;
|
||||
|
||||
std::unique_ptr<Json::CharReader> const json_reader(reader_builder.newCharReader());
|
||||
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;
|
||||
|
||||
for (const auto &item : jp)
|
||||
{
|
||||
if (!item.isString())
|
||||
{
|
||||
for (const auto& item : jp) {
|
||||
if (!item.isString()) {
|
||||
return TPE_PARAM;
|
||||
}
|
||||
|
||||
|
@ -99,18 +91,13 @@ static ex_rv tpp_cmd_kill_sessions(const char *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)
|
||||
return TPE_PARAM;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case TPP_CMD_SET_RUNTIME_CFG:
|
||||
return tpp_cmd_set_runtime_config(param);
|
||||
case TPP_CMD_KILL_SESSIONS:
|
||||
return tpp_cmd_kill_sessions(param);
|
||||
default:
|
||||
return TPE_UNKNOWN_CMD;
|
||||
switch (cmd) {
|
||||
case TPP_CMD_SET_RUNTIME_CFG:return tpp_cmd_set_runtime_config(param);
|
||||
case TPP_CMD_KILL_SESSIONS:return tpp_cmd_kill_sessions(param);
|
||||
default:return TPE_UNKNOWN_CMD;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -313,6 +313,9 @@ $app.on_table_host_render_created = function (render) {
|
|||
case TP_SESS_STAT_ERR_UNSUPPORT_PROTOCOL:
|
||||
msg = '协议不支持';
|
||||
break;
|
||||
case TP_SESS_STAT_ERR_CREATE_CHANNEL:
|
||||
msg = '无法创建数据通道';
|
||||
break;
|
||||
case TP_SESS_STAT_ERR_BAD_PKG:
|
||||
case TP_SESS_STAT_ERR_START_BAD_PKG:
|
||||
msg = '数据格式错误';
|
||||
|
|
|
@ -324,6 +324,9 @@ $app.on_table_session_render_created = function (render) {
|
|||
case TP_SESS_STAT_ERR_UNSUPPORT_PROTOCOL:
|
||||
msg = '协议不支持';
|
||||
break;
|
||||
case TP_SESS_STAT_ERR_CREATE_CHANNEL:
|
||||
msg = '无法创建数据通道';
|
||||
break;
|
||||
case TP_SESS_STAT_ERR_BAD_PKG:
|
||||
case TP_SESS_STAT_ERR_START_BAD_PKG:
|
||||
msg = '数据格式错误';
|
||||
|
|
|
@ -38,23 +38,26 @@ var TP_OS_TYPE_LINUX = 2;
|
|||
// =======================================================
|
||||
// 远程连接会话状态
|
||||
// =======================================================
|
||||
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_CONNECT = 2; // 会话结束,因为无法连接到远程主机
|
||||
var TP_SESS_STAT_ERR_BAD_SSH_KEY = 3; // 会话结束,因为无法识别SSH私钥
|
||||
var TP_SESS_STAT_ERR_INTERNAL = 4; // 会话结束,因为内部错误
|
||||
var TP_SESS_STAT_ERR_UNSUPPORT_PROTOCOL = 5; // 会话结束,因为协议不支持(RDP)
|
||||
var TP_SESS_STAT_ERR_BAD_PKG = 6; // 会话结束,因为收到错误的报文
|
||||
var TP_SESS_STAT_ERR_RESET = 7; // 会话结束,因为teleport核心服务重置了
|
||||
var TP_SESS_STAT_ERR_IO = 8; // 会话结束,因为网络中断
|
||||
var TP_SESS_STAT_ERR_SESSION = 9; // 会话结束,因为无效的会话ID
|
||||
var TP_SESS_STAT_ERR_AUTH_TYPE = 10; // // 会话结束,因为服务端不支持此认证方式
|
||||
var TP_SESS_STAT_STARTED = 100; // 已经连接成功了,开始记录录像了
|
||||
var TP_SESS_STAT_ERR_START_INTERNAL = 104; // 会话结束,因为内部错误
|
||||
var TP_SESS_STAT_ERR_START_BAD_PKG = 106; // 会话结束,因为收到错误的报文
|
||||
var TP_SESS_STAT_ERR_START_RESET = 107; // 会话结束,因为teleport核心服务重置了
|
||||
var TP_SESS_STAT_ERR_START_IO = 108; // 会话结束,因为网络中断
|
||||
var TP_SESS_STAT_RUNNING = 0; // 会话开始了,尚未结束,还在连接过程中
|
||||
var TP_SESS_STAT_ERR_AUTH_DENIED = 1; // 会话结束,因为认证失败
|
||||
var TP_SESS_STAT_ERR_CONNECT = 2; // 会话结束,因为无法连接到远程主机
|
||||
var TP_SESS_STAT_ERR_BAD_SSH_KEY = 3; // 会话结束,因为无法识别SSH私钥
|
||||
var TP_SESS_STAT_ERR_INTERNAL = 4; // 会话结束,因为内部错误
|
||||
var TP_SESS_STAT_ERR_UNSUPPORT_PROTOCOL = 5; // 会话结束,因为协议不支持(RDP)
|
||||
var TP_SESS_STAT_ERR_BAD_PKG = 6; // 会话结束,因为收到错误的报文
|
||||
var TP_SESS_STAT_ERR_RESET = 7; // 会话结束,因为teleport核心服务重置了
|
||||
var TP_SESS_STAT_ERR_IO = 8; // 会话结束,因为网络中断
|
||||
var TP_SESS_STAT_ERR_SESSION = 9; // 会话结束,因为无效的会话ID
|
||||
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_ERR_START_BAD_PKG = 106; // 会话结束,因为收到错误的报文
|
||||
var TP_SESS_STAT_ERR_START_RESET = 107; // 会话结束,因为teleport核心服务重置了
|
||||
var TP_SESS_STAT_ERR_START_IO = 108; // 会话结束,因为网络中断
|
||||
|
||||
var TP_SESS_STAT_END = 9999; // 会话成功结束
|
||||
|
||||
// ==========================================================================
|
||||
// 对象类型
|
||||
|
@ -332,7 +335,7 @@ function tp_error_msg(error_code, message) {
|
|||
case TPE_SYS_MAINTENANCE:
|
||||
msg = '系统维护中';
|
||||
break;
|
||||
|
||||
|
||||
case TPE_OATH_ALREADY_BIND:
|
||||
msg = '该账号已经绑定了身份验证器,如无法使用,请联系管理员重置密码或更换登录方式';
|
||||
break;
|
||||
|
|
|
@ -7,6 +7,7 @@ import sys
|
|||
import threading
|
||||
import time
|
||||
import traceback
|
||||
import builtins
|
||||
|
||||
__all__ = ['log']
|
||||
|
||||
|
@ -14,6 +15,7 @@ USE_TPWEB_LOG = False
|
|||
|
||||
try:
|
||||
import tpweb
|
||||
|
||||
USE_TPWEB_LOG = True
|
||||
except ImportError:
|
||||
pass
|
||||
|
@ -627,6 +629,4 @@ del Logger
|
|||
# log._test()
|
||||
# print('test built-in `print` function.')
|
||||
|
||||
import builtins
|
||||
|
||||
builtins.__dict__['print'] = log.log_print
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
from enum import IntEnum, unique
|
||||
|
||||
TP_LOGIN_AUTH_SYS_DEFAULT = 0 # 系统默认(根据系统配置进行)
|
||||
TP_LOGIN_AUTH_USERNAME_PASSWORD = 0x0001 # 用户名+密码
|
||||
TP_LOGIN_AUTH_USERNAME_PASSWORD_CAPTCHA = 0x0002 # 用户名+密码+验证码
|
||||
TP_LOGIN_AUTH_USERNAME_OATH = 0x0004 # 用户名+OATH
|
||||
TP_LOGIN_AUTH_USERNAME_PASSWORD_OATH = 0x0008 # 用户名+密码+OATH
|
||||
TP_LOGIN_AUTH_SYS_DEFAULT = 0 # 系统默认(根据系统配置进行)
|
||||
TP_LOGIN_AUTH_USERNAME_PASSWORD = 0x0001 # 用户名+密码
|
||||
TP_LOGIN_AUTH_USERNAME_PASSWORD_CAPTCHA = 0x0002 # 用户名+密码+验证码
|
||||
TP_LOGIN_AUTH_USERNAME_OATH = 0x0004 # 用户名+OATH
|
||||
TP_LOGIN_AUTH_USERNAME_PASSWORD_OATH = 0x0008 # 用户名+密码+OATH
|
||||
|
||||
APP_MODE_NORMAL = 1
|
||||
APP_MODE_MAINTENANCE = 2
|
||||
|
@ -67,7 +67,7 @@ TP_OS_TYPE_LINUX = 2
|
|||
# 远程连接会话状态
|
||||
# =======================================================
|
||||
TP_SESS_STAT_RUNNING = 0 # 会话开始了,尚未结束
|
||||
TP_SESS_STAT_END = 9999 # 会话成功结束
|
||||
|
||||
TP_SESS_STAT_ERR_AUTH_DENIED = 1 # 会话结束,因为认证失败
|
||||
TP_SESS_STAT_ERR_CONNECT = 2 # 会话结束,因为无法连接到远程主机
|
||||
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_IO = 8 # 会话结束,因为网络中断
|
||||
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_ERR_START_INTERNAL = 104 # 会话结束,因为内部错误
|
||||
TP_SESS_STAT_ERR_START_BAD_PKG = 106 # 会话结束,因为收到错误的报文
|
||||
TP_SESS_STAT_ERR_START_RESET = 107 # 会话结束,因为teleport核心服务重置了
|
||||
TP_SESS_STAT_ERR_START_IO = 108 # 会话结束,因为网络中断
|
||||
|
||||
TP_SESS_STAT_END = 9999 # 会话成功结束
|
||||
|
||||
# ==========================================================================
|
||||
# 分组类型
|
||||
# ==========================================================================
|
||||
|
@ -228,7 +234,7 @@ TPE_CAPTCHA_EXPIRED = 10000
|
|||
TPE_CAPTCHA_MISMATCH = 10001
|
||||
TPE_OATH_MISMATCH = 10002
|
||||
TPE_SYS_MAINTENANCE = 10003
|
||||
TPE_OATH_ALREADY_BIND = 10004
|
||||
TPE_OATH_ALREADY_BIND = 10004
|
||||
|
||||
TPE_USER_LOCKED = 10100
|
||||
TPE_USER_DISABLED = 10101
|
||||
|
|
Loading…
Reference in New Issue