mirror of https://github.com/aria2/aria2
2008-10-05 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Made socket for dht connections non-blocking * src/DHTAbstractMessage.cc * src/DHTAbstractMessage.h * src/DHTConnection.h * src/DHTConnectionImpl.cc * src/DHTConnectionImpl.h * src/DHTMessage.h * src/DHTMessageDispatcherImpl.cc * src/DHTMessageDispatcherImpl.h * src/DHTUnknownMessage.cc * src/DHTUnknownMessage.h * src/SocketCore.cc * src/SocketCore.h * test/MockDHTMessage.hpull/1/head
parent
04a2bd3818
commit
389f770008
17
ChangeLog
17
ChangeLog
|
@ -1,3 +1,20 @@
|
||||||
|
2008-10-05 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||||
|
|
||||||
|
Made socket for dht connections non-blocking
|
||||||
|
* src/DHTAbstractMessage.cc
|
||||||
|
* src/DHTAbstractMessage.h
|
||||||
|
* src/DHTConnection.h
|
||||||
|
* src/DHTConnectionImpl.cc
|
||||||
|
* src/DHTConnectionImpl.h
|
||||||
|
* src/DHTMessage.h
|
||||||
|
* src/DHTMessageDispatcherImpl.cc
|
||||||
|
* src/DHTMessageDispatcherImpl.h
|
||||||
|
* src/DHTUnknownMessage.cc
|
||||||
|
* src/DHTUnknownMessage.h
|
||||||
|
* src/SocketCore.cc
|
||||||
|
* src/SocketCore.h
|
||||||
|
* test/MockDHTMessage.h
|
||||||
|
|
||||||
2008-10-05 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
2008-10-05 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||||
|
|
||||||
Changed the type of offset to int.
|
Changed the type of offset to int.
|
||||||
|
|
|
@ -33,6 +33,9 @@
|
||||||
*/
|
*/
|
||||||
/* copyright --> */
|
/* copyright --> */
|
||||||
#include "DHTAbstractMessage.h"
|
#include "DHTAbstractMessage.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
#include "DHTNode.h"
|
#include "DHTNode.h"
|
||||||
#include "BencodeVisitor.h"
|
#include "BencodeVisitor.h"
|
||||||
#include "DHTConnection.h"
|
#include "DHTConnection.h"
|
||||||
|
@ -64,13 +67,16 @@ std::string DHTAbstractMessage::getBencodedMessage()
|
||||||
return v.getBencodedData();
|
return v.getBencodedData();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DHTAbstractMessage::send()
|
bool DHTAbstractMessage::send()
|
||||||
{
|
{
|
||||||
std::string message = getBencodedMessage();
|
std::string message = getBencodedMessage();
|
||||||
_connection->sendMessage(reinterpret_cast<const unsigned char*>(message.c_str()),
|
ssize_t r = _connection->sendMessage
|
||||||
|
(reinterpret_cast<const unsigned char*>(message.c_str()),
|
||||||
message.size(),
|
message.size(),
|
||||||
_remoteNode->getIPAddress(),
|
_remoteNode->getIPAddress(),
|
||||||
_remoteNode->getPort());
|
_remoteNode->getPort());
|
||||||
|
assert(r >= 0);
|
||||||
|
return r == static_cast<ssize_t>(message.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DHTAbstractMessage::setConnection(const WeakHandle<DHTConnection>& connection)
|
void DHTAbstractMessage::setConnection(const WeakHandle<DHTConnection>& connection)
|
||||||
|
|
|
@ -62,7 +62,7 @@ public:
|
||||||
|
|
||||||
virtual ~DHTAbstractMessage();
|
virtual ~DHTAbstractMessage();
|
||||||
|
|
||||||
virtual void send();
|
virtual bool send();
|
||||||
|
|
||||||
virtual std::string getType() const = 0;
|
virtual std::string getType() const = 0;
|
||||||
|
|
||||||
|
|
|
@ -44,9 +44,11 @@ class DHTConnection {
|
||||||
public:
|
public:
|
||||||
virtual ~DHTConnection() {}
|
virtual ~DHTConnection() {}
|
||||||
|
|
||||||
virtual ssize_t receiveMessage(unsigned char* data, size_t len, std::string& host, uint16_t& port) = 0;
|
virtual ssize_t receiveMessage(unsigned char* data, size_t len,
|
||||||
|
std::string& host, uint16_t& port) = 0;
|
||||||
|
|
||||||
virtual void sendMessage(const unsigned char* data, size_t len, const std::string& host, uint16_t port) = 0;
|
virtual ssize_t sendMessage(const unsigned char* data, size_t len,
|
||||||
|
const std::string& host, uint16_t port) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -33,12 +33,14 @@
|
||||||
*/
|
*/
|
||||||
/* copyright --> */
|
/* copyright --> */
|
||||||
#include "DHTConnectionImpl.h"
|
#include "DHTConnectionImpl.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "LogFactory.h"
|
#include "LogFactory.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include "RecoverableException.h"
|
#include "RecoverableException.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "Socket.h"
|
#include "Socket.h"
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -66,6 +68,7 @@ bool DHTConnectionImpl::bind(uint16_t& port)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
_socket->bind(port);
|
_socket->bind(port);
|
||||||
|
_socket->setNonBlockingMode();
|
||||||
std::pair<std::string, uint16_t> svaddr;
|
std::pair<std::string, uint16_t> svaddr;
|
||||||
_socket->getAddrInfo(svaddr);
|
_socket->getAddrInfo(svaddr);
|
||||||
port = svaddr.second;
|
port = svaddr.second;
|
||||||
|
@ -77,22 +80,24 @@ bool DHTConnectionImpl::bind(uint16_t& port)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t DHTConnectionImpl::receiveMessage(unsigned char* data, size_t len, std::string& host, uint16_t& port)
|
ssize_t DHTConnectionImpl::receiveMessage(unsigned char* data, size_t len,
|
||||||
|
std::string& host, uint16_t& port)
|
||||||
{
|
{
|
||||||
if(_socket->isReadable(0)) {
|
|
||||||
std::pair<std::string, uint16_t> remoteHost;
|
std::pair<std::string, uint16_t> remoteHost;
|
||||||
ssize_t length = _socket->readDataFrom(data, len, remoteHost);
|
ssize_t length = _socket->readDataFrom(data, len, remoteHost);
|
||||||
|
if(length == 0) {
|
||||||
|
return length;
|
||||||
|
} else {
|
||||||
host = remoteHost.first;
|
host = remoteHost.first;
|
||||||
port = remoteHost.second;
|
port = remoteHost.second;
|
||||||
return length;
|
return length;
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DHTConnectionImpl::sendMessage(const unsigned char* data, size_t len, const std::string& host, uint16_t port)
|
ssize_t DHTConnectionImpl::sendMessage(const unsigned char* data, size_t len,
|
||||||
|
const std::string& host, uint16_t port)
|
||||||
{
|
{
|
||||||
_socket->writeData(data, len, host, port);
|
return _socket->writeData(data, len, host, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedHandle<SocketCore> DHTConnectionImpl::getSocket() const
|
SharedHandle<SocketCore> DHTConnectionImpl::getSocket() const
|
||||||
|
|
|
@ -71,9 +71,11 @@ public:
|
||||||
*/
|
*/
|
||||||
bool bind(uint16_t& port);
|
bool bind(uint16_t& port);
|
||||||
|
|
||||||
virtual ssize_t receiveMessage(unsigned char* data, size_t len, std::string& host, uint16_t& port);
|
virtual ssize_t receiveMessage(unsigned char* data, size_t len,
|
||||||
|
std::string& host, uint16_t& port);
|
||||||
|
|
||||||
virtual void sendMessage(const unsigned char* data, size_t len, const std::string& host, uint16_t port);
|
virtual ssize_t sendMessage(const unsigned char* data, size_t len,
|
||||||
|
const std::string& host, uint16_t port);
|
||||||
|
|
||||||
SharedHandle<SocketCore> getSocket() const;
|
SharedHandle<SocketCore> getSocket() const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -36,9 +36,11 @@
|
||||||
#define _D_DHT_MESSAGE_H_
|
#define _D_DHT_MESSAGE_H_
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "SharedHandle.h"
|
#include "SharedHandle.h"
|
||||||
#include "A2STR.h"
|
#include "A2STR.h"
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -71,7 +73,7 @@ public:
|
||||||
|
|
||||||
virtual void doReceivedAction() = 0;
|
virtual void doReceivedAction() = 0;
|
||||||
|
|
||||||
virtual void send() = 0;
|
virtual bool send() = 0;
|
||||||
|
|
||||||
virtual bool isReply() const = 0;
|
virtual bool isReply() const = 0;
|
||||||
|
|
||||||
|
|
|
@ -67,28 +67,38 @@ DHTMessageDispatcherImpl::addMessageToQueue(const SharedHandle<DHTMessage>& mess
|
||||||
addMessageToQueue(message, DHT_MESSAGE_TIMEOUT, callback);
|
addMessageToQueue(message, DHT_MESSAGE_TIMEOUT, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
DHTMessageDispatcherImpl::sendMessage(const SharedHandle<DHTMessageEntry>& entry)
|
DHTMessageDispatcherImpl::sendMessage(const SharedHandle<DHTMessageEntry>& entry)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
entry->_message->send();
|
if(entry->_message->send()) {
|
||||||
if(!entry->_message->isReply()) {
|
if(!entry->_message->isReply()) {
|
||||||
_tracker->addMessage(entry->_message, entry->_timeout, entry->_callback);
|
_tracker->addMessage(entry->_message, entry->_timeout, entry->_callback);
|
||||||
}
|
}
|
||||||
_logger->info("Message sent: %s", entry->_message->toString().c_str());
|
_logger->info("Message sent: %s", entry->_message->toString().c_str());
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
} catch(RecoverableException& e) {
|
} catch(RecoverableException& e) {
|
||||||
_logger->error("Failed to send message: %s", e, entry->_message->toString().c_str());
|
_logger->error("Failed to send message: %s", e, entry->_message->toString().c_str());
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DHTMessageDispatcherImpl::sendMessages()
|
void DHTMessageDispatcherImpl::sendMessages()
|
||||||
{
|
{
|
||||||
// TODO I can't use bind1st and mem_fun here because bind1st cannot bind a
|
// TODO I can't use bind1st and mem_fun here because bind1st cannot bind a
|
||||||
// function which takes a reference as an argument..
|
// function which takes a reference as an argument..
|
||||||
for(std::deque<SharedHandle<DHTMessageEntry> >::iterator itr = _messageQueue.begin(); itr != _messageQueue.end(); ++itr) {
|
std::deque<SharedHandle<DHTMessageEntry> >::iterator itr =
|
||||||
sendMessage(*itr);
|
_messageQueue.begin();
|
||||||
|
for(; itr != _messageQueue.end(); ++itr) {
|
||||||
|
if(!sendMessage(*itr)) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
_messageQueue.clear();
|
}
|
||||||
|
_messageQueue.erase(_messageQueue.begin(), itr);
|
||||||
|
_logger->debug("%lu dht messages remaining in the queue.",
|
||||||
|
static_cast<unsigned long>(_messageQueue.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t DHTMessageDispatcherImpl::countMessageInQueue() const
|
size_t DHTMessageDispatcherImpl::countMessageInQueue() const
|
||||||
|
|
|
@ -52,7 +52,7 @@ private:
|
||||||
|
|
||||||
Logger* _logger;
|
Logger* _logger;
|
||||||
|
|
||||||
void sendMessage(const SharedHandle<DHTMessageEntry>& msg);
|
bool sendMessage(const SharedHandle<DHTMessageEntry>& msg);
|
||||||
public:
|
public:
|
||||||
DHTMessageDispatcherImpl(const SharedHandle<DHTMessageTracker>& tracker);
|
DHTMessageDispatcherImpl(const SharedHandle<DHTMessageTracker>& tracker);
|
||||||
|
|
||||||
|
|
|
@ -33,9 +33,12 @@
|
||||||
*/
|
*/
|
||||||
/* copyright --> */
|
/* copyright --> */
|
||||||
#include "DHTUnknownMessage.h"
|
#include "DHTUnknownMessage.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "DHTNode.h"
|
#include "DHTNode.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -66,7 +69,7 @@ DHTUnknownMessage::~DHTUnknownMessage()
|
||||||
|
|
||||||
void DHTUnknownMessage::doReceivedAction() {}
|
void DHTUnknownMessage::doReceivedAction() {}
|
||||||
|
|
||||||
void DHTUnknownMessage::send() {}
|
bool DHTUnknownMessage::send() { return true; }
|
||||||
|
|
||||||
bool DHTUnknownMessage::isReply() const
|
bool DHTUnknownMessage::isReply() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -57,7 +57,7 @@ public:
|
||||||
virtual void doReceivedAction();
|
virtual void doReceivedAction();
|
||||||
|
|
||||||
// do nothing; we don't use this message as outgoing message.
|
// do nothing; we don't use this message as outgoing message.
|
||||||
virtual void send();
|
virtual bool send();
|
||||||
|
|
||||||
// always return false
|
// always return false
|
||||||
virtual bool isReply() const;
|
virtual bool isReply() const;
|
||||||
|
|
|
@ -839,8 +839,11 @@ bool SocketCore::initiateSecureConnection()
|
||||||
#endif // __MINGW32__
|
#endif // __MINGW32__
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocketCore::writeData(const char* data, size_t len, const std::string& host, uint16_t port)
|
ssize_t SocketCore::writeData(const char* data, size_t len,
|
||||||
|
const std::string& host, uint16_t port)
|
||||||
{
|
{
|
||||||
|
_wantRead = false;
|
||||||
|
_wantWrite = false;
|
||||||
|
|
||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
struct addrinfo* res;
|
struct addrinfo* res;
|
||||||
|
@ -861,17 +864,25 @@ void SocketCore::writeData(const char* data, size_t len, const std::string& host
|
||||||
if(r == static_cast<ssize_t>(len)) {
|
if(r == static_cast<ssize_t>(len)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if(r == -1 && errno == EAGAIN) {
|
||||||
|
_wantWrite = true;
|
||||||
|
r = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
freeaddrinfo(res);
|
freeaddrinfo(res);
|
||||||
if(r == -1) {
|
if(r == -1) {
|
||||||
throw DlAbortEx(StringFormat(EX_SOCKET_SEND, errorMsg()).str());
|
throw DlAbortEx(StringFormat(EX_SOCKET_SEND, errorMsg()).str());
|
||||||
}
|
}
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t SocketCore::readDataFrom(char* data, size_t len,
|
ssize_t SocketCore::readDataFrom(char* data, size_t len,
|
||||||
std::pair<std::string /* numerichost */,
|
std::pair<std::string /* numerichost */,
|
||||||
uint16_t /* port */>& sender)
|
uint16_t /* port */>& sender)
|
||||||
{
|
{
|
||||||
|
_wantRead = false;
|
||||||
|
_wantWrite = false;
|
||||||
struct sockaddr_storage sockaddr;
|
struct sockaddr_storage sockaddr;
|
||||||
socklen_t sockaddrlen = sizeof(struct sockaddr_storage);
|
socklen_t sockaddrlen = sizeof(struct sockaddr_storage);
|
||||||
struct sockaddr* addrp = reinterpret_cast<struct sockaddr*>(&sockaddr);
|
struct sockaddr* addrp = reinterpret_cast<struct sockaddr*>(&sockaddr);
|
||||||
|
@ -879,9 +890,15 @@ ssize_t SocketCore::readDataFrom(char* data, size_t len,
|
||||||
while((r = recvfrom(sockfd, data, len, 0, addrp, &sockaddrlen)) == -1 &&
|
while((r = recvfrom(sockfd, data, len, 0, addrp, &sockaddrlen)) == -1 &&
|
||||||
EINTR == errno);
|
EINTR == errno);
|
||||||
if(r == -1) {
|
if(r == -1) {
|
||||||
throw DlAbortEx(StringFormat(EX_SOCKET_RECV, errorMsg()).str());
|
if(errno == EAGAIN) {
|
||||||
|
_wantRead = true;
|
||||||
|
r = 0;
|
||||||
|
} else {
|
||||||
|
throw DlRetryEx(StringFormat(EX_SOCKET_RECV, errorMsg()).str());
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
sender = Util::getNumericNameInfo(addrp, sockaddrlen);
|
sender = Util::getNumericNameInfo(addrp, sockaddrlen);
|
||||||
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
|
@ -222,12 +222,14 @@ public:
|
||||||
return writeData(reinterpret_cast<const char*>(data), len);
|
return writeData(reinterpret_cast<const char*>(data), len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeData(const char* data, size_t len, const std::string& host, uint16_t port);
|
ssize_t writeData(const char* data, size_t len,
|
||||||
|
const std::string& host, uint16_t port);
|
||||||
|
|
||||||
void writeData(const unsigned char* data, size_t len, const std::string& host,
|
ssize_t writeData(const unsigned char* data, size_t len,
|
||||||
|
const std::string& host,
|
||||||
uint16_t port)
|
uint16_t port)
|
||||||
{
|
{
|
||||||
writeData(reinterpret_cast<const char*>(data), len, host, port);
|
return writeData(reinterpret_cast<const char*>(data), len, host, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,9 +2,11 @@
|
||||||
#define _D_MOCK_DHT_MESSAGE_H_
|
#define _D_MOCK_DHT_MESSAGE_H_
|
||||||
|
|
||||||
#include "DHTMessage.h"
|
#include "DHTMessage.h"
|
||||||
|
|
||||||
|
#include <deque>
|
||||||
|
|
||||||
#include "DHTNode.h"
|
#include "DHTNode.h"
|
||||||
#include "Peer.h"
|
#include "Peer.h"
|
||||||
#include <deque>
|
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -30,7 +32,7 @@ public:
|
||||||
|
|
||||||
virtual void doReceivedAction() {}
|
virtual void doReceivedAction() {}
|
||||||
|
|
||||||
virtual void send() {}
|
virtual bool send() { return true; }
|
||||||
|
|
||||||
virtual bool isReply() const { return _isReply; }
|
virtual bool isReply() const { return _isReply; }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue