diff options
| author | Lu <[email protected]> | 2018-07-11 10:07:30 +0800 |
|---|---|---|
| committer | Lu <[email protected]> | 2018-07-11 10:07:30 +0800 |
| commit | 1bc920eeeac977acf1528ee4058d8bb2e701d308 (patch) | |
| tree | 2f4fb26f08226818a09e0f62382b630da887594d | |
| parent | ad2eadc4063e9335ff1c991b2d316ab92b80625b (diff) | |
支持对SSL的加解密、业务处理
| -rw-r--r-- | src/cfgparser.h | 23 | ||||
| -rw-r--r-- | src/http.h | 2 | ||||
| -rw-r--r-- | src/httpscan.cc | 2 | ||||
| -rw-r--r-- | src/logger.cc | 5 | ||||
| -rw-r--r-- | src/logger.h | 2 | ||||
| -rw-r--r-- | src/main.cc | 24 | ||||
| -rw-r--r-- | src/opts.cc | 283 | ||||
| -rw-r--r-- | src/proxy.cc | 2 | ||||
| -rw-r--r-- | src/pxyconn.cc | 141 | ||||
| -rw-r--r-- | src/pxysslshut.cc | 2 |
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}; +} @@ -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; |
