diff --git a/libtorrent/include/libtorrent/bt_peer_connection.hpp b/libtorrent/include/libtorrent/bt_peer_connection.hpp index c9a1bc7e5..da3b0fa27 100644 --- a/libtorrent/include/libtorrent/bt_peer_connection.hpp +++ b/libtorrent/include/libtorrent/bt_peer_connection.hpp @@ -333,9 +333,6 @@ private: // state of on_receive state m_state; - // the timeout in seconds - int m_timeout; - static const message_handler m_message_handler[num_supported_messages]; // this is a queue of ranges that describes diff --git a/libtorrent/include/libtorrent/storage.hpp b/libtorrent/include/libtorrent/storage.hpp index 03841ecb5..6bd1d4755 100644 --- a/libtorrent/include/libtorrent/storage.hpp +++ b/libtorrent/include/libtorrent/storage.hpp @@ -80,7 +80,7 @@ namespace libtorrent storage_mode_compact }; -#if defined(_WIN32) && defined(UNICODE) +#if TORRENT_USE_WPATH TORRENT_EXPORT std::wstring safe_convert(std::string const& s); diff --git a/libtorrent/src/disk_io_thread.cpp b/libtorrent/src/disk_io_thread.cpp index cab82f305..3ff193c3c 100644 --- a/libtorrent/src/disk_io_thread.cpp +++ b/libtorrent/src/disk_io_thread.cpp @@ -417,7 +417,10 @@ namespace libtorrent if (end_block == start_block) return -2; - int buffer_size = piece_size - (end_block - 1) * m_block_size + (end_block - start_block - 1) * m_block_size; + // the buffer_size is the size of the buffer we need to read + // all these blocks. + const int buffer_size = (std::min)((end_block - start_block) * m_block_size + , piece_size - start_block * m_block_size); TORRENT_ASSERT(buffer_size <= piece_size); TORRENT_ASSERT(buffer_size + start_block * m_block_size <= piece_size); boost::scoped_array buf; @@ -440,6 +443,7 @@ namespace libtorrent if (p.blocks[i] == 0) break; TORRENT_ASSERT(offset <= buffer_size); TORRENT_ASSERT(piece_offset <= piece_size); + TORRENT_ASSERT(offset + block_size <= buffer_size); if (buf) { std::memcpy(p.blocks[i], buf.get() + offset, block_size); diff --git a/libtorrent/src/escape_string.cpp b/libtorrent/src/escape_string.cpp index 616570014..386354fe3 100755 --- a/libtorrent/src/escape_string.cpp +++ b/libtorrent/src/escape_string.cpp @@ -355,7 +355,7 @@ namespace libtorrent TORRENT_EXPORT std::string to_hex(std::string const& s) { std::string ret; - char* digits = "0123456789abcdef"; + char const* digits = "0123456789abcdef"; for (std::string::const_iterator i = s.begin(); i != s.end(); ++i) { ret += digits[((unsigned char)*i) >> 4]; diff --git a/libtorrent/src/file.cpp b/libtorrent/src/file.cpp index 7aa594987..390baf341 100755 --- a/libtorrent/src/file.cpp +++ b/libtorrent/src/file.cpp @@ -41,10 +41,6 @@ POSSIBILITY OF SUCH DAMAGE. #include #include -#ifdef UNICODE -#include "libtorrent/storage.hpp" -#endif - #else // posix part #define _FILE_OFFSET_BITS 64 @@ -75,7 +71,8 @@ BOOST_STATIC_ASSERT(sizeof(lseek(0, 0, 0)) >= 8); #define O_RANDOM 0 #endif -#ifdef UNICODE +#ifdef TORRENT_USE_WPATH +// for safe_convert #include "libtorrent/storage.hpp" #endif @@ -170,7 +167,7 @@ namespace libtorrent close(); #ifdef TORRENT_WINDOWS -#ifdef UNICODE +#ifdef TORRENT_USE_WPATH std::wstring file_path(safe_convert(path.external_file_string())); #else std::string file_path = utf8_native(path.external_file_string()); diff --git a/libtorrent/src/natpmp.cpp b/libtorrent/src/natpmp.cpp index b183d1d22..67c4ae3c5 100644 --- a/libtorrent/src/natpmp.cpp +++ b/libtorrent/src/natpmp.cpp @@ -288,9 +288,16 @@ void natpmp::send_map_request(int i) error_code ec; m_socket.send_to(asio::buffer(buf, 12), m_nat_endpoint, 0, ec); // linear back-off instead of exponential - ++m_retry_count; - m_send_timer.expires_from_now(milliseconds(250 * m_retry_count), ec); - m_send_timer.async_wait(bind(&natpmp::resend_request, self(), i, _1)); + if (m_abort) + { + try_next_mapping(i); + } + else + { + ++m_retry_count; + m_send_timer.expires_from_now(milliseconds(250 * m_retry_count), ec); + m_send_timer.async_wait(bind(&natpmp::resend_request, self(), i, _1)); + } } void natpmp::resend_request(int i, error_code const& e) @@ -330,6 +337,14 @@ void natpmp::on_reply(error_code const& e m_socket.async_receive_from(asio::buffer(&m_response_buffer, 16) , m_remote, bind(&natpmp::on_reply, self(), _1, _2)); + // simulate packet loss +/* + if ((rand() % 2) == 0) + { + log(" simulating drop"); + return; + } +*/ if (m_remote != m_nat_endpoint) { #if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING) @@ -345,10 +360,6 @@ void natpmp::on_reply(error_code const& e error_code ec; m_send_timer.cancel(ec); - TORRENT_ASSERT(m_currently_mapping >= 0); - int i = m_currently_mapping; - mapping_t& m = m_mappings[i]; - char* in = m_response_buffer; int version = read_uint8(in); int cmd = read_uint8(in); @@ -360,6 +371,8 @@ void natpmp::on_reply(error_code const& e (void)time; // to remove warning + int protocol = (cmd - 128 == 1)?udp:tcp; + #if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING) m_log << time_now_string() << " <== port map [" @@ -375,30 +388,36 @@ void natpmp::on_reply(error_code const& e } #endif -#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING) - if (private_port != m.local_port) + mapping_t* m = 0; + int index = -1; + for (std::vector::iterator i = m_mappings.begin() + , end(m_mappings.end()); i != end; ++i) { - m_log << "*** unexpected local port: " << private_port << std::endl; + if (private_port != i->local_port) continue; + if (protocol != i->protocol) continue; + m = &*i; + index = i - m_mappings.begin(); + break; } -#endif -#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING) - if (cmd != 128 + m.protocol) + if (m == 0) { - m_log << "*** unexpected protocol: " << (cmd - 128) << std::endl; - } +#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING) + m_log << "*** not found in map table" << std::endl; #endif + return; + } if (public_port == 0 || lifetime == 0) { // this means the mapping was // successfully closed - m.protocol = none; + m->protocol = none; } else { - m.expires = time_now() + seconds(int(lifetime * 0.7f)); - m.external_port = public_port; + m->expires = time_now() + seconds(int(lifetime * 0.7f)); + m->external_port = public_port; } if (result != 0) @@ -416,19 +435,19 @@ void natpmp::on_reply(error_code const& e case 4: errmsg << "Out of resources"; break; case 5: errmsg << "Unsupported opcode"; break; } - m.expires = time_now() + hours(2); - m_callback(i, 0, errmsg.str()); + m->expires = time_now() + hours(2); + m_callback(index, 0, errmsg.str()); } - else if (m.action == mapping_t::action_add) + else if (m->action == mapping_t::action_add) { - m_callback(i, m.external_port, ""); + m_callback(index, m->external_port, ""); } m_currently_mapping = -1; - m.action = mapping_t::action_none; + m->action = mapping_t::action_none; m_send_timer.cancel(ec); update_expiration_timer(); - try_next_mapping(i); + try_next_mapping(index); } void natpmp::update_expiration_timer() diff --git a/libtorrent/src/storage.cpp b/libtorrent/src/storage.cpp index 933395526..fc491c98f 100755 --- a/libtorrent/src/storage.cpp +++ b/libtorrent/src/storage.cpp @@ -137,106 +137,6 @@ namespace libtorrent } #endif -#if defined(_WIN32) && defined(UNICODE) && BOOST_VERSION < 103400 -namespace -{ - using libtorrent::safe_convert; - using namespace boost::filesystem; - - // based on code from Boost.Fileystem - bool create_directories_win(const fs::path& ph) - { - if (ph.empty() || exists(ph)) - { - if ( !ph.empty() && !is_directory(ph) ) - boost::throw_exception( filesystem_error( - "boost::filesystem::create_directories", - ph, "path exists and is not a directory", - not_directory_error ) ); - return false; - } - - // First create branch, by calling ourself recursively - create_directories_win(ph.branch_path()); - // Now that parent's path exists, create the directory - std::wstring wph(safe_convert(ph.external_directory_string())); - CreateDirectory(wph.c_str(), 0); - return true; - } - - bool exists_win( const fs::path & ph ) - { - std::wstring wpath(safe_convert(ph.string())); - if(::GetFileAttributes( wpath.c_str() ) == 0xFFFFFFFF) - { - UINT err = ::GetLastError(); - if((err == ERROR_FILE_NOT_FOUND) - || (err == ERROR_INVALID_PARAMETER) - || (err == ERROR_NOT_READY) - || (err == ERROR_PATH_NOT_FOUND) - || (err == ERROR_INVALID_NAME) - || (err == ERROR_BAD_NETPATH )) - return false; // GetFileAttributes failed because the path does not exist - // for any other error we assume the file does exist and fall through, - // this may not be the best policy though... (JM 20040330) - return true; - } - return true; - } - - boost::intmax_t file_size_win( const fs::path & ph ) - { - std::wstring wpath(safe_convert(ph.string())); - // by now, intmax_t is 64-bits on all Windows compilers - WIN32_FILE_ATTRIBUTE_DATA fad; - if ( !::GetFileAttributesExW( wpath.c_str(), - ::GetFileExInfoStandard, &fad ) ) - boost::throw_exception( filesystem_error( - "boost::filesystem::file_size", - ph, detail::system_error_code() ) ); - if ( (fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) !=0 ) - boost::throw_exception( filesystem_error( - "boost::filesystem::file_size", - ph, "invalid: is a directory", - is_directory_error ) ); - return (static_cast(fad.nFileSizeHigh) - << (sizeof(fad.nFileSizeLow)*8)) - + fad.nFileSizeLow; - } - - std::time_t last_write_time_win( const fs::path & ph ) - { - struct _stat path_stat; - std::wstring wph(safe_convert(ph.external_file_string())); - if ( ::_wstat( wph.c_str(), &path_stat ) != 0 ) - boost::throw_exception( filesystem_error( - "boost::filesystem::last_write_time", - ph, detail::system_error_code() ) ); - return path_stat.st_mtime; - } - - void rename_win( const fs::path & old_path, - const fs::path & new_path ) - { - std::wstring wold_path(safe_convert(old_path.string())); - std::wstring wnew_path(safe_convert(new_path.string())); - if ( !::MoveFile( wold_path.c_str(), wnew_path.c_str() ) ) - boost::throw_exception( filesystem_error( - "boost::filesystem::rename", - old_path, new_path, detail::system_error_code() ) ); - } - -} // anonymous namespace - -#endif - -#if BOOST_VERSION < 103200 -bool operator<(fs::path const& lhs, fs::path const& rhs) -{ - return lhs.string() < rhs.string(); -} -#endif - namespace fs = boost::filesystem; using boost::bind; using namespace ::boost::multi_index; @@ -507,10 +407,7 @@ namespace libtorrent { last_path = dir; -#if defined(_WIN32) && defined(UNICODE) && BOOST_VERSION < 103400 - if (!exists_win(last_path)) - create_directories_win(last_path); -#elif TORRENT_USE_WPATH +#if TORRENT_USE_WPATH fs::wpath wp = safe_convert(last_path.string()); if (!exists(wp)) create_directories(wp); @@ -846,13 +743,7 @@ namespace libtorrent save_path = complete(save_path); -#if defined(_WIN32) && defined(UNICODE) && BOOST_VERSION < 103400 - std::wstring wsave_path(safe_convert(save_path.external_file_string())); - if (!exists_win(save_path)) - CreateDirectory(wsave_path.c_str(), 0); - else if ((GetFileAttributes(wsave_path.c_str()) & FILE_ATTRIBUTE_DIRECTORY) == 0) - return false; -#elif TORRENT_USE_WPATH +#if TORRENT_USE_WPATH fs::wpath wp = safe_convert(save_path.string()); if (!exists(wp)) create_directory(wp); @@ -879,11 +770,7 @@ namespace libtorrent try { #endif -#if defined(_WIN32) && defined(UNICODE) && BOOST_VERSION < 103400 - rename_win(old_path, new_path); -#else rename(old_path, new_path); -#endif m_save_path = save_path; return true; #ifndef BOOST_NO_EXCEPTIONS @@ -1764,9 +1651,7 @@ namespace libtorrent try { #endif -#if defined(_WIN32) && defined(UNICODE) && BOOST_VERSION < 103400 - file_exists = exists_win(f); -#elif TORRENT_USE_WPATH +#if TORRENT_USE_WPATH fs::wpath wf = safe_convert(f.string()); file_exists = exists(wf); #else diff --git a/libtorrent/src/upnp.cpp b/libtorrent/src/upnp.cpp index 4db690cfa..cfae4cdfd 100644 --- a/libtorrent/src/upnp.cpp +++ b/libtorrent/src/upnp.cpp @@ -242,6 +242,8 @@ void upnp::resend_request(error_code const& e) mutex_t::scoped_lock l(m_mutex); + if (m_closing) return; + if (m_retry_count < 12 && (m_devices.empty() || m_retry_count < 4)) { @@ -353,31 +355,35 @@ void upnp::on_reply(udp::endpoint const& from, char* buffer return; } - std::vector routes = enum_routes(m_io_service, ec); - if (m_ignore_non_routers && std::find_if(routes.begin(), routes.end() - , bind(&ip_route::gateway, _1) == from.address()) == routes.end()) + if (m_ignore_non_routers) { - // this upnp device is filtered because it's not in the - // list of configured routers + std::vector routes = enum_routes(m_io_service, ec); + + if (std::find_if(routes.begin(), routes.end() + , bind(&ip_route::gateway, _1) == from.address()) == routes.end()) + { + // this upnp device is filtered because it's not in the + // list of configured routers #ifdef TORRENT_UPNP_LOGGING - if (ec) - { - m_log << time_now_string() << " <== (" << from << ") error: " - << ec.message() << std::endl; - } - else - { - m_log << time_now_string() << " <== (" << from << ") UPnP device " - "ignored because it's not a router on our network "; - for (std::vector::const_iterator i = routes.begin() - , end(routes.end()); i != end; ++i) + if (ec) { - m_log << "(" << i->gateway << ", " << i->netmask << ") "; + m_log << time_now_string() << " <== (" << from << ") error: " + << ec.message() << std::endl; + } + else + { + m_log << time_now_string() << " <== (" << from << ") UPnP device " + "ignored because it's not a router on our network "; + for (std::vector::const_iterator i = routes.begin() + , end(routes.end()); i != end; ++i) + { + m_log << "(" << i->gateway << ", " << i->netmask << ") "; + } + m_log << std::endl; } - m_log << std::endl; - } #endif - return; + return; + } } http_parser p;