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>
 | 
			
		||||
 | 
			
		||||
	* src/TorrentMan.cc (setupInternal1): Fixed peerId generation bug.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,6 +40,7 @@ ChokeMessage* ChokeMessage::create(const char* data, int dataLength) {
 | 
			
		|||
 | 
			
		||||
void ChokeMessage::receivedAction() {
 | 
			
		||||
  peer->peerChoking = true;
 | 
			
		||||
  peer->snubbing = false;
 | 
			
		||||
  peerInteraction->onChoked();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -101,6 +101,7 @@ bool PeerConnection::receiveMessage(char* msg, int& length) {
 | 
			
		|||
 | 
			
		||||
bool PeerConnection::receiveHandshake(char* msg, int& length) {
 | 
			
		||||
  if(!socket->isReadable(0)) {
 | 
			
		||||
    length = 0;
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
  int remain = HANDSHAKE_MESSAGE_LENGTH-resbufLength;
 | 
			
		||||
| 
						 | 
				
			
			@ -110,14 +111,19 @@ bool PeerConnection::receiveHandshake(char* msg, int& length) {
 | 
			
		|||
    // we got EOF
 | 
			
		||||
    throw new DlAbortEx(EX_EOF_FROM_PEER);
 | 
			
		||||
  }
 | 
			
		||||
  bool retval;
 | 
			
		||||
  if(remain != temp) {
 | 
			
		||||
    resbufLength += temp;
 | 
			
		||||
    return false;
 | 
			
		||||
    retval = false;
 | 
			
		||||
  } else {
 | 
			
		||||
    retval = true;
 | 
			
		||||
  }
 | 
			
		||||
  resbufLength += temp;
 | 
			
		||||
  // we got whole handshake payload
 | 
			
		||||
  resbufLength = 0;
 | 
			
		||||
 | 
			
		||||
  memcpy(msg, resbuf, HANDSHAKE_MESSAGE_LENGTH);
 | 
			
		||||
  length = HANDSHAKE_MESSAGE_LENGTH;
 | 
			
		||||
  return true;
 | 
			
		||||
  int writeLength = resbufLength > length ? length : resbufLength;
 | 
			
		||||
  memcpy(msg, resbuf, writeLength);
 | 
			
		||||
  length = writeLength;
 | 
			
		||||
  if(retval) {
 | 
			
		||||
    resbufLength = 0;
 | 
			
		||||
  }
 | 
			
		||||
  return retval;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,7 +35,8 @@ PeerInteraction::PeerInteraction(int cuid,
 | 
			
		|||
  :cuid(cuid),
 | 
			
		||||
   uploadLimit(0),
 | 
			
		||||
   torrentMan(torrentMan),
 | 
			
		||||
   peer(peer) {
 | 
			
		||||
   peer(peer),
 | 
			
		||||
   quickReplied(false) {
 | 
			
		||||
  peerConnection = new PeerConnection(cuid, socket, op);
 | 
			
		||||
  logger = LogFactory::getInstance();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -285,10 +286,19 @@ int PeerInteraction::countRequestSlot() const {
 | 
			
		|||
  return requestSlots.size();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
HandshakeMessage* PeerInteraction::receiveHandshake() {
 | 
			
		||||
HandshakeMessage* PeerInteraction::receiveHandshake(bool quickReply) {
 | 
			
		||||
  char msg[HANDSHAKE_MESSAGE_LENGTH];
 | 
			
		||||
  int msgLength = 0;
 | 
			
		||||
  if(!peerConnection->receiveHandshake(msg, msgLength)) {
 | 
			
		||||
  int msgLength = HANDSHAKE_MESSAGE_LENGTH;
 | 
			
		||||
  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;
 | 
			
		||||
  }
 | 
			
		||||
  HandshakeMessage* handshakeMessage = createHandshakeMessage(msg, msgLength);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -62,8 +62,9 @@ private:
 | 
			
		|||
  Pieces pieces;
 | 
			
		||||
  // allowed fast piece indexes that local client has sent
 | 
			
		||||
  Integers fastSet;
 | 
			
		||||
  bool quickReplied;
 | 
			
		||||
  const Logger* logger;
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  void getNewPieceAndSendInterest(int pieceNum);
 | 
			
		||||
  PeerMessage* createPeerMessage(const char* msg, int msgLength);
 | 
			
		||||
  HandshakeMessage* createHandshakeMessage(const char* msg, int msgLength);
 | 
			
		||||
| 
						 | 
				
			
			@ -116,7 +117,7 @@ public:
 | 
			
		|||
  void sendAllowedFast();
 | 
			
		||||
 | 
			
		||||
  PeerMessage* receiveMessage();
 | 
			
		||||
  HandshakeMessage* receiveHandshake();
 | 
			
		||||
  HandshakeMessage* receiveHandshake(bool quickReply = false);
 | 
			
		||||
 | 
			
		||||
  RequestMessage* createRequestMessage(int index, int blockIndex);
 | 
			
		||||
  CancelMessage* createCancelMessage(int index, int begin, int length);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -89,7 +89,8 @@ bool PeerInteractionCommand::executeInternal() {
 | 
			
		|||
    break;
 | 
			
		||||
  }
 | 
			
		||||
  case RECEIVER_WAIT_HANDSHAKE: {
 | 
			
		||||
    HandshakeMessage* handshakeMessage = peerInteraction->receiveHandshake();
 | 
			
		||||
    HandshakeMessage* handshakeMessage =
 | 
			
		||||
      peerInteraction->receiveHandshake(true);
 | 
			
		||||
    if(handshakeMessage == NULL) {
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -98,7 +99,6 @@ bool PeerInteractionCommand::executeInternal() {
 | 
			
		|||
		 peer->ipaddr.c_str(), peer->port,
 | 
			
		||||
		 handshakeMessage->toString().c_str());
 | 
			
		||||
    delete handshakeMessage;
 | 
			
		||||
    peerInteraction->sendHandshake();
 | 
			
		||||
    haveCheckTime.reset();
 | 
			
		||||
    peerInteraction->sendBitfield();
 | 
			
		||||
    peerInteraction->sendAllowedFast();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -93,6 +93,8 @@ void SocketCore::beginListen(int port) {
 | 
			
		|||
  if(listen(sockfd, 1) == -1) {
 | 
			
		||||
    throw new DlAbortEx(EX_SOCKET_LISTEN, strerror(errno));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  setNonBlockingMode();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SocketCore* SocketCore::acceptConnection() const {
 | 
			
		||||
| 
						 | 
				
			
			@ -166,16 +168,22 @@ void SocketCore::establishConnection(const string& host, int port) {
 | 
			
		|||
    freeaddrinfo(res);
 | 
			
		||||
  }
 | 
			
		||||
  // make socket non-blocking mode
 | 
			
		||||
  int flags = fcntl(sockfd, F_GETFL, 0);
 | 
			
		||||
  fcntl(sockfd, F_SETFL, flags|O_NONBLOCK);
 | 
			
		||||
  setNonBlockingMode();
 | 
			
		||||
  if(connect(sockfd, (struct sockaddr*)&sockaddr, (socklen_t)sizeof(sockaddr)) == -1 && errno != EINPROGRESS) {
 | 
			
		||||
    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 {
 | 
			
		||||
  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() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -104,6 +104,8 @@ public:
 | 
			
		|||
   */
 | 
			
		||||
  void establishConnection(const string& host, int port);
 | 
			
		||||
 | 
			
		||||
  void setNonBlockingMode() const;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Makes this socket blocking mode.
 | 
			
		||||
   */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -399,10 +399,8 @@ void TorrentMan::readFileEntry(FileEntries& fileEntries, Directory** pTopDir, co
 | 
			
		|||
 | 
			
		||||
void TorrentMan::setupInternal1(const string& metaInfoFile) {
 | 
			
		||||
  peerId = "-aria2-";
 | 
			
		||||
  int randomSize = 20-peerId.size();
 | 
			
		||||
  for(int i = 0; i < randomSize; i++) {
 | 
			
		||||
    peerId += Util::itos((int)(((double)10)*random()/(RAND_MAX+1.0)));
 | 
			
		||||
  }
 | 
			
		||||
  peerId += Util::randomAlpha(20-peerId.size());
 | 
			
		||||
  key = Util::randomAlpha(8);
 | 
			
		||||
 | 
			
		||||
  uploadLength = 0;
 | 
			
		||||
  downloadLength = 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -109,6 +109,7 @@ public:
 | 
			
		|||
  int pieces;
 | 
			
		||||
  // TODO type char* would be better
 | 
			
		||||
  string peerId;
 | 
			
		||||
  string key;
 | 
			
		||||
  string announce;
 | 
			
		||||
  string trackerId;
 | 
			
		||||
  string name;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -87,8 +87,9 @@ bool TrackerWatcherCommand::execute() {
 | 
			
		|||
      "left="+(e->torrentMan->getTotalLength()-e->torrentMan->getDownloadLength() <= 0
 | 
			
		||||
	       ? "0" : Util::llitos(e->torrentMan->getTotalLength()-e->torrentMan->getDownloadLength()))+"&"+
 | 
			
		||||
      "compact=1"+"&"+
 | 
			
		||||
      "key="+e->torrentMan->peerId+"&"+
 | 
			
		||||
      "numwant="+Util::itos(numWant);
 | 
			
		||||
      "key="+e->torrentMan->key+"&"+
 | 
			
		||||
      "numwant="+Util::itos(numWant)+"&"+
 | 
			
		||||
      "no_peer_id=1";
 | 
			
		||||
    if(!event.empty()) {
 | 
			
		||||
      url += string("&")+"event="+event;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										15
									
								
								src/Util.cc
								
								
								
								
							
							
						
						
									
										15
									
								
								src/Util.cc
								
								
								
								
							| 
						 | 
				
			
			@ -456,3 +456,18 @@ int Util::countBit(unsigned int n) {
 | 
			
		|||
 | 
			
		||||
  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);
 | 
			
		||||
 | 
			
		||||
  static int countBit(unsigned int);
 | 
			
		||||
 | 
			
		||||
  static string randomAlpha(int length);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // _D_UTIL_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,6 +16,7 @@ class UtilTest:public CppUnit::TestFixture {
 | 
			
		|||
  // may be moved to other helper class in the future.
 | 
			
		||||
  CPPUNIT_TEST(testGetContentDispositionFilename);
 | 
			
		||||
  CPPUNIT_TEST(testComputeFastSet);
 | 
			
		||||
  CPPUNIT_TEST(testRandomAlpha);
 | 
			
		||||
  CPPUNIT_TEST_SUITE_END();
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -32,6 +33,7 @@ public:
 | 
			
		|||
  void testComputeFastSet();
 | 
			
		||||
  // may be moved to other helper class in the future.
 | 
			
		||||
  void testGetContentDispositionFilename();
 | 
			
		||||
  void testRandomAlpha();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -208,3 +210,7 @@ void UtilTest::testComputeFastSet() {
 | 
			
		|||
  Integers ansSet2(&ans2[0], &ans2[10]);
 | 
			
		||||
  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