summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLu <[email protected]>2018-07-11 10:07:30 +0800
committerLu <[email protected]>2018-07-11 10:07:30 +0800
commit1bc920eeeac977acf1528ee4058d8bb2e701d308 (patch)
tree2f4fb26f08226818a09e0f62382b630da887594d
parentad2eadc4063e9335ff1c991b2d316ab92b80625b (diff)
支持对SSL的加解密、业务处理
-rw-r--r--src/cfgparser.h23
-rw-r--r--src/http.h2
-rw-r--r--src/httpscan.cc2
-rw-r--r--src/logger.cc5
-rw-r--r--src/logger.h2
-rw-r--r--src/main.cc24
-rw-r--r--src/opts.cc283
-rw-r--r--src/proxy.cc2
-rw-r--r--src/pxyconn.cc141
-rw-r--r--src/pxysslshut.cc2
10 files changed, 281 insertions, 205 deletions
diff --git a/src/cfgparser.h b/src/cfgparser.h
index 474ed12..321432d 100644
--- a/src/cfgparser.h
+++ b/src/cfgparser.h
@@ -34,6 +34,9 @@ public:
template<typename T>
T GetValueWithDefault(const std::string &str_section, const std::string &str_entry, const T & default_value);
+ template<typename T>
+ std::pair<bool, T> TryGetValue(const std::string & str_section, const std::string & str_entry);
+
const std::string & Source() { return str_cfgfile_; }
private:
@@ -55,5 +58,21 @@ T TfeConfigParser::GetValueWithDefault(const std::string &str_section, const std
return default_value;
}
- return std::move(__value);
-} \ No newline at end of file
+ return __value;
+}
+
+template<typename T>
+std::pair<bool, T> TfeConfigParser::TryGetValue(const std::string & str_section, const std::string & str_entry)
+{
+ T __value;
+ try
+ {
+ __value = GetValue<T>(str_section, str_entry);
+ }
+ catch (...)
+ {
+ return {false, {}};
+ }
+
+ return {true, __value};
+}
diff --git a/src/http.h b/src/http.h
index 12f2992..b30a223 100644
--- a/src/http.h
+++ b/src/http.h
@@ -296,7 +296,7 @@ public:
private:
using http_sessions_t = std::list<std::unique_ptr<HttpSession>>;
- http_sessions_t http_sessions_;
+ http_sessions_t http_sessions_{};
HttpSession & create_new_session();
HttpSession & last_uncomplete_session();
diff --git a/src/httpscan.cc b/src/httpscan.cc
index 6366f85..56c57e2 100644
--- a/src/httpscan.cc
+++ b/src/httpscan.cc
@@ -123,6 +123,7 @@ void HttpScanSession::ScanRequestHeader(HttpSession * http_session_ctx)
auto & http_request = http_session_ctx->request();
int dummy[MAAT_SCAN_RESULT_];
+#if 0
/* 扫描IP地址,获取连接对应的四元组 */
const auto & connection = http_session_ctx->connection();
const auto * sockaddr_src = connection.SockAddrSource();
@@ -147,6 +148,7 @@ void HttpScanSession::ScanRequestHeader(HttpSession * http_session_ctx)
{
return hit_scan_error();
}
+#endif
/* 扫描HTTP URL */
const auto & __url = http_request.Url();
diff --git a/src/logger.cc b/src/logger.cc
index b66d5cc..dff9e7c 100644
--- a/src/logger.cc
+++ b/src/logger.cc
@@ -14,9 +14,8 @@ const char * __topic_id_to_string(int topic_id)
{
static std::map<int, const char *> __topic_id_to_string_map =
{
- //{LOG_TOPIC_CTRL_IP, "PXY_CTRL_IP"},
- //{LOG_TOPIC_CTRL_HTTP, "PXY_CTRL_HTTP"},
- {LOG_TOPIC_CTRL_HTTP, "TFE_TEST"},
+ {LOG_TOPIC_CTRL_IP, "PXY_CTRL_IP"},
+ {LOG_TOPIC_CTRL_HTTP, "PXY_CTRL_HTTP"},
};
return __topic_id_to_string_map[topic_id];
diff --git a/src/logger.h b/src/logger.h
index 3163f77..4f658e4 100644
--- a/src/logger.h
+++ b/src/logger.h
@@ -23,7 +23,7 @@ public:
enum
{
- //LOG_TOPIC_CTRL_IP,
+ LOG_TOPIC_CTRL_IP,
LOG_TOPIC_CTRL_HTTP,
LOG_TOPIC_CTRL_MAX
};
diff --git a/src/main.cc b/src/main.cc
index c473cec..ea4b6c5 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -593,18 +593,6 @@ main(int argc, char *argv[])
if (opts->contentlog)
free(opts->contentlog);
-#if 0
- if (log_content_split_pathspec(optarg, &lhs,
- &rhs) == -1) {
- fprintf(stderr, "%s: Failed to split "
- "'%s' in lhs/rhs: "
- "%s (%i)\n",
- argv0, optarg,
- strerror(errno), errno);
- exit(EXIT_FAILURE);
- }
-#endif
-
/* eliminate %% from lhs */
for (p = q = lhs; *p; p++, q++) {
if (q < p)
@@ -676,11 +664,6 @@ main(int argc, char *argv[])
oom_die(argv0);
break;
}
-#ifdef HAVE_LOCAL_PROCINFO
- case 'i':
- opts->lprocinfo = 1;
- break;
-#endif /* HAVE_LOCAL_PROCINFO */
case 'M':
if (opts->masterkeylog)
free(opts->masterkeylog);
@@ -691,12 +674,7 @@ main(int argc, char *argv[])
case 'd':
opts->detach = 1;
break;
-#if 0
- case 'D':
- log_dbg_mode(LOG_DBG_MODE_ERRLOG);
- opts->debug = 1;
- break;
-#endif
+
case 'V':
main_version();
exit(EXIT_SUCCESS);
diff --git a/src/opts.cc b/src/opts.cc
index 6ff8751..d676242 100644
--- a/src/opts.cc
+++ b/src/opts.cc
@@ -54,10 +54,10 @@ extern "C"
#include <Maat_rule.h>
-struct tfe_config *tfe_config_new()
+struct tfe_config * tfe_config_new()
{
- struct tfe_config *__config;
- __config = (struct tfe_config *)malloc(sizeof(struct tfe_config));
+ struct tfe_config * __config;
+ __config = (struct tfe_config *) malloc(sizeof(struct tfe_config));
memset(__config, 0, sizeof(struct tfe_config));
__config->sslcomp = 1;
@@ -68,13 +68,11 @@ struct tfe_config *tfe_config_new()
#define TFE_STRING_MAX 4096
-static int __proxyspec_parse_each_entry(
- tfe_config *cfg,
- TfeConfigParser &ini_config_object,
- const std::string &str_proxyspec)
+static int __proxyspec_parse_each_entry(tfe_config * cfg, TfeConfigParser & ini_config_object,
+ const std::string & str_proxyspec)
{
const std::string str_section = "proxyspec:" + str_proxyspec;
- const char *cstr_str_section = str_section.c_str();
+ const char * cstr_str_section = str_section.c_str();
std::string str_listen_addr;
std::string str_listen_port;
@@ -86,7 +84,7 @@ static int __proxyspec_parse_each_entry(
str_natengine = ini_config_object.GetValue<std::string>(str_section, "natengine");
str_protocol = ini_config_object.GetValue<std::string>(str_section, "protocol");
- struct proxyspec *__spec = (proxyspec *) malloc(sizeof(proxyspec));
+ struct proxyspec * __spec = (proxyspec *) malloc(sizeof(proxyspec));
memset(__spec, 0, sizeof(proxyspec));
if (str_protocol == "http")
@@ -94,17 +92,20 @@ static int __proxyspec_parse_each_entry(
__spec->ssl = 0;
__spec->http = 1;
__spec->upgrade = 0;
- } else if (str_protocol == "https")
+ }
+ else if (str_protocol == "https")
{
__spec->ssl = 1;
__spec->http = 1;
__spec->upgrade = 0;
- } else if (str_protocol == "ssl")
+ }
+ else if (str_protocol == "ssl")
{
__spec->ssl = 1;
__spec->http = 0;
__spec->upgrade = 0;
- } else if (str_protocol == "autossl")
+ }
+ else if (str_protocol == "autossl")
{
__spec->ssl = 0;
__spec->http = 0;
@@ -116,6 +117,7 @@ static int __proxyspec_parse_each_entry(
int ret = sys_sockaddr_parse(&__spec->listen_addr, &__spec->listen_addrlen, str_listen_addr.c_str(),
str_listen_port.c_str(), AF_INET, EVUTIL_AI_PASSIVE);
+
if (ret < 0)
{
throw cfg_invalid_format("", "", "", "");
@@ -132,7 +134,82 @@ static int __proxyspec_parse_each_entry(
return 0;
}
-static int __ssl_protocol_load_from_file(tfe_config *cfg, TfeConfigParser &cfg_parser)
+void __throw_ssl_load_exception(int err, std::string what)
+{
+ /* 系统错误 */
+ if (err)
+ {
+ throw std::system_error(err,std::generic_category(), what);
+ }
+
+ /* SSL错误 */
+ std::string ssl_err_info;
+ ERR_print_errors_cb([](const char *str, size_t len, void *u)->int
+ {
+ std::string * __str_err_info_ptr = static_cast<std::string *>(u);
+ * __str_err_info_ptr = std::string(str, len);
+ return 0;
+ },static_cast<void *>(&ssl_err_info));
+
+ throw std::runtime_error(what + ":" + ssl_err_info);
+}
+
+static int __ssl_protocol_load_cakey(tfe_config * cfg, const std::string & str_cakey)
+{
+ if (cfg->cakey)
+ {
+ EVP_PKEY_free(cfg->cakey);
+ }
+
+ cfg->cakey = ssl_key_load(str_cakey.c_str());
+ if (!cfg->cakey)
+ {
+ __throw_ssl_load_exception(errno, string_format("Error loading CA keys from %s", str_cakey.c_str()));
+ }
+
+ if (!cfg->cacrt)
+ {
+ cfg->cacrt = ssl_x509_load(str_cakey.c_str());
+ if (cfg->cacrt)
+ {
+ ssl_x509_refcount_inc(cfg->cacrt);
+ sk_X509_insert(cfg->chain, cfg->cacrt, 0);
+ }
+ }
+
+ return 0;
+}
+
+static int __ssl_protocol_load_cacert(tfe_config * cfg, const std::string & str_cacrt)
+{
+ if (cfg->cacrt)
+ {
+ X509_free(cfg->cacrt);
+ }
+
+ cfg->cacrt = ssl_x509_load(str_cacrt.c_str());
+ if (!cfg->cacrt)
+ {
+ __throw_ssl_load_exception(errno, string_format("error loading CA cert from %s", str_cacrt.c_str()));
+ }
+
+ ssl_x509_refcount_inc(cfg->cacrt);
+ sk_X509_insert(cfg->chain, cfg->cacrt, 0);
+
+ if (!cfg->cakey)
+ {
+ cfg->cakey = ssl_key_load(str_cacrt.c_str());
+ }
+
+ if (!cfg->dh)
+ {
+ cfg->dh = ssl_dh_load(str_cacrt.c_str());
+ }
+
+ return 0;
+}
+
+static int __ssl_protocol_load_from_file(tfe_config * cfg, TfeConfigParser & cfg_parser)
{
bool __en_tls_1_0 = true;
bool __en_tls_1_1 = true;
@@ -152,17 +229,29 @@ static int __ssl_protocol_load_from_file(tfe_config *cfg, TfeConfigParser &cfg_p
if (!__en_ssl_v2) cfg->no_ssl2 = 1;
if (!__en_ssl_v3) cfg->no_ssl3 = 1;
+ auto ca_key_ret = cfg_parser.TryGetValue<std::string>("ssl_protocol", "ca_key");
+ if (ca_key_ret.first)
+ {
+ __ssl_protocol_load_cakey(cfg, ca_key_ret.second);
+ }
+
+ auto ca_crt_ret = cfg_parser.TryGetValue<std::string>("ssl_protocol", "ca_crt");
+ if (ca_crt_ret.first)
+ {
+ __ssl_protocol_load_cacert(cfg, ca_crt_ret.second);
+ }
+
return 0;
}
-static int __maatframe_load_from_file(tfe_config *cfg, TfeConfigParser &cfg_parser)
+static int __maatframe_load_from_file(tfe_config * cfg, TfeConfigParser & cfg_parser)
{
if (cfg->maat_config == nullptr)
{
cfg->maat_config = new() tfe_maat_config;
}
- tfe_maat_config *__maat_config = cfg->maat_config;
+ tfe_maat_config * __maat_config = cfg->maat_config;
/* Maat配置加载来源 */
__maat_config->cfg_load_from = (tfe_maat_config::cfg_load_from_t)
@@ -201,12 +290,12 @@ static int __maatframe_load_from_file(tfe_config *cfg, TfeConfigParser &cfg_pars
return 0;
}
-static int __maatframe_init(tfe_config *cfg)
+static int __maatframe_init(tfe_config * cfg)
{
- tfe_maat_config *__maat_config = cfg->maat_config;
+ tfe_maat_config * __maat_config = cfg->maat_config;
/* 创建Logger,该Logger仅供Maat输出日志使用 */
- void *logger = MESA_create_runtime_log_handle(__maat_config->str_log_file_path.c_str(), 0);
+ void * logger = MESA_create_runtime_log_handle(__maat_config->str_log_file_path.c_str(), 0);
if (logger == nullptr)
{
throw std::runtime_error(string_format("Failed at creating runtime logger handle for MAAT: file %s",
@@ -214,25 +303,24 @@ static int __maatframe_init(tfe_config *cfg)
}
void * feather = Maat_feather(128, __maat_config->str_table_info_file.c_str(), logger);
- Maat_set_feather_opt(feather, MAAT_OPT_INSTANCE_NAME, "Tfe2a", (int)strlen("Tfe2a") + 1);
+ Maat_set_feather_opt(feather, MAAT_OPT_INSTANCE_NAME, "Tfe2a", (int) strlen("Tfe2a") + 1);
auto __maat_option_setup_helper = [feather](enum MAAT_INIT_OPT opt, const std::string value)
{
- Maat_set_feather_opt(feather, opt, value.c_str(), (int)value.length() + 1);
+ Maat_set_feather_opt(feather, opt, value.c_str(), (int) value.length() + 1);
};
switch (__maat_config->cfg_load_from)
{
case tfe_maat_config::LOAD_FROM_JSON_FILE:
- __maat_option_setup_helper(MAAT_OPT_JSON_FILE_PATH, __maat_config->str_json_file_path);
- break;
+ __maat_option_setup_helper(MAAT_OPT_JSON_FILE_PATH, __maat_config->str_json_file_path);
+ break;
case tfe_maat_config::LOAD_FROM_LOAD_IRIS:
__maat_option_setup_helper(MAAT_OPT_FULL_CFG_DIR, __maat_config->str_full_cfg_dir);
__maat_option_setup_helper(MAAT_OPT_INC_CFG_DIR, __maat_config->str_inc_cfg_dir);
break;
- default:
- assert(0);
+ default:assert(0);
}
Maat_set_feather_opt(feather, MAAT_OPT_STAT_ON, nullptr, 0);
@@ -241,8 +329,8 @@ static int __maatframe_init(tfe_config *cfg)
Maat_initiate_feather(feather);
if (feather == nullptr)
{
- MESA_destroy_runtime_log_handle(logger);
- throw std::runtime_error(string_format("Failed at initiate maat feather."));
+ MESA_destroy_runtime_log_handle(logger);
+ throw std::runtime_error(string_format("Failed at initiate maat feather."));
}
g_tfe_instance->maat_feather = feather;
@@ -251,7 +339,7 @@ static int __maatframe_init(tfe_config *cfg)
return 0;
}
-static int __forge_socket_load_from_file(tfe_config *cfg, TfeConfigParser &cfg_parser)
+static int __forge_socket_load_from_file(tfe_config * cfg, TfeConfigParser & cfg_parser)
{
cfg->forgesocket_config = new tfe_forgesocket_config;
auto * forgesocket_config = cfg->forgesocket_config;
@@ -260,13 +348,13 @@ static int __forge_socket_load_from_file(tfe_config *cfg, TfeConfigParser &cfg_p
if (forgesocket_config->en_forgesocket)
{
- forgesocket_config->str_unix_domain_file = cfg_parser.GetValue<std::string>("forgesocket","unix_domain_file");
+ forgesocket_config->str_unix_domain_file = cfg_parser.GetValue<std::string>("forgesocket", "unix_domain_file");
}
return 0;
}
-void tfe_config_load_from_file(tfe_config *cfg, const char *c_str_file)
+void tfe_config_load_from_file(tfe_config * cfg, const char * c_str_file)
{
TfeConfigParser __config_parser(c_str_file);
@@ -274,10 +362,10 @@ void tfe_config_load_from_file(tfe_config *cfg, const char *c_str_file)
{
/* 读取ProxySpec列表 */
std::string str_proxyspec_symbol = __config_parser.GetValue<std::string>("proxyspec", "symbol");
- char *__buffer_proxyspec = strdup(str_proxyspec_symbol.c_str());
+ char * __buffer_proxyspec = strdup(str_proxyspec_symbol.c_str());
/* 拆分列表,根据列表读取详细配置 */
- for (const char *__str_token = strtok(__buffer_proxyspec, ",");
+ for (const char * __str_token = strtok(__buffer_proxyspec, ",");
__str_token != nullptr; __str_token = strtok(nullptr, ","))
{
__proxyspec_parse_each_entry(cfg, __config_parser, std::string(__str_token));
@@ -294,14 +382,14 @@ void tfe_config_load_from_file(tfe_config *cfg, const char *c_str_file)
/* Logger */
g_tfe_instance->struct_logger_module = StructLogger::Factory(__config_parser);
}
- catch (cfg_invalid_format &e)
+ catch (cfg_invalid_format & e)
{
log_err_printf("Invalid format config entries in file %s, section %s, entry %s.",
e.file.c_str(), e.section.c_str(), e.item.c_str());
goto __errout;
}
- catch (cfg_lost_entry &e)
+ catch (cfg_lost_entry & e)
{
log_err_printf("Required config entries is not existed in file %s, section %s, entry %s.",
e.file.c_str(), e.section.c_str(), e.item.c_str());
@@ -314,12 +402,12 @@ __errout:
exit(EXIT_FAILURE);
}
-void tfe_config_parse_args(tfe_config *tfe, int argc, char **argv)
+void tfe_config_parse_args(tfe_config * tfe, int argc, char ** argv)
{
return;
}
-void tfe_config_free(tfe_config *opts)
+void tfe_config_free(tfe_config * opts)
{
sk_X509_pop_free(opts->chain, X509_free);
@@ -387,9 +475,9 @@ void tfe_config_free(tfe_config *opts)
* will take place with this configuration.
*/
int
-tfe_config_has_ssl_spec(tfe_config *opts)
+tfe_config_has_ssl_spec(tfe_config * opts)
{
- proxyspec *p = opts->spec;
+ proxyspec * p = opts->spec;
while (p)
{
@@ -405,9 +493,9 @@ tfe_config_has_ssl_spec(tfe_config *opts)
* Return 1 if opts_t contains a proxyspec with dns, 0 otherwise.
*/
int
-tfe_config_has_dns_spec(tfe_config *opts)
+tfe_config_has_dns_spec(tfe_config * opts)
{
- proxyspec *p = opts->spec;
+ proxyspec * p = opts->spec;
while (p)
{
@@ -424,7 +512,7 @@ tfe_config_has_dns_spec(tfe_config *opts)
* Calls exit() on failure.
*/
void
-tfe_config_proto_force(tfe_config *opts, const char *optarg, const char *argv0)
+tfe_config_proto_force(tfe_config * opts, const char * optarg, const char * argv0)
{
#if OPENSSL_VERSION_NUMBER < 0x10100000L
if (opts->sslmethod != SSLv23_method)
@@ -446,25 +534,29 @@ tfe_config_proto_force(tfe_config *opts, const char *optarg, const char *argv0)
if (!strcmp(optarg, "ssl3"))
{
opts->sslmethod = SSLv3_method;
- } else
+ }
+ else
#endif /* HAVE_SSLV3 */
#ifdef HAVE_TLSV10
if (!strcmp(optarg, "tls10") || !strcmp(optarg, "tls1"))
{
opts->sslmethod = TLSv1_method;
- } else
+ }
+ else
#endif /* HAVE_TLSV10 */
#ifdef HAVE_TLSV11
if (!strcmp(optarg, "tls11"))
{
opts->sslmethod = TLSv1_1_method;
- } else
+ }
+ else
#endif /* HAVE_TLSV11 */
#ifdef HAVE_TLSV12
if (!strcmp(optarg, "tls12"))
{
opts->sslmethod = TLSv1_2_method;
- } else
+ }
+ else
#endif /* HAVE_TLSV12 */
#else /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
/*
@@ -505,7 +597,7 @@ tfe_config_proto_force(tfe_config *opts, const char *optarg, const char *argv0)
* Calls exit() on failure.
*/
void
-tfe_config_proto_disable(tfe_config *opts, const char *optarg, const char *argv0)
+tfe_config_proto_disable(tfe_config * opts, const char * optarg, const char * argv0)
{
#ifdef HAVE_SSLV2
if (!strcmp(optarg, "ssl2")) {
@@ -516,25 +608,29 @@ tfe_config_proto_disable(tfe_config *opts, const char *optarg, const char *argv0
if (!strcmp(optarg, "ssl3"))
{
opts->no_ssl3 = 1;
- } else
+ }
+ else
#endif /* HAVE_SSLV3 */
#ifdef HAVE_TLSV10
if (!strcmp(optarg, "tls10") || !strcmp(optarg, "tls1"))
{
opts->no_tls10 = 1;
- } else
+ }
+ else
#endif /* HAVE_TLSV10 */
#ifdef HAVE_TLSV11
if (!strcmp(optarg, "tls11"))
{
opts->no_tls11 = 1;
- } else
+ }
+ else
#endif /* HAVE_TLSV11 */
#ifdef HAVE_TLSV12
if (!strcmp(optarg, "tls12"))
{
opts->no_tls12 = 1;
- } else
+ }
+ else
#endif /* HAVE_TLSV12 */
{
fprintf(stderr, "%s: Unsupported SSL/TLS protocol '%s'\n",
@@ -547,59 +643,74 @@ tfe_config_proto_disable(tfe_config *opts, const char *optarg, const char *argv0
* Dump the SSL/TLS protocol related configuration to the debug log.
*/
void
-tfe_config_proto_dbg_dump(tfe_config *opts)
+tfe_config_proto_dbg_dump(tfe_config * opts)
{
log_dbg_printf("SSL/TLS protocol: %s%s%s%s%s%s\n",
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#ifdef HAVE_SSLV2
- (opts->sslmethod == SSLv2_method) ? "ssl2" :
-#endif /* HAVE_SSLV2 */
+ (opts->sslmethod == SSLv2_method) ? "ssl2" :
+#endif
+ /* HAVE_SSLV2 */
#ifdef HAVE_SSLV3
- (opts->sslmethod == SSLv3_method) ? "ssl3" :
- #endif /* HAVE_SSLV3 */
- #ifdef HAVE_TLSV10
- (opts->sslmethod == TLSv1_method) ? "tls10" :
- #endif /* HAVE_TLSV10 */
- #ifdef HAVE_TLSV11
- (opts->sslmethod == TLSv1_1_method) ? "tls11" :
- #endif /* HAVE_TLSV11 */
- #ifdef HAVE_TLSV12
- (opts->sslmethod == TLSv1_2_method) ? "tls12" :
- #endif /* HAVE_TLSV12 */
- #else /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
- #ifdef HAVE_SSLV3
- (opts->sslversion == SSL3_VERSION) ? "ssl3" :
-#endif /* HAVE_SSLV3 */
+ (opts->sslmethod == SSLv3_method) ? "ssl3" :
+#endif
+ /* HAVE_SSLV3 */
#ifdef HAVE_TLSV10
- (opts->sslversion == TLS1_VERSION) ? "tls10" :
-#endif /* HAVE_TLSV10 */
+ (opts->sslmethod == TLSv1_method) ? "tls10" :
+#endif
+ /* HAVE_TLSV10 */
#ifdef HAVE_TLSV11
- (opts->sslversion == TLS1_1_VERSION) ? "tls11" :
-#endif /* HAVE_TLSV11 */
+ (opts->sslmethod == TLSv1_1_method) ? "tls11" :
+#endif
+ /* HAVE_TLSV11 */
#ifdef HAVE_TLSV12
- (opts->sslversion == TLS1_2_VERSION) ? "tls12" :
-#endif /* HAVE_TLSV12 */
- #endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
+ (opts->sslmethod == TLSv1_2_method) ? "tls12" :
+#endif
+ /* HAVE_TLSV12 */
+#else
+ /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
+#ifdef HAVE_SSLV3
+ (opts->sslversion == SSL3_VERSION) ? "ssl3" :
+#endif
+ /* HAVE_SSLV3 */
+#ifdef HAVE_TLSV10
+ (opts->sslversion == TLS1_VERSION) ? "tls10" :
+#endif
+ /* HAVE_TLSV10 */
+#ifdef HAVE_TLSV11
+ (opts->sslversion == TLS1_1_VERSION) ? "tls11" :
+#endif
+ /* HAVE_TLSV11 */
+#ifdef HAVE_TLSV12
+ (opts->sslversion == TLS1_2_VERSION) ? "tls12" :
+#endif
+ /* HAVE_TLSV12 */
+#endif
+ /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
"negotiate",
#ifdef HAVE_SSLV2
opts->no_ssl2 ? " -ssl2" :
-#endif /* HAVE_SSLV2 */
+#endif
+ /* HAVE_SSLV2 */
"",
#ifdef HAVE_SSLV3
opts->no_ssl3 ? " -ssl3" :
- #endif /* HAVE_SSLV3 */
+#endif /* HAVE_SSLV3 */
"",
#ifdef HAVE_TLSV10
opts->no_tls10 ? " -tls10" :
- #endif /* HAVE_TLSV10 */
+#endif
+ /* HAVE_TLSV10 */
"",
#ifdef HAVE_TLSV11
opts->no_tls11 ? " -tls11" :
- #endif /* HAVE_TLSV11 */
+#endif
+ /* HAVE_TLSV11 */
"",
#ifdef HAVE_TLSV12
opts->no_tls12 ? " -tls12" :
- #endif /* HAVE_TLSV12 */
+#endif
+ /* HAVE_TLSV12 */
"");
}
@@ -607,11 +718,11 @@ tfe_config_proto_dbg_dump(tfe_config *opts)
* Clear and free a proxy spec.
*/
void
-proxyspec_free(proxyspec *spec)
+proxyspec_free(proxyspec * spec)
{
do
{
- proxyspec *next = spec->next;
+ proxyspec * next = spec->next;
if (spec->natengine)
free(spec->natengine);
memset(spec, 0, sizeof(proxyspec));
@@ -624,11 +735,11 @@ proxyspec_free(proxyspec *spec)
* Return text representation of proxy spec for display to the user.
* Returned string must be freed by caller.
*/
-char *proxyspec_str(proxyspec *spec)
+char * proxyspec_str(proxyspec * spec)
{
- char *s;
- char *lhbuf, *lpbuf;
- char *cbuf = NULL;
+ char * s;
+ char * lhbuf, * lpbuf;
+ char * cbuf = NULL;
if (sys_sockaddr_str((struct sockaddr *) &spec->listen_addr,
spec->listen_addrlen, &lhbuf, &lpbuf) != 0)
{
@@ -636,7 +747,7 @@ char *proxyspec_str(proxyspec *spec)
}
if (spec->connect_addrlen)
{
- char *chbuf, *cpbuf;
+ char * chbuf, * cpbuf;
if (sys_sockaddr_str((struct sockaddr *) &spec->connect_addr,
spec->connect_addrlen,
&chbuf, &cpbuf) != 0)
diff --git a/src/proxy.cc b/src/proxy.cc
index 8817fb9..3fdc30c 100644
--- a/src/proxy.cc
+++ b/src/proxy.cc
@@ -174,8 +174,6 @@ void ForgeSocketListener::FdEventCallback(evutil_socket_t fd, short what)
__msghdr.msg_control = static_cast<void *>(__cmptr);
__msghdr.msg_controllen = __CONTROLLEN;
- LOG(DEBUG) << string_format("ForgeSocket Fd= %d read event arrived.", fd);
-
ssize_t rd = recvmsg(fd, &__msghdr, 0);
/* fd的常规套路 */
diff --git a/src/pxyconn.cc b/src/pxyconn.cc
index 435f73d..89f27a0 100644
--- a/src/pxyconn.cc
+++ b/src/pxyconn.cc
@@ -1089,13 +1089,7 @@ bufferevent_free_and_close_fd(struct bufferevent * bev, pxy_conn_ctx_t * ctx)
ssl = bufferevent_openssl_get_ssl(bev); /* does not inc refc */
}
-#ifdef DEBUG_PROXY
- if (OPTS_DEBUG(ctx->opts)) {
- log_dbg_printf(" %p free_and_close_fd\n",
- (void*)bev);
- }
-#endif /* DEBUG_PROXY */
-
+ CLOG(DEBUG, "conntrace") << string_format("%p free_and_close_fd", bev);
bufferevent_free(bev); /* does not free SSL unless the option
BEV_OPT_CLOSE_ON_FREE was set */
if (ssl)
@@ -1119,42 +1113,45 @@ bufferevent_free_and_close_fd(struct bufferevent * bev, pxy_conn_ctx_t * ctx)
* Returns pointer to initialized bufferevent structure, as returned
* by bufferevent_socket_new() or bufferevent_openssl_socket_new().
*/
-static struct bufferevent *
-pxy_bufferevent_setup(pxy_conn_ctx_t * ctx, evutil_socket_t fd, SSL * ssl)
+static struct bufferevent * pxy_bufferevent_setup(pxy_conn_ctx_t * ctx, evutil_socket_t fd,
+ SSL * ssl, bool is_upstream = false)
{
- struct bufferevent * bev;
-
- if (ssl)
+ struct bufferevent * bev = nullptr;
+ /* 上行,SSL的状态全部为CONNECTING */
+ if(is_upstream && ssl)
{
- bev = bufferevent_openssl_socket_new(ctx->evbase, fd, ssl,
- ((fd == -1) ? BUFFEREVENT_SSL_CONNECTING : BUFFEREVENT_SSL_ACCEPTING), BEV_OPT_DEFER_CALLBACKS);
+ bev = bufferevent_openssl_socket_new(ctx->evbase, fd, ssl, BUFFEREVENT_SSL_CONNECTING, BEV_OPT_DEFER_CALLBACKS);
+ }
+ else if(!is_upstream && ssl)
+ {
+ bev = bufferevent_openssl_socket_new(ctx->evbase, fd, ssl, ((fd == -1) ? BUFFEREVENT_SSL_CONNECTING
+ : BUFFEREVENT_SSL_ACCEPTING), BEV_OPT_DEFER_CALLBACKS);
}
else
{
bev = bufferevent_socket_new(ctx->evbase, fd, BEV_OPT_DEFER_CALLBACKS);
}
+
if (!bev)
{
log_err_printf("Error creating bufferevent socket\n");
return NULL;
}
-#if LIBEVENT_VERSION_NUMBER >= 0x02010000
if (ssl)
{
/* Prevent unclean (dirty) shutdowns to cause error
* events on the SSL socket bufferevent. */
bufferevent_openssl_set_allow_dirty_shutdown(bev, 1);
}
-#endif /* LIBEVENT_VERSION_NUMBER >= 0x02010000 */
+
bufferevent_setcb(bev, pxy_bev_readcb, pxy_bev_writecb, pxy_bev_eventcb, ctx);
bufferevent_enable(bev, EV_READ | EV_WRITE);
-#ifdef DEBUG_PROXY
- if (OPTS_DEBUG(ctx->opts)) {
- log_dbg_printf(" %p pxy_bufferevent_setup\n",
- (void*)bev);
+ if (OPTS_DEBUG(ctx->opts))
+ {
+ log_dbg_printf("%p pxy_bufferevent_setup\n",(void*)bev);
}
-#endif /* DEBUG_PROXY */
+
return bev;
}
@@ -1509,33 +1506,24 @@ static void pxy_bev_writecb(struct bufferevent * bev, void * arg)
*/
static void pxy_bev_eventcb(struct bufferevent * bev, short events, void * arg)
{
- TIMED_FUNC(timerObj);
-
pxy_conn_ctx_t * ctx = (pxy_conn_ctx_t *) arg;
pxy_conn_desc_t * this_conn = (bev == ctx->src.bev) ? &ctx->src : &ctx->dst;
pxy_conn_desc_t * other_conn = (bev == ctx->src.bev) ? &ctx->dst : &ctx->src;
int is_requestor = (bev == ctx->src.bev);
-#if 0
- log_dbg_printf("%p %p eventcb %s %s%s%s%s\n", arg, (void *) bev,
+ CLOG(DEBUG, "conntrace") << string_format("%p %p eventcb %s %s%s%s%s", arg, (void *) bev,
(bev == ctx->src.bev) ? "src" : "dst",
events & BEV_EVENT_CONNECTED ? "connected" : "",
events & BEV_EVENT_ERROR ? "error" : "",
events & BEV_EVENT_TIMEOUT ? "timeout" : "",
events & BEV_EVENT_EOF ? "eof" : "");
-#endif
if (events & BEV_EVENT_CONNECTED)
{
if (bev != ctx->dst.bev)
{
-#ifdef DEBUG_PROXY
- if (OPTS_DEBUG(ctx->opts)) {
- log_dbg_printf("src buffer event connected: "
- "ignoring event\n");
- }
-#endif /* DEBUG_PROXY */
+ LOG(DEBUG) << string_format("ctx = %p, src buffer event connected: ignoring event", ctx);
goto connected;
}
@@ -1567,6 +1555,7 @@ static void pxy_bev_eventcb(struct bufferevent * bev, short events, void * arg)
return;
}
}
+
if (ctx->clienthello_found)
{
if (OPTS_DEBUG(ctx->opts))
@@ -1585,9 +1574,9 @@ static void pxy_bev_eventcb(struct bufferevent * bev, short events, void * arg)
}
else
{
- ctx->src.bev = pxy_bufferevent_setup(ctx, ctx->fd,
- ctx->src.ssl);
+ ctx->src.bev = pxy_bufferevent_setup(ctx, ctx->fd, ctx->src.ssl);
}
+
if (!ctx->src.bev)
{
if (ctx->src.ssl)
@@ -1647,46 +1636,32 @@ connected:
}
}
- if (OPTS_DEBUG(ctx->opts))
+ if (this_conn->ssl)
{
- if (this_conn->ssl)
+ char * keystr;
+ /* for SSL, we get two connect events */
+ CLOG(DEBUG, "conntrace") << string_format("SSL connected %s [%s]:%s %s %s",
+ bev == ctx->dst.bev ? "to" : "from",
+ bev == ctx->dst.bev ? ctx->dsthost_str : ctx->srchost_str,
+ bev == ctx->dst.bev ? ctx->dstport_str : ctx->srcport_str,
+ SSL_get_version(this_conn->ssl), SSL_get_cipher(this_conn->ssl), this_conn);
+
+ keystr = ssl_ssl_masterkey_to_str(this_conn->ssl);
+ if (keystr)
{
- char * keystr;
- /* for SSL, we get two connect events */
- log_dbg_printf("SSL connected %s [%s]:%s"
- " %s %s\n",
- bev == ctx->dst.bev ?
- "to" : "from",
- bev == ctx->dst.bev ?
- ctx->dsthost_str :
- ctx->srchost_str,
- bev == ctx->dst.bev ?
- ctx->dstport_str :
- ctx->srcport_str,
- SSL_get_version(this_conn->ssl),
- SSL_get_cipher(this_conn->ssl), this_conn);
-
- keystr = ssl_ssl_masterkey_to_str(this_conn->ssl);
- if (keystr)
- {
- log_dbg_print_free(keystr);
- }
- }
- else
- {
- /* for TCP, we get only a dst connect event,
- * since src was already connected from the
- * beginning; mirror SSL debug output anyway
- * in order not to confuse anyone who might be
- * looking closely at the output */
- log_dbg_printf("TCP connected to [%s]:%s\n",
- ctx->dsthost_str,
- ctx->dstport_str);
- log_dbg_printf("TCP connected from [%s]:%s\n",
- ctx->srchost_str,
- ctx->srcport_str);
+ log_dbg_print_free(keystr);
}
}
+ else
+ {
+ /* for TCP, we get only a dst connect event,
+ * since src was already connected from the
+ * beginning; mirror SSL debug output anyway
+ * in order not to confuse anyone who might be
+ * looking closely at the output */
+ CLOG(DEBUG, "conntrace") << string_format("TCP connected to [%s]:%s", ctx->dsthost_str, ctx->dstport_str);
+ CLOG(DEBUG, "conntrace") << string_format("TCP connected from [%s]:%s", ctx->srchost_str, ctx->srcport_str);
+ }
return;
}
@@ -1897,11 +1872,7 @@ leave:
*/
static void pxy_conn_connect(pxy_conn_ctx_t * ctx)
{
- TIMED_FUNC(timerObj);
-
- CLOG(DEBUG, "conntrace") << string_format("ctx = %p, fd = %d, peer fd = %d, upstream setup begin.",
- ctx, ctx->fd, ctx->peer_fd);
-
+ CLOG(DEBUG, "conntrace") << string_format("ctx = %p, fd = %d, peer fd = %d", ctx, ctx->fd, ctx->peer_fd);
if (!ctx->addrlen)
{
log_err_printf("No target address; aborting connection\n");
@@ -1915,7 +1886,7 @@ static void pxy_conn_connect(pxy_conn_ctx_t * ctx)
if (!ctx->dst.ssl) goto __close_connection;
}
- ctx->dst.bev = pxy_bufferevent_setup(ctx, ctx->peer_fd > 0 ? ctx->peer_fd : -1, ctx->dst.ssl);
+ ctx->dst.bev = pxy_bufferevent_setup(ctx, ctx->peer_fd > 0 ? ctx->peer_fd : -1, ctx->dst.ssl, true);
if (!ctx->dst.bev) goto __close_connection_with_ssl;
if (OPTS_DEBUG(ctx->opts))
@@ -1934,19 +1905,18 @@ static void pxy_conn_connect(pxy_conn_ctx_t * ctx)
}
}
- /* 对于已经提供peer_fd的连接,上游连接已经建立,直接触发连接事件 */
- if (ctx->peer_fd > 0)
+ /* 对于明文上游连接,直接出发CONNECT事件
+ * 密文的上游连接,需要等SSL连接建立后,由libevent触发
+ */
+ if (ctx->peer_fd == 0)
{
- bufferevent_trigger_event(ctx->dst.bev, BEV_EVENT_CONNECTED, 0);
+ bufferevent_socket_connect(ctx->dst.bev, (struct sockaddr *) &ctx->addr, ctx->addrlen);
}
- else
+ if (ctx->peer_fd > 0 && ctx->spec->ssl == 0)
{
- bufferevent_socket_connect(ctx->dst.bev, (struct sockaddr *) &ctx->addr, ctx->addrlen);
+ bufferevent_trigger_event(ctx->dst.bev, BEV_EVENT_CONNECTED, 0);
}
- CLOG(DEBUG, "conntrace") << string_format("ctx = %p, fd = %d, peer fd = %d, upstream setup finished.",
- ctx, ctx->fd, ctx->peer_fd);
-
return;
__close_connection_with_ssl:
@@ -1999,8 +1969,7 @@ static void pxy_fd_readcb(evutil_socket_t fd, short what, void * arg)
pxy_conn_ctx_t * ctx = (pxy_conn_ctx_t *) arg;
CLOG(DEBUG, "conntrace") << string_format("ctx = %p, fd = %d is readable", ctx, fd);
- CLOG(DEBUG, "conntrace")
- << string_format("ctx = %p, ctx->spec->http = %d, ctx->spec->ssl = %d, ctx->passthrough = %d",
+ CLOG(DEBUG, "conntrace") << string_format("ctx = %p, ctx->spec->http = %d, ctx->spec->ssl = %d, ctx->passthrough = %d",
ctx, ctx->spec->http, ctx->spec->ssl, ctx->passthrough);
/* for SSL, peek ClientHello and parse SNI from it */
diff --git a/src/pxysslshut.cc b/src/pxysslshut.cc
index 7763a8e..a1d4f06 100644
--- a/src/pxysslshut.cc
+++ b/src/pxysslshut.cc
@@ -89,7 +89,7 @@ pxy_ssl_shutdown_ctx_free(pxy_ssl_shutdown_ctx_t *ctx)
static void
pxy_ssl_shutdown_cb(evutil_socket_t fd, UNUSED short what, void *arg)
{
- pxy_ssl_shutdown_ctx_t *ctx = arg;
+ pxy_ssl_shutdown_ctx_t *ctx = (pxy_ssl_shutdown_ctx_t *)arg;
struct timeval retry_delay = {0, 100};
short want = 0;
int rv, sslerr;