diff options
Diffstat (limited to 'contrib/epee')
-rw-r--r-- | contrib/epee/include/file_io_utils.h | 20 | ||||
-rw-r--r-- | contrib/epee/include/misc_os_dependent.h | 4 | ||||
-rw-r--r-- | contrib/epee/include/net/abstract_tcp_server.h | 2 | ||||
-rw-r--r-- | contrib/epee/include/net/abstract_tcp_server2.inl | 12 | ||||
-rw-r--r-- | contrib/epee/include/net/http_client.h | 186 | ||||
-rw-r--r-- | contrib/epee/include/net/http_protocol_handler.inl | 7 | ||||
-rw-r--r-- | contrib/epee/include/net/levin_protocol_handler_async.h | 36 | ||||
-rw-r--r-- | contrib/epee/include/net/net_parse_helpers.h | 4 | ||||
-rw-r--r-- | contrib/epee/include/net/network_throttle.hpp | 2 | ||||
-rw-r--r-- | contrib/epee/include/string_tools.h | 2 | ||||
-rw-r--r-- | contrib/epee/src/mlog.cpp | 1 | ||||
-rw-r--r-- | contrib/epee/src/network_throttle-detail.cpp | 8 | ||||
-rw-r--r-- | contrib/epee/src/network_throttle.cpp | 3 | ||||
-rw-r--r-- | contrib/epee/src/wipeable_string.cpp | 13 |
14 files changed, 189 insertions, 111 deletions
diff --git a/contrib/epee/include/file_io_utils.h b/contrib/epee/include/file_io_utils.h index f037b4dd5..989d16fba 100644 --- a/contrib/epee/include/file_io_utils.h +++ b/contrib/epee/include/file_io_utils.h @@ -133,6 +133,26 @@ namespace file_io_utils return false; } } + + inline + bool get_file_size(const std::string& path_to_file, uint64_t &size) + { + try + { + std::ifstream fstream; + fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit); + fstream.open(path_to_file, std::ios_base::binary | std::ios_base::in | std::ios::ate); + size = fstream.tellg(); + fstream.close(); + return true; + } + + catch(...) + { + return false; + } + } + } } diff --git a/contrib/epee/include/misc_os_dependent.h b/contrib/epee/include/misc_os_dependent.h index 81cecf714..99690b301 100644 --- a/contrib/epee/include/misc_os_dependent.h +++ b/contrib/epee/include/misc_os_dependent.h @@ -23,6 +23,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // +#ifdef _WIN32 +#include <Winsock2.h> +#endif + #ifdef WIN32 #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN diff --git a/contrib/epee/include/net/abstract_tcp_server.h b/contrib/epee/include/net/abstract_tcp_server.h index 000305cfa..cbad1717c 100644 --- a/contrib/epee/include/net/abstract_tcp_server.h +++ b/contrib/epee/include/net/abstract_tcp_server.h @@ -305,7 +305,7 @@ namespace net_utils m_connections.back().powner = this; m_connections.back().m_self_it = --m_connections.end(); m_connections.back().m_context.m_remote_address = remote_address; - m_connections.back().m_htread = threads_helper::create_thread(ConnectionHandlerProc, &m_connections.back()); + m_connections.back().m_htread = threads_helper::create_thread(ConnectionHandlerProc, &m_connections.back()); // ugh, seems very risky return true; } diff --git a/contrib/epee/include/net/abstract_tcp_server2.inl b/contrib/epee/include/net/abstract_tcp_server2.inl index 04d884af2..870f6c2b2 100644 --- a/contrib/epee/include/net/abstract_tcp_server2.inl +++ b/contrib/epee/include/net/abstract_tcp_server2.inl @@ -735,7 +735,17 @@ PRAGMA_WARNING_DISABLE_VS(4355) boost::asio::placeholders::error)); return true; - CATCH_ENTRY_L0("boosted_tcp_server<t_protocol_handler>::init_server", false); + } + catch (const std::exception &e) + { + MFATAL("Error starting server: " << e.what()); + return false; + } + catch (...) + { + MFATAL("Error starting server"); + return false; + } } //----------------------------------------------------------------------------- PUSH_WARNINGS diff --git a/contrib/epee/include/net/http_client.h b/contrib/epee/include/net/http_client.h index 1a9d5d064..1edf65928 100644 --- a/contrib/epee/include/net/http_client.h +++ b/contrib/epee/include/net/http_client.h @@ -27,6 +27,7 @@ #pragma once +#include <ctype.h> #include <boost/shared_ptr.hpp> #include <boost/regex.hpp> #include <boost/lexical_cast.hpp> @@ -236,7 +237,8 @@ namespace net_utils namespace http { - class http_simple_client: public i_target_handler + template<typename net_client_type> + class http_simple_client_template: public i_target_handler { private: enum reciev_machine_state @@ -259,7 +261,7 @@ namespace net_utils }; - blocked_mode_client m_net_client; + net_client_type m_net_client; std::string m_host_buff; std::string m_port; http_client_auth m_auth; @@ -276,7 +278,7 @@ namespace net_utils bool m_ssl; public: - explicit http_simple_client() + explicit http_simple_client_template() : i_target_handler() , m_net_client() , m_host_buff() @@ -428,6 +430,15 @@ namespace net_utils CRITICAL_REGION_LOCAL(m_lock); return invoke(uri, "POST", body, timeout, ppresponse_info, additional_params); } + //--------------------------------------------------------------------------- + bool test(const std::string &s, std::chrono::milliseconds timeout) // TEST FUNC ONLY + { + CRITICAL_REGION_LOCAL(m_lock); + m_net_client.set_test_data(s); + m_state = reciev_machine_state_header; + return handle_reciev(timeout); + } + //--------------------------------------------------------------------------- private: //--------------------------------------------------------------------------- inline bool handle_reciev(std::chrono::milliseconds timeout) @@ -742,87 +753,107 @@ namespace net_utils return true; } //--------------------------------------------------------------------------- - inline - bool parse_header(http_header_info& body_info, const std::string& m_cache_to_process) - { + inline bool parse_header(http_header_info& body_info, const std::string& m_cache_to_process) + { MTRACE("http_stream_filter::parse_cached_header(*)"); - - STATIC_REGEXP_EXPR_1(rexp_mach_field, - "\n?((Connection)|(Referer)|(Content-Length)|(Content-Type)|(Transfer-Encoding)|(Content-Encoding)|(Host)|(Cookie)|(User-Agent)|(Origin)" - // 12 3 4 5 6 7 8 9 10 11 - "|([\\w-]+?)) ?: ?((.*?)(\r?\n))[^\t ]", - //12 13 14 15 - boost::regex::icase | boost::regex::normal); - boost::smatch result; - std::string::const_iterator it_current_bound = m_cache_to_process.begin(); - std::string::const_iterator it_end_bound = m_cache_to_process.end(); - - - - //lookup all fields and fill well-known fields - while( boost::regex_search( it_current_bound, it_end_bound, result, rexp_mach_field, boost::match_default) && result[0].matched) + const char *ptr = m_cache_to_process.c_str(); + while (ptr[0] != '\r' || ptr[1] != '\n') { - const size_t field_val = 14; - //const size_t field_etc_name = 11; - - int i = 2; //start position = 2 - if(result[i++].matched)//"Connection" - body_info.m_connection = result[field_val]; - else if(result[i++].matched)//"Referrer" - body_info.m_referer = result[field_val]; - else if(result[i++].matched)//"Content-Length" - body_info.m_content_length = result[field_val]; - else if(result[i++].matched)//"Content-Type" - body_info.m_content_type = result[field_val]; - else if(result[i++].matched)//"Transfer-Encoding" - body_info.m_transfer_encoding = result[field_val]; - else if(result[i++].matched)//"Content-Encoding" - body_info.m_content_encoding = result[field_val]; - else if(result[i++].matched)//"Host" - { body_info.m_host = result[field_val]; - string_tools::trim(body_info.m_host); + // optional \n + if (*ptr == '\n') + ++ptr; + // an identifier composed of letters or - + const char *key_pos = ptr; + while (isalnum(*ptr) || *ptr == '_' || *ptr == '-') + ++ptr; + const char *key_end = ptr; + // optional space (not in RFC, but in previous code) + if (*ptr == ' ') + ++ptr; + CHECK_AND_ASSERT_MES(*ptr == ':', true, "http_stream_filter::parse_cached_header() invalid header in: " << m_cache_to_process); + ++ptr; + // optional whitespace, but not newlines - line folding is obsolete, let's ignore it + while (isblank(*ptr)) + ++ptr; + const char *value_pos = ptr; + while (*ptr != '\r' && *ptr != '\n') + ++ptr; + const char *value_end = ptr; + // optional trailing whitespace + while (value_end > value_pos && isblank(*(value_end-1))) + --value_end; + if (*ptr == '\r') + ++ptr; + CHECK_AND_ASSERT_MES(*ptr == '\n', true, "http_stream_filter::parse_cached_header() invalid header in: " << m_cache_to_process); + ++ptr; + + const std::string key = std::string(key_pos, key_end - key_pos); + const std::string value = std::string(value_pos, value_end - value_pos); + if (!key.empty()) + { + if (!string_tools::compare_no_case(key, "Connection")) + body_info.m_connection = value; + else if(!string_tools::compare_no_case(key, "Referrer")) + body_info.m_referer = value; + else if(!string_tools::compare_no_case(key, "Content-Length")) + body_info.m_content_length = value; + else if(!string_tools::compare_no_case(key, "Content-Type")) + body_info.m_content_type = value; + else if(!string_tools::compare_no_case(key, "Transfer-Encoding")) + body_info.m_transfer_encoding = value; + else if(!string_tools::compare_no_case(key, "Content-Encoding")) + body_info.m_content_encoding = value; + else if(!string_tools::compare_no_case(key, "Host")) + body_info.m_host = value; + else if(!string_tools::compare_no_case(key, "Cookie")) + body_info.m_cookie = value; + else if(!string_tools::compare_no_case(key, "User-Agent")) + body_info.m_user_agent = value; + else if(!string_tools::compare_no_case(key, "Origin")) + body_info.m_origin = value; + else + body_info.m_etc_fields.emplace_back(key, value); } - else if(result[i++].matched)//"Cookie" - body_info.m_cookie = result[field_val]; - else if(result[i++].matched)//"User-Agent" - body_info.m_user_agent = result[field_val]; - else if(result[i++].matched)//"Origin" - body_info.m_origin = result[field_val]; - else if(result[i++].matched)//e.t.c (HAVE TO BE MATCHED!) - body_info.m_etc_fields.emplace_back(result[12], result[field_val]); - else - {CHECK_AND_ASSERT_MES(false, false, "http_stream_filter::parse_cached_header() not matched last entry in:"<<m_cache_to_process);} - - it_current_bound = result[(int)result.size()-1]. first; } - return true; - + return true; } - inline - bool analize_first_response_line() + //--------------------------------------------------------------------------- + inline bool analize_first_response_line() { - - //First line response, look like this: "HTTP/1.1 200 OK" - STATIC_REGEXP_EXPR_1(rexp_match_first_response_line, "^HTTP/(\\d+).(\\d+) ((\\d)\\d{2})( [^\n]*)?\r?\n", boost::regex::icase | boost::regex::normal); - // 1 2 34 5 - //size_t match_len = 0; - boost::smatch result; - if(boost::regex_search( m_header_cache, result, rexp_match_first_response_line, boost::match_default) && result[0].matched) - { - CHECK_AND_ASSERT_MES(result[1].matched&&result[2].matched, false, "http_stream_filter::handle_invoke_reply_line() assert failed..."); - m_response_info.m_http_ver_hi = boost::lexical_cast<int>(result[1]); - m_response_info.m_http_ver_lo = boost::lexical_cast<int>(result[2]); - m_response_info.m_response_code = boost::lexical_cast<int>(result[3]); - - m_header_cache.erase(to_nonsonst_iterator(m_header_cache, result[0].first), to_nonsonst_iterator(m_header_cache, result[0].second)); - return true; - }else - { - LOG_ERROR("http_stream_filter::handle_invoke_reply_line(): Failed to match first response line:" << m_header_cache); - return false; - } - + //First line response, look like this: "HTTP/1.1 200 OK" + const char *ptr = m_header_cache.c_str(); + CHECK_AND_ASSERT_MES(!memcmp(ptr, "HTTP/", 5), false, "Invalid first response line: " + m_header_cache); + ptr += 5; + CHECK_AND_ASSERT_MES(isdigit(*ptr), false, "Invalid first response line: " + m_header_cache); + unsigned long ul; + char *end; + ul = strtoul(ptr, &end, 10); + CHECK_AND_ASSERT_MES(ul <= INT_MAX && *end =='.', false, "Invalid first response line: " + m_header_cache); + m_response_info.m_http_ver_hi = ul; + ptr = end + 1; + CHECK_AND_ASSERT_MES(isdigit(*ptr), false, "Invalid first response line: " + m_header_cache + ", ptr: " << ptr); + ul = strtoul(ptr, &end, 10); + CHECK_AND_ASSERT_MES(ul <= INT_MAX && isblank(*end), false, "Invalid first response line: " + m_header_cache + ", ptr: " << ptr); + m_response_info.m_http_ver_lo = ul; + ptr = end + 1; + while (isblank(*ptr)) + ++ptr; + CHECK_AND_ASSERT_MES(isdigit(*ptr), false, "Invalid first response line: " + m_header_cache); + ul = strtoul(ptr, &end, 10); + CHECK_AND_ASSERT_MES(ul >= 100 && ul <= 999 && isspace(*end), false, "Invalid first response line: " + m_header_cache); + m_response_info.m_response_code = ul; + ptr = end; + // ignore the optional text, till the end + while (*ptr != '\r' && *ptr != '\n') + ++ptr; + if (*ptr == '\r') + ++ptr; + CHECK_AND_ASSERT_MES(*ptr == '\n', false, "Invalid first response line: " << m_header_cache); + ++ptr; + + m_header_cache.erase(0, ptr - m_header_cache.c_str()); + return true; } inline bool set_reply_content_encoder() @@ -957,6 +988,7 @@ namespace net_utils return true; } }; + typedef http_simple_client_template<blocked_mode_client> http_simple_client; } } } diff --git a/contrib/epee/include/net/http_protocol_handler.inl b/contrib/epee/include/net/http_protocol_handler.inl index c555707ac..c18f7f706 100644 --- a/contrib/epee/include/net/http_protocol_handler.inl +++ b/contrib/epee/include/net/http_protocol_handler.inl @@ -345,7 +345,12 @@ namespace net_utils { analize_http_method(result, m_query_info.m_http_method, m_query_info.m_http_ver_hi, m_query_info.m_http_ver_hi); m_query_info.m_URI = result[10]; - parse_uri(m_query_info.m_URI, m_query_info.m_uri_content); + if (!parse_uri(m_query_info.m_URI, m_query_info.m_uri_content)) + { + m_state = http_state_error; + MERROR("Failed to parse URI: m_query_info.m_URI"); + return false; + } m_query_info.m_http_method_str = result[2]; m_query_info.m_full_request_str = result[0]; diff --git a/contrib/epee/include/net/levin_protocol_handler_async.h b/contrib/epee/include/net/levin_protocol_handler_async.h index 7b526e4e7..5b825cef9 100644 --- a/contrib/epee/include/net/levin_protocol_handler_async.h +++ b/contrib/epee/include/net/levin_protocol_handler_async.h @@ -99,6 +99,7 @@ public: async_protocol_handler_config():m_pcommands_handler(NULL), m_pcommands_handler_destroy(NULL), m_max_packet_size(LEVIN_DEFAULT_MAX_PACKET_SIZE) {} + ~async_protocol_handler_config() { set_handler(NULL, NULL); } void del_out_connections(size_t count); }; @@ -378,12 +379,16 @@ public: if(m_cache_in_buffer.size() < m_current_head.m_cb) { is_continue = false; - if(cb >= MIN_BYTES_WANTED && !m_invoke_response_handlers.empty()) + if(cb >= MIN_BYTES_WANTED) { - //async call scenario - boost::shared_ptr<invoke_response_handler_base> response_handler = m_invoke_response_handlers.front(); - response_handler->reset_timer(); - MDEBUG(m_connection_context << "LEVIN_PACKET partial msg received. len=" << cb); + CRITICAL_REGION_LOCAL(m_invoke_response_handlers_lock); + if (!m_invoke_response_handlers.empty()) + { + //async call scenario + boost::shared_ptr<invoke_response_handler_base> response_handler = m_invoke_response_handlers.front(); + response_handler->reset_timer(); + MDEBUG(m_connection_context << "LEVIN_PACKET partial msg received. len=" << cb); + } } break; } @@ -745,15 +750,18 @@ void async_protocol_handler_config<t_connection_context>::del_out_connections(si shuffle(out_connections.begin(), out_connections.end(), std::default_random_engine(seed)); while (count > 0 && out_connections.size() > 0) { - boost::uuids::uuid connection_id = *out_connections.begin(); - async_protocol_handler<t_connection_context> *connection = find_connection(connection_id); - // we temporarily ref the connection so it doesn't drop from the m_connects table - // when we close it - connection->start_outer_call(); - close(connection_id); - del_connection(m_connects.at(connection_id)); - out_connections.erase(out_connections.begin()); - connection->finish_outer_call(); + try + { + auto i = out_connections.begin(); + async_protocol_handler<t_connection_context> *conn = m_connects.at(*i); + del_connection(conn); + close(*i); + out_connections.erase(i); + } + catch (const std::out_of_range &e) + { + MWARNING("Connection not found in m_connects, continuing"); + } --count; } diff --git a/contrib/epee/include/net/net_parse_helpers.h b/contrib/epee/include/net/net_parse_helpers.h index 08d2a2000..708cce0ff 100644 --- a/contrib/epee/include/net/net_parse_helpers.h +++ b/contrib/epee/include/net/net_parse_helpers.h @@ -103,7 +103,7 @@ namespace net_utils STATIC_REGEXP_EXPR_1(rexp_match_uri, "^([^?#]*)(\\?([^#]*))?(#(.*))?", boost::regex::icase | boost::regex::normal); boost::smatch result; - if(!boost::regex_search(uri, result, rexp_match_uri, boost::match_default) && result[0].matched) + if(!(boost::regex_search(uri, result, rexp_match_uri, boost::match_default) && result[0].matched)) { LOG_PRINT_L1("[PARSE URI] regex not matched for uri: " << uri); content.m_path = uri; @@ -139,7 +139,7 @@ namespace net_utils // 12 34 5 6 7 content.port = 0; boost::smatch result; - if(!boost::regex_search(url_str, result, rexp_match_uri, boost::match_default) && result[0].matched) + if(!(boost::regex_search(url_str, result, rexp_match_uri, boost::match_default) && result[0].matched)) { LOG_PRINT_L1("[PARSE URI] regex not matched for uri: " << rexp_match_uri); //content.m_path = uri; diff --git a/contrib/epee/include/net/network_throttle.hpp b/contrib/epee/include/net/network_throttle.hpp index 464b34726..fffd22a6a 100644 --- a/contrib/epee/include/net/network_throttle.hpp +++ b/contrib/epee/include/net/network_throttle.hpp @@ -121,8 +121,6 @@ class network_throttle_manager { friend class connection_basic; // FRIEND - to directly access global throttle-s. !! REMEMBER TO USE LOCKS! friend class connection_basic_pimpl; // ditto - static int xxx; - public: static i_network_throttle & get_global_throttle_in(); ///< singleton ; for friend class ; caller MUST use proper locks! like m_lock_get_global_throttle_in static i_network_throttle & get_global_throttle_inreq(); ///< ditto ; use lock ... use m_lock_get_global_throttle_inreq obviously diff --git a/contrib/epee/include/string_tools.h b/contrib/epee/include/string_tools.h index 307323aa1..5a1ef0743 100644 --- a/contrib/epee/include/string_tools.h +++ b/contrib/epee/include/string_tools.h @@ -161,7 +161,7 @@ DISABLE_GCC_WARNING(maybe-uninitialized) val = boost::lexical_cast<XType>(str_id); return true; } - catch(std::exception& /*e*/) + catch(const std::exception& /*e*/) { //const char* pmsg = e.what(); return false; diff --git a/contrib/epee/src/mlog.cpp b/contrib/epee/src/mlog.cpp index a30efbc6a..5b9472006 100644 --- a/contrib/epee/src/mlog.cpp +++ b/contrib/epee/src/mlog.cpp @@ -59,6 +59,7 @@ static std::string generate_log_filename(const char *base) strcpy(tmp, "unknown"); else strftime(tmp, sizeof(tmp), "%Y-%m-%d-%H-%M-%S", &tm); + tmp[sizeof(tmp) - 1] = 0; filename += "-"; filename += tmp; return filename; diff --git a/contrib/epee/src/network_throttle-detail.cpp b/contrib/epee/src/network_throttle-detail.cpp index 317dde8e0..ed6bc07ed 100644 --- a/contrib/epee/src/network_throttle-detail.cpp +++ b/contrib/epee/src/network_throttle-detail.cpp @@ -231,8 +231,10 @@ network_time_seconds network_throttle::get_sleep_time_after_tick(size_t packet_s } void network_throttle::logger_handle_net(const std::string &filename, double time, size_t size) { - boost::mutex mutex; - mutex.lock(); { + static boost::mutex mutex; + + boost::lock_guard<boost::mutex> lock(mutex); + { std::fstream file; file.open(filename.c_str(), std::ios::app | std::ios::out ); file.precision(6); @@ -240,7 +242,7 @@ void network_throttle::logger_handle_net(const std::string &filename, double tim _warn("Can't open file " << filename); file << static_cast<int>(time) << " " << static_cast<double>(size/1024) << "\n"; file.close(); - } mutex.unlock(); + } } // fine tune this to decide about sending speed: diff --git a/contrib/epee/src/network_throttle.cpp b/contrib/epee/src/network_throttle.cpp index afacc3e96..dd1640a2e 100644 --- a/contrib/epee/src/network_throttle.cpp +++ b/contrib/epee/src/network_throttle.cpp @@ -71,9 +71,6 @@ boost::mutex network_throttle_manager::m_lock_get_global_throttle_in; boost::mutex network_throttle_manager::m_lock_get_global_throttle_inreq; boost::mutex network_throttle_manager::m_lock_get_global_throttle_out; -int network_throttle_manager::xxx; - - // ================================================================================================ // methods: i_network_throttle & network_throttle_manager::get_global_throttle_in() { diff --git a/contrib/epee/src/wipeable_string.cpp b/contrib/epee/src/wipeable_string.cpp index 75191df71..894c47bbd 100644 --- a/contrib/epee/src/wipeable_string.cpp +++ b/contrib/epee/src/wipeable_string.cpp @@ -85,11 +85,15 @@ void wipeable_string::wipe() void wipeable_string::grow(size_t sz, size_t reserved) { CHECK_AND_ASSERT_THROW_MES(wipefunc, "wipefunc is not set"); - if (reserved == 0) + if (reserved < sz) reserved = sz; - CHECK_AND_ASSERT_THROW_MES(reserved >= sz, "reserved < sz"); if (reserved <= buffer.capacity()) + { + if (sz < buffer.size()) + wipefunc(buffer.data() + sz, buffer.size() - sz); + buffer.resize(sz); return; + } size_t old_sz = buffer.size(); std::unique_ptr<char[]> tmp{new char[old_sz]}; memcpy(tmp.get(), buffer.data(), old_sz * sizeof(char)); @@ -103,7 +107,7 @@ void wipeable_string::grow(size_t sz, size_t reserved) void wipeable_string::push_back(char c) { grow(size() + 1); - buffer.push_back(c); + buffer.back() = c; } void wipeable_string::pop_back() @@ -113,9 +117,6 @@ void wipeable_string::pop_back() void wipeable_string::resize(size_t sz) { - CHECK_AND_ASSERT_THROW_MES(wipefunc, "wipefunc is not set"); - if (sz < buffer.size()) - wipefunc(buffer.data() + sz, buffer.size() - sz); grow(sz); } |