diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000000000000000000000000000000000..f02b9651827975bd294d947c00ea545ee3029db6 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,18 @@ +language: cpp +compiler: + - gcc + - clang + +before_install: + - sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test + - sudo apt-get update -qq + - sudo apt-get build-dep libtorrent-dev + + - if [ "$CXX" = "g++" ]; then sudo apt-get install -qq g++-4.7; fi + - if [ "$CXX" = "g++" ]; then export CXX="g++-4.7" CC="gcc-4.7"; fi + +# prevent `macro `AM_PATH_CPPUNIT' not found in library` in `autogen.sh` + - sudo apt-get install libcppunit-dev + +# Figure out how to fix the issue running 'make check'. +script: ./autogen.sh && ./configure && make -j12 check && sudo make install diff --git a/configure.ac b/configure.ac index 0e7420fb5b54a5108a4dfbf1dbf724e7cc980a4d..2b3eb7ab61ea79aaed2605d2b129bdfe968c2675 100644 --- a/configure.ac +++ b/configure.ac @@ -1,12 +1,12 @@ -AC_INIT(libtorrent, 0.13.4, sundell.software@gmail.com) +AC_INIT(libtorrent, 0.13.6, sundell.software@gmail.com) LT_INIT([disable-static]) dnl Find a better way to do this -AC_DEFINE(PEER_NAME, "-lt0D40-", Identifier that is part of the default peer id) -AC_DEFINE(PEER_VERSION, "lt\x0D\x40", 4 byte client and version identifier for DHT) +AC_DEFINE(PEER_NAME, "-lt0D60-", Identifier that is part of the default peer id) +AC_DEFINE(PEER_VERSION, "lt\x0D\x60", 4 byte client and version identifier for DHT) -LIBTORRENT_CURRENT=18 +LIBTORRENT_CURRENT=19 LIBTORRENT_REVISION=0 LIBTORRENT_AGE=0 diff --git a/src/data/chunk.cc b/src/data/chunk.cc index 3770bf0db38ad9d71df1cdeeb2ce06e7cece828d..b69a0393adeb4f0637e42a4ac09e77727c837a12 100644 --- a/src/data/chunk.cc +++ b/src/data/chunk.cc @@ -39,13 +39,23 @@ #include #include #include -#include +#include +#include #include "torrent/exceptions.h" #include "chunk.h" #include "chunk_iterator.h" +jmp_buf jmp_disk_full; + +void +bus_handler(int sig, siginfo_t *si, void *vuctx) +{ + if (si->si_code == BUS_ADRERR) + longjmp(jmp_disk_full, 1); +} + namespace torrent { bool @@ -226,6 +236,13 @@ Chunk::to_buffer(void* buffer, uint32_t position, uint32_t length) { // matching. bool Chunk::from_buffer(const void* buffer, uint32_t position, uint32_t length) { + struct sigaction sa, oldact; + std::memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = bus_handler; + sa.sa_flags = SA_SIGINFO; + sigfillset(&sa.sa_mask); + sigaction(SIGBUS, &sa, &oldact); + if (position + length > m_chunkSize) throw internal_error("Chunk::from_buffer(...) position + length > m_chunkSize."); @@ -235,12 +252,18 @@ Chunk::from_buffer(const void* buffer, uint32_t position, uint32_t length) { Chunk::data_type data; ChunkIterator itr(this, position, position + length); - do { - data = itr.data(); - std::memcpy(data.first, buffer, data.second); + if (setjmp(jmp_disk_full) == 0) { + do { + data = itr.data(); + std::memcpy(data.first, buffer, data.second); - buffer = static_cast(buffer) + data.second; - } while (itr.next()); + buffer = static_cast(buffer) + data.second; + } while (itr.next()); + } else { + throw storage_error("no space left on disk"); + } + + sigaction(SIGBUS, &oldact, NULL); return true; } diff --git a/src/dht/dht_server.cc b/src/dht/dht_server.cc index 1a00908a9acc7e51126acd3d1d79f8b3a4aba5ad..ac4234a806993a21b8ca8af966a53911b3078a5c 100644 --- a/src/dht/dht_server.cc +++ b/src/dht/dht_server.cc @@ -804,6 +804,9 @@ DhtServer::process_queue(packet_queue& queue, uint32_t* quota) { while (!queue.empty()) { DhtTransactionPacket* packet = queue.front(); + DhtTransaction::key_type transactionKey = 0; + if(packet->has_transaction()) + transactionKey = packet->transaction()->key(packet->id()); // Make sure its transaction hasn't timed out yet, if it has/had one // and don't bother sending non-transaction packets (replies) after @@ -836,7 +839,7 @@ DhtServer::process_queue(packet_queue& queue, uint32_t* quota) { } catch (network_error& e) { // Couldn't write packet, maybe something wrong with node address or routing, so mark node as bad. if (packet->has_transaction()) { - transaction_itr itr = m_transactions.find(packet->transaction()->key(packet->id())); + transaction_itr itr = m_transactions.find(transactionKey); if (itr == m_transactions.end()) throw internal_error("DhtServer::process_queue could not find transaction."); @@ -844,8 +847,12 @@ DhtServer::process_queue(packet_queue& queue, uint32_t* quota) { } } - if (packet->has_transaction()) - packet->transaction()->set_packet(NULL); + if (packet->has_transaction()) { + // here transaction can be already deleted by failed_transaction. + transaction_itr itr = m_transactions.find(transactionKey); + if (itr != m_transactions.end()) + packet->transaction()->set_packet(NULL); + } delete packet; } diff --git a/src/dht/dht_transaction.cc b/src/dht/dht_transaction.cc index f876e70d8a1fc78fe8a4109fd125cdf226c95137..84ffc17571501a0881a4cb7a2f8928c70eae80a2 100644 --- a/src/dht/dht_transaction.cc +++ b/src/dht/dht_transaction.cc @@ -46,14 +46,15 @@ namespace torrent { DhtSearch::DhtSearch(const HashString& target, const DhtBucket& contacts) - : base_type(dht_compare_closer(m_target = target)), + : base_type(dht_compare_closer(target)), m_pending(0), m_contacted(0), m_replied(0), m_concurrency(3), m_restart(false), m_started(false), - m_next(end()) { + m_next(end()), + m_target(target) { add_contacts(contacts); } diff --git a/src/download/download_wrapper.cc b/src/download/download_wrapper.cc index 063fcf8a19c2b84a06e48b9f868837192b83d9e6..59e817814e2a0152d024244ad2ae3728fbaa1caf 100644 --- a/src/download/download_wrapper.cc +++ b/src/download/download_wrapper.cc @@ -241,6 +241,7 @@ DownloadWrapper::receive_hash_done(ChunkHandle handle, const char* hash) { } } + data()->call_chunk_done(handle.object()); m_main->chunk_list()->release(&handle); } diff --git a/src/protocol/extensions.cc b/src/protocol/extensions.cc index ccfd93f0a3ef953403be7057dceeab8912e1d7d9..d558a5ee8df8b2a8df265ffb092cc97bf16f934d 100644 --- a/src/protocol/extensions.cc +++ b/src/protocol/extensions.cc @@ -394,7 +394,7 @@ ProtocolExtension::send_metadata_piece(size_t piece) { if (m_download->info()->is_meta_download() || piece >= pieceEnd) { // reject: { "msg_type" => 2, "piece" => ... } m_pendingType = UT_METADATA; - m_pending = build_bencode(40, "d8:msg_typei2e5:piecei%zuee", piece); + m_pending = build_bencode(sizeof(size_t) + 36, "d8:msg_typei2e5:piecei%zuee", piece); return; } @@ -407,7 +407,7 @@ ProtocolExtension::send_metadata_piece(size_t piece) { // data: { "msg_type" => 1, "piece" => ..., "total_size" => ... } followed by piece data (outside of dictionary) size_t length = piece == pieceEnd - 1 ? m_download->info()->metadata_size() % metadata_piece_size : metadata_piece_size; m_pendingType = UT_METADATA; - m_pending = build_bencode(length + 128, "d8:msg_typei1e5:piecei%zue10:total_sizei%zuee", piece, metadataSize); + m_pending = build_bencode((2 * sizeof(size_t)) + length + 120, "d8:msg_typei1e5:piecei%zue10:total_sizei%zuee", piece, metadataSize); memcpy(m_pending.end(), buffer + (piece << metadata_piece_shift), length); m_pending.set(m_pending.data(), m_pending.end() + length, m_pending.owned()); diff --git a/src/protocol/handshake.cc b/src/protocol/handshake.cc index 08b1bb5a81bb98e3a28038a04b3f76fc2e0bde90..6b41bbe33878d2b5085c9c1039134b97d102065f 100644 --- a/src/protocol/handshake.cc +++ b/src/protocol/handshake.cc @@ -289,7 +289,8 @@ Handshake::read_encryption_key() { if (m_incoming) prepare_key_plus_pad(); - m_encryption.key()->compute_secret(m_readBuffer.position(), 96); + if(!m_encryption.key()->compute_secret(m_readBuffer.position(), 96)) + throw handshake_error(ConnectionManager::handshake_failed, e_handshake_invalid_encryption); m_readBuffer.consume(96); // Determine the synchronisation string. @@ -737,7 +738,7 @@ restart: break; if (m_readBuffer.remaining() > m_encryption.length_ia()) - throw internal_error("Read past initial payload after incoming encrypted handshake."); + throw handshake_error(ConnectionManager::handshake_failed, e_handshake_invalid_value); if (m_encryption.crypto() != HandshakeEncryption::crypto_rc4) m_encryption.info()->set_obfuscated(); diff --git a/src/torrent/data/download_data.h b/src/torrent/data/download_data.h index 781ef8c5552796b8ba07221f5e90f00444eb9577..2b9c94120334510891f8a2e4bcc5e5446cf1a343 100644 --- a/src/torrent/data/download_data.h +++ b/src/torrent/data/download_data.h @@ -45,7 +45,7 @@ #include namespace torrent { - +class ChunkListNode; class ChunkSelector; class Download; class DownloadWrapper; @@ -59,6 +59,8 @@ public: typedef std::function slot_void; + typedef void (function_chunk_list_node_p)(ChunkListNode *); + typedef std::function slot_chunk_list_node_p; download_data() : m_wanted_chunks(0) {} const HashString& hash() const { return m_hash; } @@ -81,6 +83,7 @@ public: slot_void& slot_download_done() const { return m_slot_download_done; } slot_void& slot_partially_done() const { return m_slot_partially_done; } slot_void& slot_partially_restarted() const { return m_slot_partially_restarted; } + slot_chunk_list_node_p& slot_chunk_done() const {return m_slot_chunk_done;} protected: friend class ChunkList; @@ -103,7 +106,7 @@ protected: void call_download_done() { if (m_slot_download_done) m_slot_download_done(); } void call_partially_done() { if (m_slot_partially_done) m_slot_partially_done(); } void call_partially_restarted() { if (m_slot_partially_restarted) m_slot_partially_restarted(); } - + void call_chunk_done(ChunkListNode* chunk_ptr) {if(m_slot_chunk_done) m_slot_chunk_done(chunk_ptr);} private: HashString m_hash; @@ -119,6 +122,7 @@ private: mutable slot_void m_slot_download_done; mutable slot_void m_slot_partially_done; mutable slot_void m_slot_partially_restarted; + mutable slot_chunk_list_node_p m_slot_chunk_done; }; } diff --git a/src/torrent/data/file.cc b/src/torrent/data/file.cc index c1cdf2da44d775206309262c796e73c9a10aad83..0dfe6ea8a974d6a5247114a268bfeb3a3364eb1b 100644 --- a/src/torrent/data/file.cc +++ b/src/torrent/data/file.cc @@ -177,13 +177,14 @@ File::resize_file() { if (m_size == SocketFile(m_fd).size()) return true; - // For now make it so that the fallocate flag indicates if we want - // to do potentially blocking allocation, while FS supported - // non-blocking allocation is done always. - int flags = SocketFile::flag_fallocate; + int flags = 0; - if (m_flags & flag_fallocate) + // Set FS supported non-blocking allocation flag and potentially + // blocking allocation flag if fallocate flag is set. + if (m_flags & flag_fallocate) { + flags |= SocketFile::flag_fallocate; flags |= SocketFile::flag_fallocate_blocking; + } return SocketFile(m_fd).set_size(m_size, flags); } diff --git a/src/torrent/data/file_list.cc b/src/torrent/data/file_list.cc index a13ff25317a55ffb58c26cc91d98126bb30d1763..4721bdbd61de8f5b60adde7bfc8dfb782f8d59d4 100644 --- a/src/torrent/data/file_list.cc +++ b/src/torrent/data/file_list.cc @@ -71,15 +71,15 @@ namespace torrent { void verify_file_list(const FileList* fl) { if (fl->empty()) - throw internal_error("verify_file_list() 1."); + throw internal_error("verify_file_list() 1.", fl->data()->hash()); if ((*fl->begin())->match_depth_prev() != 0 || (*fl->rbegin())->match_depth_next() != 0) - throw internal_error("verify_file_list() 2."); + throw internal_error("verify_file_list() 2.", fl->data()->hash()); for (FileList::const_iterator itr = fl->begin(), last = fl->end() - 1; itr != last; itr++) if ((*itr)->match_depth_next() != (*(itr + 1))->match_depth_prev() || (*itr)->match_depth_next() >= (*itr)->path()->size()) - throw internal_error("verify_file_list() 3."); + throw internal_error("verify_file_list() 3.", fl->data()->hash()); } FileList::FileList() : @@ -145,7 +145,7 @@ FileList::completed_bytes() const { } else { if (completed_chunks() == 0) - throw internal_error("FileList::bytes_completed() completed_chunks() == 0."); + throw internal_error("FileList::bytes_completed() completed_chunks() == 0.", data()->hash()); return (completed_chunks() - 1) * cs + size_bytes() % cs; } @@ -156,10 +156,10 @@ FileList::left_bytes() const { uint64_t left = size_bytes() - completed_bytes(); if (left > ((uint64_t)1 << 60)) - throw internal_error("FileList::bytes_left() is too large."); + throw internal_error("FileList::bytes_left() is too large.", data()->hash()); if (completed_chunks() == size_chunks() && left != 0) - throw internal_error("FileList::bytes_left() has an invalid size."); + throw internal_error("FileList::bytes_left() has an invalid size.", data()->hash()); return left; } @@ -214,10 +214,10 @@ FileList::free_diskspace() const { FileList::iterator_range FileList::split(iterator position, split_type* first, split_type* last) { if (is_open()) - throw internal_error("FileList::split(...) is_open()."); + throw internal_error("FileList::split(...) is_open().", data()->hash()); if (first == last || position == end()) - throw internal_error("FileList::split(...) invalid arguments."); + throw internal_error("FileList::split(...) invalid arguments.", data()->hash()); if (position != begin()) (*(position - 1))->set_match_depth_next(0); @@ -252,7 +252,7 @@ FileList::split(iterator position, split_type* first, split_type* last) { } if (offset != oldFile->offset() + oldFile->size_bytes()) - throw internal_error("FileList::split(...) split size does not match the old size."); + throw internal_error("FileList::split(...) split size does not match the old size.", data()->hash()); delete oldFile; return iterator_range(position, itr); @@ -369,10 +369,10 @@ FileList::make_all_paths() { void FileList::initialize(uint64_t torrentSize, uint32_t chunkSize) { if (sizeof(off_t) != 8) - throw internal_error("Last minute panic; sizeof(off_t) != 8."); + throw internal_error("Last minute panic; sizeof(off_t) != 8.", data()->hash()); if (chunkSize == 0) - throw internal_error("FileList::initialize() chunk_size() == 0."); + throw internal_error("FileList::initialize() chunk_size() == 0.", data()->hash()); m_chunkSize = chunkSize; m_torrentSize = torrentSize; @@ -405,7 +405,7 @@ FileList::open(int flags) { LT_LOG_FL(INFO, "Opening.", 0); if (m_rootDir.empty()) - throw internal_error("FileList::open() m_rootDir.empty()."); + throw internal_error("FileList::open() m_rootDir.empty().", data()->hash()); m_indirectLinks.push_back(m_rootDir); @@ -589,7 +589,7 @@ FileList::create_chunk_part(FileList::iterator itr, uint64_t offset, uint32_t le length = std::min(length, (*itr)->size_bytes() - offset); if ((int64_t)offset < 0) - throw internal_error("FileList::chunk_part(...) caught a negative offset"); + throw internal_error("FileList::chunk_part(...) caught a negative offset", data()->hash()); // Check that offset != length of file. @@ -602,14 +602,14 @@ FileList::create_chunk_part(FileList::iterator itr, uint64_t offset, uint32_t le Chunk* FileList::create_chunk(uint64_t offset, uint32_t length, int prot) { if (offset + length > m_torrentSize) - throw internal_error("Tried to access chunk out of range in FileList"); + throw internal_error("Tried to access chunk out of range in FileList", data()->hash()); std::auto_ptr chunk(new Chunk); for (iterator itr = std::find_if(begin(), end(), std::bind2nd(std::mem_fun(&File::is_valid_position), offset)); length != 0; ++itr) { if (itr == end()) - throw internal_error("FileList could not find a valid file for chunk"); + throw internal_error("FileList could not find a valid file for chunk", data()->hash()); if ((*itr)->size_bytes() == 0) continue; @@ -620,10 +620,10 @@ FileList::create_chunk(uint64_t offset, uint32_t length, int prot) { return NULL; if (mc.size() == 0) - throw internal_error("FileList::create_chunk(...) mc.size() == 0."); + throw internal_error("FileList::create_chunk(...) mc.size() == 0.", data()->hash()); if (mc.size() > length) - throw internal_error("FileList::create_chunk(...) mc.size() > length."); + throw internal_error("FileList::create_chunk(...) mc.size() > length.", data()->hash()); chunk->push_back(ChunkPart::MAPPED_MMAP, mc); chunk->back().set_file(*itr, offset - (*itr)->offset()); @@ -646,19 +646,19 @@ FileList::create_chunk_index(uint32_t index, int prot) { void FileList::mark_completed(uint32_t index) { if (index >= size_chunks() || completed_chunks() >= size_chunks()) - throw internal_error("FileList::mark_completed(...) received an invalid index."); + throw internal_error("FileList::mark_completed(...) received an invalid index.", data()->hash()); if (bitfield()->empty()) - throw internal_error("FileList::mark_completed(...) bitfield is empty."); + throw internal_error("FileList::mark_completed(...) bitfield is empty.", data()->hash()); if (bitfield()->size_bits() != size_chunks()) - throw internal_error("FileList::mark_completed(...) bitfield is not the right size."); + throw internal_error("FileList::mark_completed(...) bitfield is not the right size.", data()->hash()); if (bitfield()->get(index)) - throw internal_error("FileList::mark_completed(...) received a chunk that has already been finished."); + throw internal_error("FileList::mark_completed(...) received a chunk that has already been finished.", data()->hash()); if (bitfield()->size_set() >= bitfield()->size_bits()) - throw internal_error("FileList::mark_completed(...) bitfield()->size_set() >= bitfield()->size_bits()."); + throw internal_error("FileList::mark_completed(...) bitfield()->size_set() >= bitfield()->size_bits().", data()->hash()); LT_LOG_FL(DEBUG, "Done chunk: index:%" PRIu32 ".", index); @@ -668,7 +668,7 @@ FileList::mark_completed(uint32_t index) { // TODO: Remember to validate 'wanted_chunks'. if (m_data.normal_priority()->has(index) || m_data.high_priority()->has(index)) { if (m_data.wanted_chunks() == 0) - throw internal_error("FileList::mark_completed(...) m_data.wanted_chunks() == 0."); + throw internal_error("FileList::mark_completed(...) m_data.wanted_chunks() == 0.", data()->hash()); m_data.set_wanted_chunks(m_data.wanted_chunks() - 1); } @@ -680,7 +680,7 @@ FileList::inc_completed(iterator firstItr, uint32_t index) { iterator lastItr = std::find_if(firstItr, end(), rak::less(index + 1, std::mem_fun(&File::range_second))); if (firstItr == end()) - throw internal_error("FileList::inc_completed() first == m_entryList->end()."); + throw internal_error("FileList::inc_completed() first == m_entryList->end().", data()->hash()); // TODO: Check if this works right for zero-length files. std::for_each(firstItr, @@ -693,7 +693,7 @@ FileList::inc_completed(iterator firstItr, uint32_t index) { void FileList::update_completed() { if (!bitfield()->is_tail_cleared()) - throw internal_error("Content::update_done() called but m_bitfield's tail isn't cleared."); + throw internal_error("Content::update_done() called but m_bitfield's tail isn't cleared.", data()->hash()); m_data.update_wanted_chunks(); diff --git a/src/torrent/exceptions.h b/src/torrent/exceptions.h index d85683484efca817699b3f6f58f76c8eaca0d93c..e3fee86aa29ab6e6b3328fb7b02f772127187882 100644 --- a/src/torrent/exceptions.h +++ b/src/torrent/exceptions.h @@ -46,6 +46,7 @@ #include #include #include +#include namespace torrent { @@ -61,6 +62,10 @@ public: class LIBTORRENT_EXPORT internal_error : public base_error { public: internal_error(const char* msg) { initialize(msg); } + internal_error(const char* msg, const std::string& context) { + initialize(std::string(msg) + " [" + context + "]"); } + internal_error(const char* msg, const HashString& hash) { + initialize(std::string(msg) + " [#" + hash_string_to_hex_str(hash) + "]"); } internal_error(const std::string& msg) { initialize(msg); } virtual ~internal_error() throw() {} diff --git a/src/torrent/object_stream.cc b/src/torrent/object_stream.cc index 8c09aea5250486fc3ebfbddd3b5c0b4d4b4fa8f8..011e23d8ad648525302156bf51f820986147a3e6 100644 --- a/src/torrent/object_stream.cc +++ b/src/torrent/object_stream.cc @@ -104,7 +104,8 @@ object_read_bencode_c_string(const char* first, const char* last) { while (first != last && *first >= '0' && *first <= '9') length = length * 10 + (*first++ - '0'); - if (length + 1 > (unsigned int)std::distance(first, last) || *first++ != ':') + if (length + 1 > (unsigned int)std::distance(first, last) || *first++ != ':' + || length + 1 == 0) throw torrent::bencode_error("Invalid bencode data."); return raw_string(first, length); diff --git a/src/torrent/peer/client_list.cc b/src/torrent/peer/client_list.cc index f7d7c7494333cd08fcf35f69677f72d49dd90902..c857f62da1c7d760e62798a566b422e2c17608ee 100644 --- a/src/torrent/peer/client_list.cc +++ b/src/torrent/peer/client_list.cc @@ -61,6 +61,7 @@ ClientList::ClientList() { insert_helper(ClientInfo::TYPE_AZUREUS, "KT", NULL, NULL, "KTorrent"); insert_helper(ClientInfo::TYPE_AZUREUS, "LT", NULL, NULL, "libtorrent"); insert_helper(ClientInfo::TYPE_AZUREUS, "lt", NULL, NULL, "libTorrent"); + insert_helper(ClientInfo::TYPE_AZUREUS, "UM", NULL, NULL, "uTorrent Mac"); insert_helper(ClientInfo::TYPE_AZUREUS, "UT", NULL, NULL, "uTorrent"); insert_helper(ClientInfo::TYPE_MAINLINE, "M", NULL, NULL, "Mainline"); @@ -72,6 +73,7 @@ ClientList::ClientList() { insert_helper(ClientInfo::TYPE_AZUREUS, "BB", NULL, NULL, "BitBuddy"); insert_helper(ClientInfo::TYPE_AZUREUS, "BX", NULL, NULL, "Bittorrent X"); insert_helper(ClientInfo::TYPE_AZUREUS, "BS", NULL, NULL, "BTSlave"); + insert_helper(ClientInfo::TYPE_AZUREUS, "BT", NULL, NULL, "BBTor"); insert_helper(ClientInfo::TYPE_AZUREUS, "CT", NULL, NULL, "CTorrent"); insert_helper(ClientInfo::TYPE_AZUREUS, "DE", NULL, NULL, "DelugeTorrent"); insert_helper(ClientInfo::TYPE_AZUREUS, "ES", NULL, NULL, "Electric Sheep"); diff --git a/src/torrent/poll_epoll.cc b/src/torrent/poll_epoll.cc index f8775588dd5442f90d6800943ba97ff20ed6c3d1..345a7365e36ee10b1e317cae5865a3adcbf10f95 100644 --- a/src/torrent/poll_epoll.cc +++ b/src/torrent/poll_epoll.cc @@ -213,8 +213,13 @@ PollEPoll::do_poll(int64_t timeout_usec, int flags) { thread_base::acquire_global_lock(); } - if (status == -1 && rak::error_number::current().value() != rak::error_number::e_intr) - throw std::runtime_error("Poll::work(): " + std::string(rak::error_number::current().c_str())); + if (status == -1) { + if (rak::error_number::current().value() != rak::error_number::e_intr) { + throw std::runtime_error("PollEPoll::work(): " + std::string(rak::error_number::current().c_str())); + } + + return 0; + } return perform(); } diff --git a/src/torrent/poll_kqueue.cc b/src/torrent/poll_kqueue.cc index 25a8a2eb905b911191fd67be1d2b8528e348aaa7..6bd4d02da9cb7877fad632c05c089ae40b65e44a 100644 --- a/src/torrent/poll_kqueue.cc +++ b/src/torrent/poll_kqueue.cc @@ -272,8 +272,13 @@ PollKQueue::do_poll(int64_t timeout_usec, int flags) { thread_base::acquire_global_lock(); } - if (status == -1 && rak::error_number::current().value() != rak::error_number::e_intr) - throw std::runtime_error("Poll::work(): " + std::string(rak::error_number::current().c_str())); + if (status == -1) { + if (rak::error_number::current().value() != rak::error_number::e_intr) { + throw std::runtime_error("PollKQueue::work(): " + std::string(rak::error_number::current().c_str())); + } + + return 0; + } return perform(); } diff --git a/src/torrent/poll_select.cc b/src/torrent/poll_select.cc index b42e8709505d7e38c60c78a3e980da3e117bd42a..dc802c3cd6ab248d4a08e452b6eae99cacebfa45 100644 --- a/src/torrent/poll_select.cc +++ b/src/torrent/poll_select.cc @@ -254,8 +254,13 @@ PollSelect::do_poll(int64_t timeout_usec, int flags) { thread_base::acquire_global_lock(); } - if (status == -1 && rak::error_number::current().value() != rak::error_number::e_intr) - throw std::runtime_error("Poll::work(): " + std::string(rak::error_number::current().c_str())); + if (status == -1) { + if (rak::error_number::current().value() != rak::error_number::e_intr) { + throw std::runtime_error("PollSelect::work(): " + std::string(rak::error_number::current().c_str())); + } + + return 0; + } return perform(read_set, write_set, error_set); } diff --git a/src/utils/diffie_hellman.cc b/src/utils/diffie_hellman.cc index 65dfdc4efb7c11345146e63cf0380fb4f7e40b82..aa653d45f85e0f430b91a2350ed0a6b723a601d8 100644 --- a/src/utils/diffie_hellman.cc +++ b/src/utils/diffie_hellman.cc @@ -80,7 +80,7 @@ DiffieHellman::is_valid() const { #endif } -void +bool DiffieHellman::compute_secret(const unsigned char *pubkey, unsigned int length) { #ifdef USE_OPENSSL BIGNUM* k = BN_bin2bn(pubkey, length, NULL); @@ -91,6 +91,10 @@ DiffieHellman::compute_secret(const unsigned char *pubkey, unsigned int length) m_size = DH_compute_key((unsigned char*)m_secret, k, m_dh); BN_free(k); + + return m_size != -1; +#else + return false; #endif }; diff --git a/src/utils/diffie_hellman.h b/src/utils/diffie_hellman.h index c07f874e54ef9cd946ba5cc98cb5e8e206e0af9a..432542be17e1871766c048df2010225885abdbd6 100644 --- a/src/utils/diffie_hellman.h +++ b/src/utils/diffie_hellman.h @@ -53,7 +53,7 @@ public: const unsigned char generator[], int generatorLength); ~DiffieHellman(); - void compute_secret(const unsigned char pubkey[], unsigned int length); + bool compute_secret(const unsigned char pubkey[], unsigned int length); void store_pub_key(unsigned char* dest, unsigned int length); bool is_valid() const;