|
@@ -126,9 +126,9 @@ bool FtpNegotiationCommand::executeInternal() {
|
|
return true;
|
|
return true;
|
|
} else if(sequence_ == SEQ_FILE_PREPARATION) {
|
|
} else if(sequence_ == SEQ_FILE_PREPARATION) {
|
|
if(getOption()->getAsBool(PREF_FTP_PASV)) {
|
|
if(getOption()->getAsBool(PREF_FTP_PASV)) {
|
|
- sequence_ = SEQ_SEND_PASV;
|
|
|
|
|
|
+ sequence_ = SEQ_PREPARE_PASV;
|
|
} else {
|
|
} else {
|
|
- sequence_ = SEQ_PREPARE_SERVER_SOCKET;
|
|
|
|
|
|
+ sequence_ = SEQ_PREPARE_PORT;
|
|
}
|
|
}
|
|
return false;
|
|
return false;
|
|
} else if(sequence_ == SEQ_EXIT) {
|
|
} else if(sequence_ == SEQ_EXIT) {
|
|
@@ -391,9 +391,9 @@ bool FtpNegotiationCommand::onFileSizeDetermined(uint64_t totalLength)
|
|
if(totalLength == 0) {
|
|
if(totalLength == 0) {
|
|
|
|
|
|
if(getOption()->getAsBool(PREF_FTP_PASV)) {
|
|
if(getOption()->getAsBool(PREF_FTP_PASV)) {
|
|
- sequence_ = SEQ_SEND_PASV;
|
|
|
|
|
|
+ sequence_ = SEQ_PREPARE_PASV;
|
|
} else {
|
|
} else {
|
|
- sequence_ = SEQ_PREPARE_SERVER_SOCKET;
|
|
|
|
|
|
+ sequence_ = SEQ_PREPARE_PORT;
|
|
}
|
|
}
|
|
|
|
|
|
if(getOption()->getAsBool(PREF_DRY_RUN)) {
|
|
if(getOption()->getAsBool(PREF_DRY_RUN)) {
|
|
@@ -514,9 +514,9 @@ bool FtpNegotiationCommand::recvSize() {
|
|
// wrong file to be downloaded if user-specified URL is wrong.
|
|
// wrong file to be downloaded if user-specified URL is wrong.
|
|
}
|
|
}
|
|
if(getOption()->getAsBool(PREF_FTP_PASV)) {
|
|
if(getOption()->getAsBool(PREF_FTP_PASV)) {
|
|
- sequence_ = SEQ_SEND_PASV;
|
|
|
|
|
|
+ sequence_ = SEQ_PREPARE_PASV;
|
|
} else {
|
|
} else {
|
|
- sequence_ = SEQ_PREPARE_SERVER_SOCKET;
|
|
|
|
|
|
+ sequence_ = SEQ_PREPARE_PORT;
|
|
}
|
|
}
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
@@ -526,6 +526,22 @@ void FtpNegotiationCommand::afterFileAllocation()
|
|
setReadCheckSocket(getSocket());
|
|
setReadCheckSocket(getSocket());
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+bool FtpNegotiationCommand::preparePort() {
|
|
|
|
+ afterFileAllocation();
|
|
|
|
+ if(getSocket()->getAddressFamily() == AF_INET6) {
|
|
|
|
+ sequence_ = SEQ_PREPARE_SERVER_SOCKET_EPRT;
|
|
|
|
+ } else {
|
|
|
|
+ sequence_ = SEQ_PREPARE_SERVER_SOCKET;
|
|
|
|
+ }
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+bool FtpNegotiationCommand::prepareServerSocketEprt() {
|
|
|
|
+ serverSocket_ = ftp_->createServerSocket();
|
|
|
|
+ sequence_ = SEQ_SEND_EPRT;
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
bool FtpNegotiationCommand::prepareServerSocket()
|
|
bool FtpNegotiationCommand::prepareServerSocket()
|
|
{
|
|
{
|
|
serverSocket_ = ftp_->createServerSocket();
|
|
serverSocket_ = ftp_->createServerSocket();
|
|
@@ -533,8 +549,30 @@ bool FtpNegotiationCommand::prepareServerSocket()
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+bool FtpNegotiationCommand::sendEprt() {
|
|
|
|
+ if(ftp_->sendEprt(serverSocket_)) {
|
|
|
|
+ disableWriteCheckSocket();
|
|
|
|
+ sequence_ = SEQ_RECV_EPRT;
|
|
|
|
+ } else {
|
|
|
|
+ setWriteCheckSocket(getSocket());
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+bool FtpNegotiationCommand::recvEprt() {
|
|
|
|
+ unsigned int status = ftp_->receiveResponse();
|
|
|
|
+ if(status == 0) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ if(status == 200) {
|
|
|
|
+ sequence_ = SEQ_SEND_REST;
|
|
|
|
+ } else {
|
|
|
|
+ sequence_ = SEQ_PREPARE_SERVER_SOCKET;
|
|
|
|
+ }
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
bool FtpNegotiationCommand::sendPort() {
|
|
bool FtpNegotiationCommand::sendPort() {
|
|
- afterFileAllocation();
|
|
|
|
if(ftp_->sendPort(serverSocket_)) {
|
|
if(ftp_->sendPort(serverSocket_)) {
|
|
disableWriteCheckSocket();
|
|
disableWriteCheckSocket();
|
|
sequence_ = SEQ_RECV_PORT;
|
|
sequence_ = SEQ_RECV_PORT;
|
|
@@ -556,8 +594,45 @@ bool FtpNegotiationCommand::recvPort() {
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
-bool FtpNegotiationCommand::sendPasv() {
|
|
|
|
|
|
+bool FtpNegotiationCommand::preparePasv() {
|
|
afterFileAllocation();
|
|
afterFileAllocation();
|
|
|
|
+ if(getSocket()->getAddressFamily() == AF_INET6) {
|
|
|
|
+ sequence_ = SEQ_SEND_EPSV;
|
|
|
|
+ } else {
|
|
|
|
+ sequence_ = SEQ_SEND_PASV;
|
|
|
|
+ }
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+bool FtpNegotiationCommand::sendEpsv() {
|
|
|
|
+ if(ftp_->sendEpsv()) {
|
|
|
|
+ disableWriteCheckSocket();
|
|
|
|
+ sequence_ = SEQ_RECV_EPSV;
|
|
|
|
+ } else {
|
|
|
|
+ setWriteCheckSocket(getSocket());
|
|
|
|
+ }
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+bool FtpNegotiationCommand::recvEpsv() {
|
|
|
|
+ uint16_t port;
|
|
|
|
+ unsigned int status = ftp_->receiveEpsvResponse(port);
|
|
|
|
+ if(status == 0) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ if(status == 229) {
|
|
|
|
+ std::pair<std::string, uint16_t> peerInfo;
|
|
|
|
+ getSocket()->getPeerInfo(peerInfo);
|
|
|
|
+ peerInfo.second = port;
|
|
|
|
+ dataConnAddr_ = peerInfo;
|
|
|
|
+ return preparePasvConnect();
|
|
|
|
+ } else {
|
|
|
|
+ sequence_ = SEQ_SEND_PASV;
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+bool FtpNegotiationCommand::sendPasv() {
|
|
if(ftp_->sendPasv()) {
|
|
if(ftp_->sendPasv()) {
|
|
disableWriteCheckSocket();
|
|
disableWriteCheckSocket();
|
|
sequence_ = SEQ_RECV_PASV;
|
|
sequence_ = SEQ_RECV_PASV;
|
|
@@ -576,20 +651,26 @@ bool FtpNegotiationCommand::recvPasv() {
|
|
if(status != 227) {
|
|
if(status != 227) {
|
|
throw DL_ABORT_EX(StringFormat(EX_BAD_STATUS, status).str());
|
|
throw DL_ABORT_EX(StringFormat(EX_BAD_STATUS, status).str());
|
|
}
|
|
}
|
|
- // TODO Should we check to see that dest.first is not in noProxy list?
|
|
|
|
|
|
+ dataConnAddr_ = dest;
|
|
|
|
+
|
|
|
|
+ return preparePasvConnect();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+bool FtpNegotiationCommand::preparePasvConnect() {
|
|
|
|
+ // TODO Should we check to see that dataConnAddr_.first is not in
|
|
|
|
+ // noProxy list?
|
|
if(isProxyDefined()) {
|
|
if(isProxyDefined()) {
|
|
- dataConnAddr_ = dest;
|
|
|
|
sequence_ = SEQ_RESOLVE_PROXY;
|
|
sequence_ = SEQ_RESOLVE_PROXY;
|
|
return true;
|
|
return true;
|
|
} else {
|
|
} else {
|
|
// make a data connection to the server.
|
|
// make a data connection to the server.
|
|
if(getLogger()->info()) {
|
|
if(getLogger()->info()) {
|
|
getLogger()->info(MSG_CONNECTING_TO_SERVER, util::itos(getCuid()).c_str(),
|
|
getLogger()->info(MSG_CONNECTING_TO_SERVER, util::itos(getCuid()).c_str(),
|
|
- dest.first.c_str(),
|
|
|
|
- dest.second);
|
|
|
|
|
|
+ dataConnAddr_.first.c_str(),
|
|
|
|
+ dataConnAddr_.second);
|
|
}
|
|
}
|
|
dataSocket_.reset(new SocketCore());
|
|
dataSocket_.reset(new SocketCore());
|
|
- dataSocket_->establishConnection(dest.first, dest.second);
|
|
|
|
|
|
+ dataSocket_->establishConnection(dataConnAddr_.first, dataConnAddr_.second);
|
|
disableReadCheckSocket();
|
|
disableReadCheckSocket();
|
|
setWriteCheckSocket(dataSocket_);
|
|
setWriteCheckSocket(dataSocket_);
|
|
sequence_ = SEQ_SEND_REST_PASV;
|
|
sequence_ = SEQ_SEND_REST_PASV;
|
|
@@ -691,6 +772,12 @@ bool FtpNegotiationCommand::recvTunnelResponse()
|
|
|
|
|
|
bool FtpNegotiationCommand::sendRestPasv(const SharedHandle<Segment>& segment) {
|
|
bool FtpNegotiationCommand::sendRestPasv(const SharedHandle<Segment>& segment) {
|
|
//dataSocket_->setBlockingMode();
|
|
//dataSocket_->setBlockingMode();
|
|
|
|
+ // Check connection is made properly
|
|
|
|
+ if(dataSocket_->isReadable(0)) {
|
|
|
|
+ std::string error = dataSocket_->getSocketError();
|
|
|
|
+ throw DL_ABORT_EX
|
|
|
|
+ (StringFormat(MSG_ESTABLISHING_CONNECTION_FAILED, error.c_str()).str());
|
|
|
|
+ }
|
|
setReadCheckSocket(getSocket());
|
|
setReadCheckSocket(getSocket());
|
|
disableWriteCheckSocket();
|
|
disableWriteCheckSocket();
|
|
return sendRest(segment);
|
|
return sendRest(segment);
|
|
@@ -803,12 +890,26 @@ bool FtpNegotiationCommand::processSequence
|
|
return sendSize();
|
|
return sendSize();
|
|
case SEQ_RECV_SIZE:
|
|
case SEQ_RECV_SIZE:
|
|
return recvSize();
|
|
return recvSize();
|
|
|
|
+ case SEQ_PREPARE_PORT:
|
|
|
|
+ return preparePort();
|
|
|
|
+ case SEQ_PREPARE_SERVER_SOCKET_EPRT:
|
|
|
|
+ return prepareServerSocketEprt();
|
|
|
|
+ case SEQ_SEND_EPRT:
|
|
|
|
+ return sendEprt();
|
|
|
|
+ case SEQ_RECV_EPRT:
|
|
|
|
+ return recvEprt();
|
|
case SEQ_PREPARE_SERVER_SOCKET:
|
|
case SEQ_PREPARE_SERVER_SOCKET:
|
|
return prepareServerSocket();
|
|
return prepareServerSocket();
|
|
case SEQ_SEND_PORT:
|
|
case SEQ_SEND_PORT:
|
|
return sendPort();
|
|
return sendPort();
|
|
case SEQ_RECV_PORT:
|
|
case SEQ_RECV_PORT:
|
|
return recvPort();
|
|
return recvPort();
|
|
|
|
+ case SEQ_PREPARE_PASV:
|
|
|
|
+ return preparePasv();
|
|
|
|
+ case SEQ_SEND_EPSV:
|
|
|
|
+ return sendEpsv();
|
|
|
|
+ case SEQ_RECV_EPSV:
|
|
|
|
+ return recvEpsv();
|
|
case SEQ_SEND_PASV:
|
|
case SEQ_SEND_PASV:
|
|
return sendPasv();
|
|
return sendPasv();
|
|
case SEQ_RECV_PASV:
|
|
case SEQ_RECV_PASV:
|