1 /* <!-- copyright */
2 /*
3  * aria2 - The high speed download utility
4  *
5  * Copyright (C) 2006 Tatsuhiro Tsujikawa
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  *
21  * In addition, as a special exception, the copyright holders give
22  * permission to link the code of portions of this program with the
23  * OpenSSL library under certain conditions as described in each
24  * individual source file, and distribute linked combinations
25  * including the two.
26  * You must obey the GNU General Public License in all respects
27  * for all of the code used other than OpenSSL.  If you modify
28  * file(s) with this exception, you may extend this exception to your
29  * version of the file(s), but you are not obligated to do so.  If you
30  * do not wish to do so, delete this exception statement from your
31  * version.  If you delete this exception statement from all source
32  * files in the program, then also delete it here.
33  */
34 /* copyright --> */
35 #include "PeerInitiateConnectionCommand.h"
36 #include "InitiatorMSEHandshakeCommand.h"
37 #include "PeerInteractionCommand.h"
38 #include "DownloadEngine.h"
39 #include "DlAbortEx.h"
40 #include "message.h"
41 #include "prefs.h"
42 #include "SocketCore.h"
43 #include "Logger.h"
44 #include "LogFactory.h"
45 #include "Peer.h"
46 #include "BtRuntime.h"
47 #include "PeerStorage.h"
48 #include "PieceStorage.h"
49 #include "PeerConnection.h"
50 #include "RequestGroup.h"
51 #include "util.h"
52 #include "fmt.h"
53 
54 namespace aria2 {
55 
PeerInitiateConnectionCommand(cuid_t cuid,RequestGroup * requestGroup,const std::shared_ptr<Peer> & peer,DownloadEngine * e,const std::shared_ptr<BtRuntime> & btRuntime,bool mseHandshakeEnabled)56 PeerInitiateConnectionCommand::PeerInitiateConnectionCommand(
57     cuid_t cuid, RequestGroup* requestGroup, const std::shared_ptr<Peer>& peer,
58     DownloadEngine* e, const std::shared_ptr<BtRuntime>& btRuntime,
59     bool mseHandshakeEnabled)
60     : PeerAbstractCommand(cuid, peer, e),
61       requestGroup_(requestGroup),
62       btRuntime_(btRuntime),
63       mseHandshakeEnabled_(mseHandshakeEnabled)
64 {
65   btRuntime_->increaseConnections();
66   requestGroup_->increaseNumCommand();
67 }
68 
~PeerInitiateConnectionCommand()69 PeerInitiateConnectionCommand::~PeerInitiateConnectionCommand()
70 {
71   requestGroup_->decreaseNumCommand();
72   btRuntime_->decreaseConnections();
73 }
74 
executeInternal()75 bool PeerInitiateConnectionCommand::executeInternal()
76 {
77   A2_LOG_INFO(fmt(MSG_CONNECTING_TO_SERVER, getCuid(),
78                   getPeer()->getIPAddress().c_str(), getPeer()->getPort()));
79   createSocket();
80   getSocket()->establishConnection(getPeer()->getIPAddress(),
81                                    getPeer()->getPort(), false);
82   getSocket()->applyIpDscp();
83   if (mseHandshakeEnabled_) {
84     auto c = make_unique<InitiatorMSEHandshakeCommand>(
85         getCuid(), requestGroup_, getPeer(), getDownloadEngine(), btRuntime_,
86         getSocket());
87     c->setPeerStorage(peerStorage_);
88     c->setPieceStorage(pieceStorage_);
89     getDownloadEngine()->addCommand(std::move(c));
90   }
91   else {
92     getDownloadEngine()->addCommand(make_unique<PeerInteractionCommand>(
93         getCuid(), requestGroup_, getPeer(), getDownloadEngine(), btRuntime_,
94         pieceStorage_, peerStorage_, getSocket(),
95         PeerInteractionCommand::INITIATOR_SEND_HANDSHAKE));
96   }
97   return true;
98 }
99 
100 // TODO this method removed when PeerBalancerCommand is implemented
prepareForNextPeer(time_t wait)101 bool PeerInitiateConnectionCommand::prepareForNextPeer(time_t wait)
102 {
103   if (peerStorage_->isPeerAvailable() && btRuntime_->lessThanEqMinPeers()) {
104     cuid_t ncuid = getDownloadEngine()->newCUID();
105     std::shared_ptr<Peer> peer = peerStorage_->checkoutPeer(ncuid);
106     // sanity check
107     if (peer) {
108       auto command = make_unique<PeerInitiateConnectionCommand>(
109           ncuid, requestGroup_, peer, getDownloadEngine(), btRuntime_);
110       command->setPeerStorage(peerStorage_);
111       command->setPieceStorage(pieceStorage_);
112       getDownloadEngine()->addCommand(std::move(command));
113     }
114   }
115   return true;
116 }
117 
onAbort()118 void PeerInitiateConnectionCommand::onAbort()
119 {
120   peerStorage_->returnPeer(getPeer());
121 }
122 
exitBeforeExecute()123 bool PeerInitiateConnectionCommand::exitBeforeExecute()
124 {
125   return btRuntime_->isHalt();
126 }
127 
setPeerStorage(const std::shared_ptr<PeerStorage> & peerStorage)128 void PeerInitiateConnectionCommand::setPeerStorage(
129     const std::shared_ptr<PeerStorage>& peerStorage)
130 {
131   peerStorage_ = peerStorage;
132 }
133 
setPieceStorage(const std::shared_ptr<PieceStorage> & pieceStorage)134 void PeerInitiateConnectionCommand::setPieceStorage(
135     const std::shared_ptr<PieceStorage>& pieceStorage)
136 {
137   pieceStorage_ = pieceStorage;
138 }
139 
140 } // namespace aria2
141