summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLu <[email protected]>2018-07-20 20:01:07 +0800
committerLu <[email protected]>2018-07-20 20:01:07 +0800
commit0f197cd29e6a1d9b9be7323d0105f9a3100922c3 (patch)
treef738e790071471807c85f19772221314d86bff17 /src
parent5b9b1e38e9f71aedbfbec04bf5c42327d4b37194 (diff)
#11 增加HttpSession的追踪功能,在HttpSession析构时打印四元组、URL等信息,便于诊断问题。
增加全局线程号功能,启动多线程处理功能。
Diffstat (limited to 'src')
-rw-r--r--src/http.h293
-rw-r--r--src/http1.cc86
-rw-r--r--src/httpscan.cc18
-rw-r--r--src/main.cc15
-rw-r--r--src/pxythrmgr.cc19
-rw-r--r--src/pxythrmgr.h1
-rw-r--r--src/util.h14
7 files changed, 274 insertions, 172 deletions
diff --git a/src/http.h b/src/http.h
index 79da780..8059fcf 100644
--- a/src/http.h
+++ b/src/http.h
@@ -7,6 +7,7 @@
#include <string>
#include <list>
+#include "util.h"
#include "easylogging++.h"
class HttpConnection;
@@ -37,6 +38,151 @@ private:
connection_cb_t connection_close_cb_;
};
+class HttpHeaders
+{
+public:
+ HttpHeaders() = default;
+ virtual ~HttpHeaders() = default;
+
+ using str_field_t = std::string;
+ using str_value_t = std::string;
+
+ virtual void Add(const str_field_t & str_field, const str_value_t & str_value) = 0;
+ virtual void Set(const str_field_t & str_field, const str_value_t & str_value) = 0;
+ virtual void Remove(const str_field_t & str_field) = 0;
+
+ using for_each_cb_t = std::function<bool(const str_field_t &, const str_value_t &)>;
+
+ virtual bool ForEachHeader(for_each_cb_t cb) const = 0;
+ virtual bool ForEachValueOfHeader(const str_field_t & str_field, for_each_cb_t cb) const = 0;
+};
+
+class HttpRequest
+{
+public:
+ HttpRequest() = default;
+ virtual ~HttpRequest() = default;
+
+ /* URL读取、设置接口 */
+ virtual const std::string & Url() const = 0;
+ virtual void Url(const std::string & url) = 0;
+
+ virtual const std::string & Uri() const = 0;
+ virtual void Uri(const std::string & url) = 0;
+
+ /* HttpHeaders */
+ virtual HttpHeaders & Headers() = 0;
+ virtual const HttpHeaders & cHeaders() const = 0;
+
+ /* Request Body */
+ using body_content_t = std::vector<char>;
+ using body_content_ptr_t = std::unique_ptr<body_content_t>;
+
+ /* Body读取、设置接口 */
+ virtual const body_content_t * Body() const = 0;
+ virtual void Body(body_content_ptr_t body) = 0;
+
+ /* Body的Stolen接口 */
+ virtual body_content_ptr_t StolenBody() = 0;
+
+ /* Bypass,标记本请求为直通
+ * 当请求标记为直通时,转发数据,不再调用业务处理函数 */
+ virtual bool Bypass() = 0;
+ virtual void Bypass(bool is_bypass) = 0;
+
+ /* ReadOnly,标记本请求为只读。
+ * 当一个请求为只读请求时,业务不应修改它的内容,底层处理Readonly的请求时,应直接转发不缓存 */
+ virtual bool ReadOnly() = 0;
+ virtual void ReadOnly(bool is_readonly) = 0;
+
+ /* Forward,标记本请求应被转发到对端
+ * 当请求标记为不转发时,该请求被丢弃 */
+ virtual bool Forward() = 0;
+ virtual void Forward(bool is_forward) = 0;
+
+ /* 完整标记,该请求是否已经完整可用 */
+ enum section_t
+ {
+ kSectionHeader, kSectionBody, kSecionMessage
+ };
+ virtual bool Complete(section_t section) = 0;
+
+ /* HTTP版本 */
+ using version_t = std::tuple<short, short>;
+ virtual version_t Version() = 0;
+
+ /* 构建接口,根据结构化数据构建HTTP请求头部 */
+ virtual void Construct() = 0;
+
+ /* 调试接口 */
+ virtual std::string DumpToString() = 0;
+};
+
+class HttpResponse
+{
+public:
+ enum section_t
+ {
+ kSectionHeader,
+ kSectionBody,
+ kSectionMessage,
+ kSectionMax
+ };
+
+ enum section_state_t
+ {
+ kStateBegin,
+ kStateReading,
+ kStateComplete,
+ kStateStream,
+ kStateCalled,
+ kStateStolen
+ };
+
+public:
+ HttpResponse() = default;
+ virtual ~HttpResponse() = default;
+
+ /* 响应码 */
+ virtual int ResponseCode() = 0;
+ virtual void ResponseCode(int cde) = 0;
+
+ /* HttpHeaders */
+ virtual HttpHeaders & Headers() = 0;
+ virtual const HttpHeaders & cHeaders() const = 0;
+
+ /* Request Body */
+ using body_content_t = std::vector<char>;
+ using body_content_ptr_t = std::unique_ptr<body_content_t>;
+
+ /* Body读取、设置接口 */
+ virtual const std::vector<const body_content_t *> Body() const = 0;
+ virtual void Body(std::vector<body_content_ptr_t> body) = 0;
+ virtual std::vector<body_content_ptr_t> StolenBody() = 0;
+
+ /* ReadOnly,标记本请求为只读。
+ * 当一个请求为只读请求时,业务不应修改它的内容,底层处理Readonly的请求时,应直接转发不缓存 */
+ virtual bool ReadOnly() = 0;
+ virtual void ReadOnly(bool is_readonly) = 0;
+
+ /* Forward,标记本请求应被转发到对端
+ * 当请求标记为不转发时,该请求被丢弃 */
+ virtual bool Forward() = 0;
+ virtual void Forward(bool is_forward) = 0;
+
+ /* Bypass,标记本应答为直通
+ * 当应答标记为直通时,转发数据,不再调用业务处理函数 */
+ virtual bool Bypass() = 0;
+ virtual void Bypass(bool is_bypass) = 0;
+
+ virtual section_state_t SectionState(section_t section) = 0;
+ /* 构建指令,根据Object构建对应的Memory */
+ virtual void Construct() = 0;
+
+ /* 调试接口 */
+ virtual std::string DumpToString() = 0;
+};
+
class HttpConnection
{
public:
@@ -67,7 +213,7 @@ class HttpSession
{
public:
explicit HttpSession(HttpConnection & connection) : http_connection_(connection) {}
- virtual ~HttpSession() = default;
+ virtual ~HttpSession() { __dump_session(); }
using http_session_cb_t = std::function<void(HttpSession &)>;
@@ -191,145 +337,22 @@ private:
if (cb_tag == kCallbackTagRepeat) cb_tag = kCallBackTagOnlyOnce;
}
}
-};
-
-class HttpHeaders
-{
-public:
- HttpHeaders() = default;
- virtual ~HttpHeaders() = default;
-
- using str_field_t = std::string;
- using str_value_t = std::string;
-
- virtual void Add(const str_field_t & str_field, const str_value_t & str_value) = 0;
- virtual void Set(const str_field_t & str_field, const str_value_t & str_value) = 0;
- virtual void Remove(const str_field_t & str_field) = 0;
-
- using for_each_cb_t = std::function<bool(const str_field_t &, const str_value_t &)>;
-
- virtual bool ForEachHeader(for_each_cb_t cb) const = 0;
- virtual bool ForEachValueOfHeader(const str_field_t & str_field, for_each_cb_t cb) const = 0;
-};
-
-class HttpRequest
-{
-public:
- HttpRequest() = default;
- virtual ~HttpRequest() = default;
-
- /* URL读取、设置接口 */
- virtual const std::string & Url() const = 0;
- virtual void Url(const std::string & url) = 0;
-
- virtual const std::string & Uri() const = 0;
- virtual void Uri(const std::string & url) = 0;
-
- /* HttpHeaders */
- virtual HttpHeaders & Headers() = 0;
- virtual const HttpHeaders & cHeaders() const = 0;
-
- /* Request Body */
- using body_content_t = std::vector<char>;
- using body_content_ptr_t = std::unique_ptr<body_content_t>;
-
- /* Body读取、设置接口 */
- virtual const body_content_t * Body() const = 0;
- virtual void Body(body_content_ptr_t body) = 0;
-
- /* Body的Stolen接口 */
- virtual body_content_ptr_t StolenBody() = 0;
-
- /* Bypass,标记本请求为直通
- * 当请求标记为直通时,转发数据,不再调用业务处理函数 */
- virtual bool Bypass() = 0;
- virtual void Bypass(bool is_bypass) = 0;
-
- /* ReadOnly,标记本请求为只读。
- * 当一个请求为只读请求时,业务不应修改它的内容,底层处理Readonly的请求时,应直接转发不缓存 */
- virtual bool ReadOnly() = 0;
- virtual void ReadOnly(bool is_readonly) = 0;
-
- /* Forward,标记本请求应被转发到对端
- * 当请求标记为不转发时,该请求被丢弃 */
- virtual bool Forward() = 0;
- virtual void Forward(bool is_forward) = 0;
-
- /* 完整标记,该请求是否已经完整可用 */
- enum section_t
- {
- kSectionHeader, kSectionBody, kSecionMessage
- };
- virtual bool Complete(section_t section) = 0;
-
- /* HTTP版本 */
- using version_t = std::tuple<short, short>;
- virtual version_t Version() = 0;
-
- /* 构建接口,根据结构化数据构建HTTP请求头部 */
- virtual void Construct() = 0;
-};
-class HttpResponse
-{
-public:
- enum section_t
+ void __dump_session()
{
- kSectionHeader,
- kSectionBody,
- kSectionMessage,
- kSectionMax
- };
+ auto str_src_addr = sockaddr_to_string(http_connection_.SockAddrSource());
+ auto str_dst_addr = sockaddr_to_string(http_connection_.SockAddrDest());
- enum section_state_t
- {
- kStateBegin,
- kStateReading,
- kStateComplete,
- kStateStream,
- kStateCalled,
- kStateStolen
- };
+ auto str_request = request_->DumpToString();
+ auto str_response = response_->DumpToString();
-public:
- HttpResponse() = default;
- virtual ~HttpResponse() = default;
+ std::string status{};
+ if (NeedToDrop()) status += "DROP";
+ if (NeedToBypass()) status += "BYPASS";
- /* 响应码 */
- virtual int ResponseCode() = 0;
- virtual void ResponseCode(int cde) = 0;
-
- /* HttpHeaders */
- virtual HttpHeaders & Headers() = 0;
- virtual const HttpHeaders & cHeaders() const = 0;
-
- /* Request Body */
- using body_content_t = std::vector<char>;
- using body_content_ptr_t = std::unique_ptr<body_content_t>;
-
- /* Body读取、设置接口 */
- virtual const std::vector<const body_content_t *> Body() const = 0;
- virtual void Body(std::vector<body_content_ptr_t> body) = 0;
- virtual std::vector<body_content_ptr_t> StolenBody() = 0;
-
- /* ReadOnly,标记本请求为只读。
- * 当一个请求为只读请求时,业务不应修改它的内容,底层处理Readonly的请求时,应直接转发不缓存 */
- virtual bool ReadOnly() = 0;
- virtual void ReadOnly(bool is_readonly) = 0;
-
- /* Forward,标记本请求应被转发到对端
- * 当请求标记为不转发时,该请求被丢弃 */
- virtual bool Forward() = 0;
- virtual void Forward(bool is_forward) = 0;
-
- /* Bypass,标记本应答为直通
- * 当应答标记为直通时,转发数据,不再调用业务处理函数 */
- virtual bool Bypass() = 0;
- virtual void Bypass(bool is_bypass) = 0;
-
- virtual section_state_t SectionState(section_t section) = 0;
- /* 构建指令,根据Object构建对应的Memory */
- virtual void Construct() = 0;
+ CLOG(DEBUG, "HttpSessionTrace") << str_src_addr << str_dst_addr
+ << str_request << str_response << status;
+ }
};
std::unique_ptr<HttpRequest> HttpRequestFactory(int primary_version, int second_version);
diff --git a/src/http1.cc b/src/http1.cc
index 7b31ae2..b51635c 100644
--- a/src/http1.cc
+++ b/src/http1.cc
@@ -209,6 +209,8 @@ public:
void Bypass(bool is_bypass) override
{}
+ std::string DumpToString() override;
+
private:
/* Http Version */
short major_version_{1};
@@ -356,7 +358,7 @@ ssize_t Http1Request::ConstructFromMemory(const char * buf, size_t buflen)
/* 解析失败 */
if(sz_parsed && parser_->http_errno > 0)
{
- throw invalid_input_format(string_format("Failed at http parsing: errcode=%u, %s, %s",
+ throw std::runtime_error(string_format("Failed at http parsing: errcode=%u, %s, %s",
parser_->http_errno, http_errno_name(static_cast<http_errno>(parser_->http_errno)),
http_errno_description(static_cast<http_errno>(parser_->http_errno))));
}
@@ -417,6 +419,11 @@ void Http1Request::Construct()
return;
}
+std::string Http1Request::DumpToString()
+{
+ return string_format("HTTP/%d.%d %s", major_version_, minor_version_, str_url_.c_str());
+}
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// HTTP Response Parser Implementation for HTTP 1.0/1.1
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -565,8 +572,10 @@ public:
}
}
+ std::string DumpToString() override;
+
private:
- int resp_code_;
+ int resp_code_{-1};
short resp_version_major_{1};
short resp_version_minor_{1};
@@ -604,6 +613,10 @@ private:
Http1Headers headers_{};
std::string last_header_field_{};
+ /* Headers For Debug */
+ std::string content_type;
+ std::string content_length;
+
/* Parser & Raw Content
* 该原始内容,等价于本结构体的序列化后的结果,因此,输入的、未经解析的字节数据,不应该保留在这个位置 */
std::unique_ptr<struct http_parser> parser_{new struct http_parser};
@@ -702,6 +715,20 @@ int Http1ResponseParserCallbacks::CallbackOnHeaderComplete(http_parser * parser)
/* Flush Last HTTP Resp Header-Value */
resp_ptr->headers_.ConstructByHttpParserComplete();
+
+ /* Lookup Content-Type and Content-Length */
+ resp_ptr->headers_.ForEachValueOfHeader("Content-Type", [resp_ptr](const std::string & f, const std::string &v)
+ {
+ resp_ptr->content_type = v;
+ return false;
+ });
+
+ resp_ptr->headers_.ForEachValueOfHeader("Content-Length", [resp_ptr](const std::string & f, const std::string &v)
+ {
+ resp_ptr->content_length = v;
+ return false;
+ });
+
return 0;
}
@@ -787,7 +814,7 @@ ssize_t Http1Response::ConstructFromMemory(const char * buf, size_t buflen)
/* 解析错误 */
if (sz_parsed && parser_->http_errno > 0)
{
- throw invalid_input_format(string_format("Failed at http parsing: errcode=%u, %s, %s",
+ throw std::runtime_error(string_format("Failed at http parsing: errcode=%u, %s, %s",
parser_->http_errno, http_errno_name(static_cast<http_errno>(parser_->http_errno)),
http_errno_description(static_cast<http_errno>(parser_->http_errno))));
}
@@ -889,6 +916,11 @@ evbuffer_unique_ptr_t Http1Response::StolenEvBuf()
return std::move(evbuf_content_raw_);
}
+std::string Http1Response::DumpToString()
+{
+ return {std::to_string(resp_code_) + " " + content_type + " " + content_length};
+}
+
int Http1Connection::on_connection_close(pxy_conn_ctx_t * conn_ctx, struct bufferevent * bev)
{
return 0;
@@ -905,25 +937,34 @@ int Http1Connection::on_connection_read_request(pxy_conn_ctx_t * conn_ctx, pxy_c
auto * downstream_evbuf = bufferevent_get_input(conn_this->bev);
auto * upstream_evbuf = bufferevent_get_output(conn_other->bev);
- ssize_t forward_len = request.ConstructFromEvBuf(downstream_evbuf);
- if (forward_len < 0)
+ ssize_t forward_len = 0;
+ try
+ {
+ forward_len = request.ConstructFromEvBuf(downstream_evbuf);
+ }
+ catch (std::runtime_error & err)
{
- LOG(DEBUG) << "ctx = " << conn_ctx << " "
- << "RequestConstructFromEvBuf Failed, connection turns to passthrough";
+ auto str_src_addr = sockaddr_to_string(SockAddrSource());
+ auto str_dst_addr = sockaddr_to_string(SockAddrDest());
+ LOG(ERROR) << str_src_addr << str_dst_addr << "PASSTHROUGH" << err.what();
+ conn_ctx->passthrough = 1;
+ return 0;
+ }
+
+ if (forward_len < 0)
+ {
conn_ctx->passthrough = 1;
return 0;
}
if (request.Complete(HttpRequest::kSectionHeader))
{
- LOG(DEBUG) << std::addressof(http_session) << "CallRequestHeaderCallback";
http_session->CallRequestHeaderCallback();
}
if (request.Complete(HttpRequest::kSectionBody) && request.Body() != nullptr)
{
- LOG(DEBUG) << std::addressof(http_session) << "CallRequestBodyCallback";
http_session->CallRequestBodyCallback();
}
@@ -946,12 +987,18 @@ int Http1Connection::on_connection_read_response(pxy_conn_ctx_t * conn_ctx, pxy_
pxy_conn_desc_t * conn_other)
{
auto * session = last_uncomplete_session(kDirectionResponse);
- assert(session != nullptr);
-
- auto & response = dynamic_cast<Http1Response &>(session->response());
auto * downstream_evbuf = bufferevent_get_input(conn_this->bev);
auto * upstream_evbuf = bufferevent_get_output(conn_other->bev);
+ if (session == nullptr)
+ {
+ LOG(WARNING) << "Found standlone HTTP response, Ignore it.";
+ LOG(WARNING) << hexdump("upstream recieve buffer", upstream_evbuf);
+ return 0;
+ }
+
+ auto & response = dynamic_cast<Http1Response &>(session->response());
+
/* 检查Bypass和Drop标记,该标记可能由请求侧设置
* 设置任何一个,即不调用上层业务函数,直接解析到消息结束 */
if (session->NeedToBypass() || session->NeedToDrop())
@@ -959,12 +1006,23 @@ int Http1Connection::on_connection_read_response(pxy_conn_ctx_t * conn_ctx, pxy_
response.Bypass(true);
}
- ssize_t forward_len = response.ConstructFromEvBuf(downstream_evbuf);
- if (forward_len <= 0)
+ ssize_t forward_len = 0;
+ try
{
+ forward_len = response.ConstructFromEvBuf(downstream_evbuf);
+ }
+ catch (std::runtime_error & err)
+ {
+ auto str_src_addr = sockaddr_to_string(SockAddrSource());
+ auto str_dst_addr = sockaddr_to_string(SockAddrDest());
+
+ LOG(ERROR) << str_src_addr << str_dst_addr << "PASSTHROUGH" << err.what();
+ conn_ctx->passthrough = 1;
return 0;
}
+ if (forward_len <= 0) return 0;
+
if (response.SectionState(response.kSectionHeader) == response.kStateComplete)
{
session->CallResponseHeaderCallback();
diff --git a/src/httpscan.cc b/src/httpscan.cc
index 8f3a20c..991d6c9 100644
--- a/src/httpscan.cc
+++ b/src/httpscan.cc
@@ -134,7 +134,8 @@ void HttpScanSession::ScanRequestHeader(HttpSession * http_session_ctx)
/* 扫描IP地址 */
nr_maat_scan_result_ = Maat_scan_addr(httpscan_module_ref_.maat_feather_ref,
httpscan_module_ref_.table_id_ctrl_ip, sapp_tuple4_ptr.get(),
- maat_scan_result_, MAAT_SCAN_RESULT_, &maat_scan_mid_, 0);
+ maat_scan_result_, MAAT_SCAN_RESULT_,
+ &maat_scan_mid_, tfe_thread_current_thread_id());
/* 以下所有扫描命中后,配置callback tag为repeat,在本函数返回后,再次调用RequestHeader处理回调
* 函数,执行命中动作 */
@@ -153,7 +154,8 @@ void HttpScanSession::ScanRequestHeader(HttpSession * http_session_ctx)
nr_maat_scan_result_ = Maat_full_scan_string(httpscan_module_ref_.maat_feather_ref,
httpscan_module_ref_.table_id_ctrl_http_url, CHARSET_UTF8, __url.c_str(), (int) __url.length(),
- maat_scan_result_, dummy, MAAT_SCAN_RESULT_, &maat_scan_mid_, 0);
+ maat_scan_result_, dummy, MAAT_SCAN_RESULT_,
+ &maat_scan_mid_, tfe_thread_current_thread_id());
if (nr_maat_scan_result_ > 0)
{
@@ -184,7 +186,8 @@ void HttpScanSession::ScanRequestHeader(HttpSession * http_session_ctx)
nr_maat_scan_result_ = Maat_full_scan_string(httpscan_module_ref_.maat_feather_ref,
httpscan_module_ref_.table_id_ctrl_http_req_hdr, MAAT_DEFAULT_CHARSET_,
- value.c_str(), (int) value.length(), maat_scan_result_, __dummy, MAAT_SCAN_RESULT_, &maat_scan_mid_, 0);
+ value.c_str(), (int) value.length(), maat_scan_result_, __dummy, MAAT_SCAN_RESULT_,
+ &maat_scan_mid_, tfe_thread_current_thread_id());
if (nr_maat_scan_result_ > 0)
{
@@ -215,7 +218,7 @@ void HttpScanSession::ScanRequestBody(HttpSession * http_session_ctx)
nr_maat_scan_result_ = Maat_full_scan_string(httpscan_module_ref_.maat_feather_ref,
httpscan_module_ref_.table_id_ctrl_http_req_body, CHARSET_UTF8, body_content_raw, (int) body_content_length,
- maat_scan_result_, __dummy, MAAT_SCAN_RESULT_, &maat_scan_mid_, 0);
+ maat_scan_result_, __dummy, MAAT_SCAN_RESULT_, &maat_scan_mid_, tfe_thread_current_thread_id());
if (nr_maat_scan_result_ > 0)
{
@@ -311,7 +314,7 @@ HttpScanSession::scan_result_t HttpScanSession::scan_headers(const HttpHeaders &
nr_maat_scan_result_ = Maat_full_scan_string(httpscan_module_ref_.maat_feather_ref,
table_id, MAAT_DEFAULT_CHARSET_, value.c_str(), (int) value.length(), maat_scan_result_, __dummy,
- MAAT_SCAN_RESULT_, &maat_scan_mid_, 0);
+ MAAT_SCAN_RESULT_, &maat_scan_mid_, tfe_thread_current_thread_id());
if (nr_maat_scan_result_ > 0)
{
@@ -336,7 +339,8 @@ HttpScanSession::scan_result_t HttpScanSession::scan_body(const char * data, siz
int __dummy[MAAT_SCAN_RESULT_];
nr_maat_scan_result_ = Maat_full_scan_string(httpscan_module_ref_.maat_feather_ref,
- table_id, CHARSET_UTF8, data, (int) len, maat_scan_result_, __dummy, MAAT_SCAN_RESULT_, &maat_scan_mid_, 0);
+ table_id, CHARSET_UTF8, data, (int) len, maat_scan_result_, __dummy, MAAT_SCAN_RESULT_,
+ &maat_scan_mid_, tfe_thread_current_thread_id());
if (nr_maat_scan_result_ > 0)
return scan_result_t::kScanResultHit;
@@ -357,7 +361,7 @@ HttpScanSession::scan_result_t HttpScanSession::scan_bypass_content_type(const H
content_type = value; return false;
});
- if (content_type.find("text") == 0)
+ if (content_type.find("text") != 0)
{
return scan_result_t::kScanResultHit;
}
diff --git a/src/main.cc b/src/main.cc
index 8440962..bd9fbfd 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -293,13 +293,14 @@ main(int argc, char *argv[])
event_enable_debug_logging(0);
START_EASYLOGGINGPP(argc, argv);
+ el::Loggers::configureFromGlobal("conf/logger.conf");
el::Loggers::addFlag(el::LoggingFlag::MultiLoggerSupport);
el::Loggers::addFlag(el::LoggingFlag::AutoSpacing);
- el::Loggers::reconfigureAllLoggers(el::ConfigurationType::SubsecondPrecision, "6");
el::Loggers::getLogger("structLogger");
el::Loggers::getLogger("conntrace");
el::Loggers::getLogger("HttpScanTrace");
+ el::Loggers::getLogger("HttpSessionTrace");
if (nat_getdefaultname())
{
@@ -917,8 +918,8 @@ main(int argc, char *argv[])
g_tfe_instance->http_module = std::make_unique<Http>();
g_tfe_instance->http_scan_module = std::make_unique<HttpScan>(g_tfe_instance, g_tfe_config);
-
g_tfe_instance->stat_module = tfe_stat_create("conf/tfe.conf");
+
if (g_tfe_instance->stat_module == NULL)
{
log_err_printf("Failed to create stat module, exited.");
@@ -963,16 +964,6 @@ main(int argc, char *argv[])
goto out_sslreinit_failed;
}
-#if 0
- /* Post-privdrop/chroot/detach initialization, thread spawning */
- if (log_init(opts, proxy, clisock[1], clisock[2]) == -1) {
- fprintf(stderr, "%s: failed to init log facility: %s\n",
- argv0, strerror(errno));
- goto out_log_failed;
- }
-
-#endif
-
if (cachemgr_init() == -1) {
log_err_printf("Failed to init cache manager.\n");
goto out_cachemgr_failed;
diff --git a/src/pxythrmgr.cc b/src/pxythrmgr.cc
index 39d2086..b3357b3 100644
--- a/src/pxythrmgr.cc
+++ b/src/pxythrmgr.cc
@@ -62,6 +62,8 @@ struct tfe_thread_ctx
~tfe_thread_ctx();
};
+__thread int __currect_thread_id;
+
tfe_thread_ctx::tfe_thread_ctx(int thread_id, bool en_dns_base) : thread_id(thread_id), running(false)
{
evbase = event_base_new();
@@ -120,14 +122,16 @@ static void *__tfe_thrmgr_thread_entry(void *arg)
struct event *ev;
ev = event_new(ctx->evbase, -1, EV_PERSIST, __dummy_event_handler, NULL);
- if (!ev)
- return NULL;
+ if (!ev) return NULL;
evtimer_add(ev, &timer_delay);
ctx->running = 1;
+
+ __currect_thread_id = ctx->thread_id;
+ LOG(INFO) << string_format("EventThread %d is running...", __currect_thread_id);
+
event_base_dispatch(ctx->evbase);
event_free(ev);
-
return NULL;
}
@@ -211,7 +215,7 @@ int tfe_thread_manager_attach(tfe_thread_manager_ctx *ctx,
for (unsigned thread_id = 1; thread_id < ctx->nr_thread; thread_id++)
{
- if (min_load > ctx->thr_ctx[min_thread_id]->load)
+ if (min_load > ctx->thr_ctx[thread_id]->load)
{
min_load = ctx->thr_ctx[thread_id]->load;
min_thread_id = thread_id;
@@ -222,6 +226,8 @@ int tfe_thread_manager_attach(tfe_thread_manager_ctx *ctx,
*dnsbase = ctx->thr_ctx[min_thread_id]->dnsbase;
ctx->thr_ctx[min_thread_id]->load++;
+
+ LOG(DEBUG) << "new connection attached to the thread, thread id =" << min_thread_id;
return min_thread_id;
}
@@ -235,4 +241,9 @@ void tfe_thread_manager_detach(tfe_thread_manager_ctx *ctx, int thread_id)
ctx->thr_ctx[thread_id]->load--;
}
+int tfe_thread_current_thread_id()
+{
+ return __currect_thread_id;
+}
+
/* vim: set noet ft=c: */ \ No newline at end of file
diff --git a/src/pxythrmgr.h b/src/pxythrmgr.h
index 782ead2..94bfe90 100644
--- a/src/pxythrmgr.h
+++ b/src/pxythrmgr.h
@@ -48,6 +48,7 @@ int tfe_thread_manager_attach(tfe_thread_manager_ctx *, struct event_base **,
struct evdns_base **) WUNRES;
void tfe_thread_manager_detach(tfe_thread_manager_ctx *, int);
+int tfe_thread_current_thread_id();
#endif /* !PXYTHRMGR_H */
diff --git a/src/util.h b/src/util.h
index 62e6a82..cde06d5 100644
--- a/src/util.h
+++ b/src/util.h
@@ -245,3 +245,17 @@ static std::string hexdump(const char * title, const void * buf, unsigned int le
return str_ret;
}
+
+extern "C"
+{
+#include <event2/buffer.h>
+}
+
+static std::string hexdump(const char * title, struct evbuffer * evbuf)
+{
+ auto buffer_len = evbuffer_get_length(evbuf);
+ auto buffer_ptr = std::unique_ptr<char[]>(new char[buffer_len]);
+
+ evbuffer_copyout(evbuf, buffer_ptr.get(), buffer_len);
+ return hexdump(title, buffer_ptr.get(), (unsigned int)buffer_len);
+} \ No newline at end of file