mirror of https://github.com/aria2/aria2
2006-06-22 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
To make a listening socket non-block: * src/SocketCore.h (setNonBlockingMode): New function. * src/SocketCore.cc (setNonBlockingMode): New function. (beginListen): Added a call to setNonBlockingMode(). (acceptConnection): Call setNonBlockingMode(). (setBlockingMode): Updated. To handle tracker's NAT-checking: * src/PeerConnection.cc (receiveHandshake): 'msg' param is filled with received data and its length is assigned to 'length' param, even if all handshake message is not yet received. * src/PeerInteractionCommand.cc (executeInternal): Use peerInteraction->receiveHandshake(true) when a new peer connects to localhost. A call to peerInteraction->sendHandshake() was removed because it is called from peerInteraction->receiveHandshake(true). * src/PeerInteraction.h (quickReplied): New variable. (receiveHandshake): Added an argument. * src/PeerInteraction.cc (PeerInteraction): Added the initialization of quickReplied. (receiveHandshake): Send handshake message as soon as the info hash in a handshake message from a peer is correct. To change the random part of peer id and key parameter: * src/TorrentMan.h (key): New variable. * src/TorrentMan.cc (setupInternal1): Use Util::randomAlpha() to generate random part of peer id, which is now "-aria2-"+13 alphabet characters([A-Za-z]). key is also generated by Util::randomAlpha() and it is now 8 character long. * src/Util.h (randomAlpha): New function. * src/Util.cc (randomAlpha): New function. * src/TrackerWatcherCommand.cc (execute): In a tracker request: Use torrentMan->key as key parameter. Added no_peer_id=1. Set snubbing flag to false when a choke message is received from a snubbed peer. * src/ChokeMessage.cc (receivedAction): Set snubbing flag to false.pull/1/head
parent
70ff0c0b3b
commit
d02d80d9e9
55
ChangeLog
55
ChangeLog
|
@ -1,3 +1,58 @@
|
||||||
|
2006-06-22 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||||
|
|
||||||
|
To make a listening socket non-block:
|
||||||
|
|
||||||
|
* src/SocketCore.h
|
||||||
|
(setNonBlockingMode): New function.
|
||||||
|
* src/SocketCore.cc
|
||||||
|
(setNonBlockingMode): New function.
|
||||||
|
(beginListen): Added a call to setNonBlockingMode().
|
||||||
|
(acceptConnection): Call setNonBlockingMode().
|
||||||
|
(setBlockingMode): Updated.
|
||||||
|
|
||||||
|
To handle tracker's NAT-checking:
|
||||||
|
|
||||||
|
* src/PeerConnection.cc
|
||||||
|
(receiveHandshake): 'msg' param is filled with received data and
|
||||||
|
its length is assigned to 'length' param, even if all handshake
|
||||||
|
message is not yet received.
|
||||||
|
* src/PeerInteractionCommand.cc
|
||||||
|
(executeInternal): Use peerInteraction->receiveHandshake(true) when
|
||||||
|
a new peer connects to localhost.
|
||||||
|
A call to peerInteraction->sendHandshake() was removed because
|
||||||
|
it is called from peerInteraction->receiveHandshake(true).
|
||||||
|
* src/PeerInteraction.h
|
||||||
|
(quickReplied): New variable.
|
||||||
|
(receiveHandshake): Added an argument.
|
||||||
|
* src/PeerInteraction.cc
|
||||||
|
(PeerInteraction): Added the initialization of quickReplied.
|
||||||
|
(receiveHandshake): Send handshake message as soon as the info hash
|
||||||
|
in a handshake message from a peer is correct.
|
||||||
|
|
||||||
|
|
||||||
|
To change the random part of peer id and key parameter:
|
||||||
|
|
||||||
|
* src/TorrentMan.h
|
||||||
|
(key): New variable.
|
||||||
|
* src/TorrentMan.cc
|
||||||
|
(setupInternal1): Use Util::randomAlpha() to generate random part
|
||||||
|
of peer id, which is now "-aria2-"+13 alphabet characters([A-Za-z]).
|
||||||
|
key is also generated by Util::randomAlpha() and it is now 8 character
|
||||||
|
long.
|
||||||
|
* src/Util.h
|
||||||
|
(randomAlpha): New function.
|
||||||
|
* src/Util.cc
|
||||||
|
(randomAlpha): New function.
|
||||||
|
* src/TrackerWatcherCommand.cc
|
||||||
|
(execute): In a tracker request: Use torrentMan->key as key parameter.
|
||||||
|
Added no_peer_id=1.
|
||||||
|
|
||||||
|
Set snubbing flag to false when a choke message is received from a
|
||||||
|
snubbed peer.
|
||||||
|
|
||||||
|
* src/ChokeMessage.cc
|
||||||
|
(receivedAction): Set snubbing flag to false.
|
||||||
|
|
||||||
2006-06-18 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
2006-06-18 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||||
|
|
||||||
* src/TorrentMan.cc (setupInternal1): Fixed peerId generation bug.
|
* src/TorrentMan.cc (setupInternal1): Fixed peerId generation bug.
|
||||||
|
|
|
@ -40,6 +40,7 @@ ChokeMessage* ChokeMessage::create(const char* data, int dataLength) {
|
||||||
|
|
||||||
void ChokeMessage::receivedAction() {
|
void ChokeMessage::receivedAction() {
|
||||||
peer->peerChoking = true;
|
peer->peerChoking = true;
|
||||||
|
peer->snubbing = false;
|
||||||
peerInteraction->onChoked();
|
peerInteraction->onChoked();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,6 +101,7 @@ bool PeerConnection::receiveMessage(char* msg, int& length) {
|
||||||
|
|
||||||
bool PeerConnection::receiveHandshake(char* msg, int& length) {
|
bool PeerConnection::receiveHandshake(char* msg, int& length) {
|
||||||
if(!socket->isReadable(0)) {
|
if(!socket->isReadable(0)) {
|
||||||
|
length = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int remain = HANDSHAKE_MESSAGE_LENGTH-resbufLength;
|
int remain = HANDSHAKE_MESSAGE_LENGTH-resbufLength;
|
||||||
|
@ -110,14 +111,19 @@ bool PeerConnection::receiveHandshake(char* msg, int& length) {
|
||||||
// we got EOF
|
// we got EOF
|
||||||
throw new DlAbortEx(EX_EOF_FROM_PEER);
|
throw new DlAbortEx(EX_EOF_FROM_PEER);
|
||||||
}
|
}
|
||||||
|
bool retval;
|
||||||
if(remain != temp) {
|
if(remain != temp) {
|
||||||
|
retval = false;
|
||||||
|
} else {
|
||||||
|
retval = true;
|
||||||
|
}
|
||||||
resbufLength += temp;
|
resbufLength += temp;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// we got whole handshake payload
|
// we got whole handshake payload
|
||||||
|
int writeLength = resbufLength > length ? length : resbufLength;
|
||||||
|
memcpy(msg, resbuf, writeLength);
|
||||||
|
length = writeLength;
|
||||||
|
if(retval) {
|
||||||
resbufLength = 0;
|
resbufLength = 0;
|
||||||
|
}
|
||||||
memcpy(msg, resbuf, HANDSHAKE_MESSAGE_LENGTH);
|
return retval;
|
||||||
length = HANDSHAKE_MESSAGE_LENGTH;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,8 @@ PeerInteraction::PeerInteraction(int cuid,
|
||||||
:cuid(cuid),
|
:cuid(cuid),
|
||||||
uploadLimit(0),
|
uploadLimit(0),
|
||||||
torrentMan(torrentMan),
|
torrentMan(torrentMan),
|
||||||
peer(peer) {
|
peer(peer),
|
||||||
|
quickReplied(false) {
|
||||||
peerConnection = new PeerConnection(cuid, socket, op);
|
peerConnection = new PeerConnection(cuid, socket, op);
|
||||||
logger = LogFactory::getInstance();
|
logger = LogFactory::getInstance();
|
||||||
}
|
}
|
||||||
|
@ -285,10 +286,19 @@ int PeerInteraction::countRequestSlot() const {
|
||||||
return requestSlots.size();
|
return requestSlots.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
HandshakeMessage* PeerInteraction::receiveHandshake() {
|
HandshakeMessage* PeerInteraction::receiveHandshake(bool quickReply) {
|
||||||
char msg[HANDSHAKE_MESSAGE_LENGTH];
|
char msg[HANDSHAKE_MESSAGE_LENGTH];
|
||||||
int msgLength = 0;
|
int msgLength = HANDSHAKE_MESSAGE_LENGTH;
|
||||||
if(!peerConnection->receiveHandshake(msg, msgLength)) {
|
bool retval = peerConnection->receiveHandshake(msg, msgLength);
|
||||||
|
// To handle tracker's NAT-checking feature
|
||||||
|
if(!quickReplied && quickReply && msgLength >= 48) {
|
||||||
|
quickReplied = true;
|
||||||
|
// check info_hash
|
||||||
|
if(memcmp(torrentMan->getInfoHash(), &msg[28], INFO_HASH_LENGTH) == 0) {
|
||||||
|
sendHandshake();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!retval) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
HandshakeMessage* handshakeMessage = createHandshakeMessage(msg, msgLength);
|
HandshakeMessage* handshakeMessage = createHandshakeMessage(msg, msgLength);
|
||||||
|
|
|
@ -62,6 +62,7 @@ private:
|
||||||
Pieces pieces;
|
Pieces pieces;
|
||||||
// allowed fast piece indexes that local client has sent
|
// allowed fast piece indexes that local client has sent
|
||||||
Integers fastSet;
|
Integers fastSet;
|
||||||
|
bool quickReplied;
|
||||||
const Logger* logger;
|
const Logger* logger;
|
||||||
|
|
||||||
void getNewPieceAndSendInterest(int pieceNum);
|
void getNewPieceAndSendInterest(int pieceNum);
|
||||||
|
@ -116,7 +117,7 @@ public:
|
||||||
void sendAllowedFast();
|
void sendAllowedFast();
|
||||||
|
|
||||||
PeerMessage* receiveMessage();
|
PeerMessage* receiveMessage();
|
||||||
HandshakeMessage* receiveHandshake();
|
HandshakeMessage* receiveHandshake(bool quickReply = false);
|
||||||
|
|
||||||
RequestMessage* createRequestMessage(int index, int blockIndex);
|
RequestMessage* createRequestMessage(int index, int blockIndex);
|
||||||
CancelMessage* createCancelMessage(int index, int begin, int length);
|
CancelMessage* createCancelMessage(int index, int begin, int length);
|
||||||
|
|
|
@ -89,7 +89,8 @@ bool PeerInteractionCommand::executeInternal() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RECEIVER_WAIT_HANDSHAKE: {
|
case RECEIVER_WAIT_HANDSHAKE: {
|
||||||
HandshakeMessage* handshakeMessage = peerInteraction->receiveHandshake();
|
HandshakeMessage* handshakeMessage =
|
||||||
|
peerInteraction->receiveHandshake(true);
|
||||||
if(handshakeMessage == NULL) {
|
if(handshakeMessage == NULL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -98,7 +99,6 @@ bool PeerInteractionCommand::executeInternal() {
|
||||||
peer->ipaddr.c_str(), peer->port,
|
peer->ipaddr.c_str(), peer->port,
|
||||||
handshakeMessage->toString().c_str());
|
handshakeMessage->toString().c_str());
|
||||||
delete handshakeMessage;
|
delete handshakeMessage;
|
||||||
peerInteraction->sendHandshake();
|
|
||||||
haveCheckTime.reset();
|
haveCheckTime.reset();
|
||||||
peerInteraction->sendBitfield();
|
peerInteraction->sendBitfield();
|
||||||
peerInteraction->sendAllowedFast();
|
peerInteraction->sendAllowedFast();
|
||||||
|
|
|
@ -93,6 +93,8 @@ void SocketCore::beginListen(int port) {
|
||||||
if(listen(sockfd, 1) == -1) {
|
if(listen(sockfd, 1) == -1) {
|
||||||
throw new DlAbortEx(EX_SOCKET_LISTEN, strerror(errno));
|
throw new DlAbortEx(EX_SOCKET_LISTEN, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setNonBlockingMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
SocketCore* SocketCore::acceptConnection() const {
|
SocketCore* SocketCore::acceptConnection() const {
|
||||||
|
@ -166,16 +168,22 @@ void SocketCore::establishConnection(const string& host, int port) {
|
||||||
freeaddrinfo(res);
|
freeaddrinfo(res);
|
||||||
}
|
}
|
||||||
// make socket non-blocking mode
|
// make socket non-blocking mode
|
||||||
int flags = fcntl(sockfd, F_GETFL, 0);
|
setNonBlockingMode();
|
||||||
fcntl(sockfd, F_SETFL, flags|O_NONBLOCK);
|
|
||||||
if(connect(sockfd, (struct sockaddr*)&sockaddr, (socklen_t)sizeof(sockaddr)) == -1 && errno != EINPROGRESS) {
|
if(connect(sockfd, (struct sockaddr*)&sockaddr, (socklen_t)sizeof(sockaddr)) == -1 && errno != EINPROGRESS) {
|
||||||
throw new DlAbortEx(EX_SOCKET_CONNECT, host.c_str(), strerror(errno));
|
throw new DlAbortEx(EX_SOCKET_CONNECT, host.c_str(), strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SocketCore::setNonBlockingMode() const {
|
||||||
|
int flags = fcntl(sockfd, F_GETFL, 0);
|
||||||
|
// TODO add error handling
|
||||||
|
fcntl(sockfd, F_SETFL, flags|O_NONBLOCK);
|
||||||
|
}
|
||||||
|
|
||||||
void SocketCore::setBlockingMode() const {
|
void SocketCore::setBlockingMode() const {
|
||||||
int flags = fcntl(sockfd, F_GETFL, 0);
|
int flags = fcntl(sockfd, F_GETFL, 0);
|
||||||
fcntl(sockfd, F_SETFL, flags&~O_NONBLOCK);
|
// TODO add error handling
|
||||||
|
fcntl(sockfd, F_SETFL, flags&(~O_NONBLOCK));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocketCore::closeConnection() {
|
void SocketCore::closeConnection() {
|
||||||
|
|
|
@ -104,6 +104,8 @@ public:
|
||||||
*/
|
*/
|
||||||
void establishConnection(const string& host, int port);
|
void establishConnection(const string& host, int port);
|
||||||
|
|
||||||
|
void setNonBlockingMode() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes this socket blocking mode.
|
* Makes this socket blocking mode.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -399,10 +399,8 @@ void TorrentMan::readFileEntry(FileEntries& fileEntries, Directory** pTopDir, co
|
||||||
|
|
||||||
void TorrentMan::setupInternal1(const string& metaInfoFile) {
|
void TorrentMan::setupInternal1(const string& metaInfoFile) {
|
||||||
peerId = "-aria2-";
|
peerId = "-aria2-";
|
||||||
int randomSize = 20-peerId.size();
|
peerId += Util::randomAlpha(20-peerId.size());
|
||||||
for(int i = 0; i < randomSize; i++) {
|
key = Util::randomAlpha(8);
|
||||||
peerId += Util::itos((int)(((double)10)*random()/(RAND_MAX+1.0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
uploadLength = 0;
|
uploadLength = 0;
|
||||||
downloadLength = 0;
|
downloadLength = 0;
|
||||||
|
|
|
@ -109,6 +109,7 @@ public:
|
||||||
int pieces;
|
int pieces;
|
||||||
// TODO type char* would be better
|
// TODO type char* would be better
|
||||||
string peerId;
|
string peerId;
|
||||||
|
string key;
|
||||||
string announce;
|
string announce;
|
||||||
string trackerId;
|
string trackerId;
|
||||||
string name;
|
string name;
|
||||||
|
|
|
@ -87,8 +87,9 @@ bool TrackerWatcherCommand::execute() {
|
||||||
"left="+(e->torrentMan->getTotalLength()-e->torrentMan->getDownloadLength() <= 0
|
"left="+(e->torrentMan->getTotalLength()-e->torrentMan->getDownloadLength() <= 0
|
||||||
? "0" : Util::llitos(e->torrentMan->getTotalLength()-e->torrentMan->getDownloadLength()))+"&"+
|
? "0" : Util::llitos(e->torrentMan->getTotalLength()-e->torrentMan->getDownloadLength()))+"&"+
|
||||||
"compact=1"+"&"+
|
"compact=1"+"&"+
|
||||||
"key="+e->torrentMan->peerId+"&"+
|
"key="+e->torrentMan->key+"&"+
|
||||||
"numwant="+Util::itos(numWant);
|
"numwant="+Util::itos(numWant)+"&"+
|
||||||
|
"no_peer_id=1";
|
||||||
if(!event.empty()) {
|
if(!event.empty()) {
|
||||||
url += string("&")+"event="+event;
|
url += string("&")+"event="+event;
|
||||||
}
|
}
|
||||||
|
|
15
src/Util.cc
15
src/Util.cc
|
@ -456,3 +456,18 @@ int Util::countBit(unsigned int n) {
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string Util::randomAlpha(int length) {
|
||||||
|
string str;
|
||||||
|
for(int i = 0; i < length; i++) {
|
||||||
|
int index = (int)(((double)52)*random()/(RAND_MAX+1.0));
|
||||||
|
char ch;
|
||||||
|
if(index < 26) {
|
||||||
|
ch = (char)('A'+index);
|
||||||
|
} else {
|
||||||
|
ch = (char)('a'+index-26);
|
||||||
|
}
|
||||||
|
str += ch;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
|
@ -86,6 +86,8 @@ public:
|
||||||
int pieces, int fastSetSize);
|
int pieces, int fastSetSize);
|
||||||
|
|
||||||
static int countBit(unsigned int);
|
static int countBit(unsigned int);
|
||||||
|
|
||||||
|
static string randomAlpha(int length);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _D_UTIL_H_
|
#endif // _D_UTIL_H_
|
||||||
|
|
|
@ -16,6 +16,7 @@ class UtilTest:public CppUnit::TestFixture {
|
||||||
// may be moved to other helper class in the future.
|
// may be moved to other helper class in the future.
|
||||||
CPPUNIT_TEST(testGetContentDispositionFilename);
|
CPPUNIT_TEST(testGetContentDispositionFilename);
|
||||||
CPPUNIT_TEST(testComputeFastSet);
|
CPPUNIT_TEST(testComputeFastSet);
|
||||||
|
CPPUNIT_TEST(testRandomAlpha);
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -32,6 +33,7 @@ public:
|
||||||
void testComputeFastSet();
|
void testComputeFastSet();
|
||||||
// may be moved to other helper class in the future.
|
// may be moved to other helper class in the future.
|
||||||
void testGetContentDispositionFilename();
|
void testGetContentDispositionFilename();
|
||||||
|
void testRandomAlpha();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -208,3 +210,7 @@ void UtilTest::testComputeFastSet() {
|
||||||
Integers ansSet2(&ans2[0], &ans2[10]);
|
Integers ansSet2(&ans2[0], &ans2[10]);
|
||||||
CPPUNIT_ASSERT(equal(fastSet.begin(), fastSet.end(), ansSet2.begin()));
|
CPPUNIT_ASSERT(equal(fastSet.begin(), fastSet.end(), ansSet2.begin()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UtilTest::testRandomAlpha() {
|
||||||
|
CPPUNIT_ASSERT_EQUAL(string("rUopvKRn"), Util::randomAlpha(8));
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue