Ejemplo n.º 1
0
wxString CTransferSocket::SetupActiveTransfer(const wxString& ip)
{
	ResetSocket();
	m_pSocketServer = CreateSocketServer();

	if (!m_pSocketServer)
	{
		m_pControlSocket->LogMessage(::Debug_Warning, _T("CreateSocketServer failed"));
		return _T("");
	}

	int error;
	int port = m_pSocketServer->GetLocalPort(error);
	if (port == -1)
	{
		ResetSocket();

		m_pControlSocket->LogMessage(::Debug_Warning, _T("GetLocalPort failed: %s"), CSocket::GetErrorDescription(error).c_str());
		return _T("");
	}

	wxString portArguments;
	if (m_pSocketServer->GetAddressFamily() == CSocket::ipv6)
	{
		portArguments = wxString::Format(_T("|2|%s|%d|"), ip.c_str(), port);
	}
	else
	{
		portArguments = ip;
		portArguments += wxString::Format(_T(",%d,%d"), port / 256, port % 256);
		portArguments.Replace(_T("."), _T(","));
	}

	return portArguments;
}
Ejemplo n.º 2
0
/*virtual*/
void
OpScopeNetwork::Reset()
{
	ResetSTP();
	if (GetConnectionState() != STATE_CLOSED)
		ResetSocket();
}
Ejemplo n.º 3
0
OpScopeNetworkServer::~OpScopeNetworkServer()
{
	State state = GetListenerState();

	ResetSocket();

	if (state == STATE_LISTENING)
		NotifyListenerClosed(this);
}
Ejemplo n.º 4
0
/* virtual */
void
OpScopeNetworkServer::OnSocketClosed(OpSocket* closing_socket)
{
	if (closing_socket != listening_socket)
		return;

	ResetSocket();

	NotifyListenerClosed(this);
}
Ejemplo n.º 5
0
void
OpScopeNetworkServer::Disconnect()
{
	BOOL was_listening = GetListenerState() == STATE_LISTENING;

	ResetSocket();

	if (was_listening)
		NotifyListenerClosed(this);
}
Ejemplo n.º 6
0
OP_STATUS
OpScopeNetworkServer::SetupListener()
{
	if (is_listening)
		ResetSocket();

	RETURN_IF_ERROR(SocketWrapper::CreateTCPSocket(&listening_socket, this, SocketWrapper::NO_WRAPPERS));
	RETURN_IF_ERROR(OpSocketAddress::Create(&sockaddr));

	OP_STATUS status;

	is_listening = TRUE;
	if (listen_port == 0)
	{
		sockaddr->FromString(listen_address.CStr());
		int port = 49152; // Dynamic/private ports: 49152-65535 <http://www.iana.org/assignments/port-numbers>
		do {
			port++;
			sockaddr->SetPort(port);
			listen_port = port;
			// See OnSocketListenError
			is_address_in_use = FALSE;
			status = listening_socket->Listen(sockaddr, 1);
		} while (is_address_in_use && port < 65535);
	}
	else
	{
		if (!listen_address.IsEmpty())
			RETURN_IF_ERROR(sockaddr->FromString(listen_address.CStr()));
		sockaddr->SetPort(listen_port);
		status = listening_socket->Listen(sockaddr, 1);
	}

	if (!is_listening)
		ResetSocket();

	if (OpStatus::IsError(status) || !is_listening)
		NotifyListeningFailure(this);
	else
		NotifyListeningSuccess(this);
	return status;
}
Ejemplo n.º 7
0
void CTransferSocket::TransferEnd(TransferEndReason reason)
{
	controlSocket_.LogMessage(MessageType::Debug_Verbose, _T("CTransferSocket::TransferEnd(%d)"), reason);

	if (m_transferEndReason != TransferEndReason::none)
		return;
	m_transferEndReason = reason;

	ResetSocket();

	engine_.send_event<CFileZillaEngineEvent>(engineTransferEnd);
}
Ejemplo n.º 8
0
void CTransferSocket::TransferEnd(enum TransferEndReason reason)
{
	m_pControlSocket->LogMessage(::Debug_Verbose, _T("CTransferSocket::TransferEnd(%d)"), reason);

	if (m_transferEndReason != none)
		return;
	m_transferEndReason = reason;

	ResetSocket();

	m_pEngine->SendEvent(engineTransferEnd);
}
Ejemplo n.º 9
0
bool CTransferSocket::SetupPassiveTransfer(wxString host, int port)
{
	ResetSocket();

	m_pSocket = new CSocket(this);

	if (m_pControlSocket->m_pProxyBackend)
	{
		m_pProxyBackend = new CProxySocket(this, m_pSocket, m_pControlSocket);

		int res = m_pProxyBackend->Handshake(m_pControlSocket->m_pProxyBackend->GetProxyType(),
											 host, port,
											 m_pControlSocket->m_pProxyBackend->GetUser(), m_pControlSocket->m_pProxyBackend->GetPass());

		if (res != EINPROGRESS)
		{
			ResetSocket();
			return false;
		}
		int error;
		host = m_pControlSocket->m_pSocket->GetPeerIP();
		port = m_pControlSocket->m_pSocket->GetRemotePort(error);
		if( host.empty() || port < 1 ) {
			m_pControlSocket->LogMessage(::Debug_Warning, _T("Could not get peer address of control connection."));
			ResetSocket();
			return false;
		}
	}

	SetSocketBufferSizes(m_pSocket);

	int res = m_pSocket->Connect(host, port);
	if (res && res != EINPROGRESS)
	{
		ResetSocket();
		return false;
	}

	return true;
}
Ejemplo n.º 10
0
std::wstring CTransferSocket::SetupActiveTransfer(std::string const& ip)
{
	ResetSocket();
	m_pSocketServer = CreateSocketServer();

	if (!m_pSocketServer) {
		controlSocket_.LogMessage(MessageType::Debug_Warning, _T("CreateSocketServer failed"));
		return std::wstring();
	}

	int error;
	int port = m_pSocketServer->GetLocalPort(error);
	if (port == -1)	{
		ResetSocket();

		controlSocket_.LogMessage(MessageType::Debug_Warning, _T("GetLocalPort failed: %s"), CSocket::GetErrorDescription(error));
		return std::wstring();
	}

	if (engine_.GetOptions().GetOptionVal(OPTION_LIMITPORTS)) {
		port += static_cast<int>(engine_.GetOptions().GetOptionVal(OPTION_LIMITPORTS_OFFSET));
		if (port <= 0 || port >= 65536) {
			controlSocket_.LogMessage(MessageType::Debug_Warning, _T("Port outside valid range"));
			return std::wstring();
		}
	}

	std::wstring portArguments;
	if (m_pSocketServer->GetAddressFamily() == CSocket::ipv6) {
		portArguments = fz::sprintf(L"|2|%s|%d|", ip, port);
	}
	else {
		portArguments = fz::to_wstring(ip);
		fz::replace_substrings(portArguments, L".", L",");
		portArguments += fz::sprintf(L",%d,%d", port / 256, port % 256);
	}

	return portArguments;
}
Ejemplo n.º 11
0
OpScopeNetwork::~OpScopeNetwork()
{
	ConnectionState constate = GetConnectionState();

	in_destruct = TRUE;
	g_main_message_handler->UnsetCallBack(this, MSG_SCOPE_PROCESS_MESSAGE);

	ResetSTP();
	if (constate != STATE_CLOSED)
		ResetSocket();

	if (constate == STATE_CONNECTED)
		NotifyConnectionClosed(this);
}
Ejemplo n.º 12
0
CTransferSocket::~CTransferSocket()
{
	remove_handler();
	if (m_transferEndReason == TransferEndReason::none) {
		m_transferEndReason = TransferEndReason::successful;
	}
	ResetSocket();

	if (m_transferMode == TransferMode::upload || m_transferMode == TransferMode::download) {
		if (ioThread_) {
			if (m_transferMode == TransferMode::download) {
				FinalizeWrite();
			}
			ioThread_->SetEventHandler(0);
		}
	}
}
Ejemplo n.º 13
0
CTransferSocket::~CTransferSocket()
{
	if (m_transferEndReason == none)
		m_transferEndReason = successful;
	ResetSocket();

	if (m_pControlSocket)
	{
		if (m_transferMode == upload || m_transferMode == download)
		{
			CFtpFileTransferOpData *pData = static_cast<CFtpFileTransferOpData *>(static_cast<CRawTransferOpData *>(m_pControlSocket->m_pCurOpData)->pOldData);
			if (pData && pData->pIOThread)
			{
				if (m_transferMode == download)
					FinalizeWrite();
				pData->pIOThread->SetEventHandler(0);
			}
		}
	}
}
Ejemplo n.º 14
0
int CHttpControlSocket::ResetOperation(int nErrorCode)
{
	if (m_pCurOpData && m_pCurOpData->opId == cmd_transfer)
	{
		CHttpFileTransferOpData *pData = static_cast<CHttpFileTransferOpData *>(m_pCurOpData);
		delete pData->pFile;
		pData->pFile = 0;
	}

	if (!m_pCurOpData || !m_pCurOpData->pNextOpData)
	{
		if (m_pBackend)
		{
			if (nErrorCode == FZ_REPLY_OK)
				LogMessage(Status, _("Disconnected from server"));
			else
				LogMessage(::Error, _("Disconnected from server"));
		}
		ResetSocket();
		m_pHttpOpData = 0;
	}

	return CControlSocket::ResetOperation(nErrorCode);
}
Ejemplo n.º 15
0
int CHttpControlSocket::ParseHeader(CHttpOpData* pData)
{
	// Parse the HTTP header.
	// We do just the neccessary parsing and silently ignore most header fields
	// Redirects are supported though if the server sends the Location field.

	for (;;)
	{
		// Find line ending
		unsigned int i = 0;
		for (i = 0; (i + 1) < m_recvBufferPos; i++)
		{
			if (m_pRecvBuffer[i] == '\r')
			{
				if (m_pRecvBuffer[i + 1] != '\n')
				{
					LogMessage(::Error, _("Malformed reply, server not sending proper line endings"));
					ResetOperation(FZ_REPLY_ERROR);
					return FZ_REPLY_ERROR;
				}
				break;
			}
		}
		if ((i + 1) >= m_recvBufferPos)
		{
			if (m_recvBufferPos == m_recvBufferLen)
			{
				// We don't support header lines larger than 4096
				LogMessage(::Error, _("Too long header line"));
				ResetOperation(FZ_REPLY_ERROR);
				return FZ_REPLY_ERROR;
			}
			return FZ_REPLY_WOULDBLOCK;
		}

		m_pRecvBuffer[i] = 0;
		const wxString& line = wxString(m_pRecvBuffer, wxConvLocal);
		if (line != _T(""))
			LogMessageRaw(Response, line);

		if (pData->m_responseCode == -1)
		{
			pData->m_responseString = line;
			if (m_recvBufferPos < 16 || memcmp(m_pRecvBuffer, "HTTP/1.", 7))
			{
				// Invalid HTTP Status-Line
				LogMessage(::Error, _("Invalid HTTP Response"));
				ResetOperation(FZ_REPLY_ERROR);
				return FZ_REPLY_ERROR;
			}

			if (m_pRecvBuffer[9] < '1' || m_pRecvBuffer[9] > '5' ||
				m_pRecvBuffer[10] < '0' || m_pRecvBuffer[10] > '9' ||
				m_pRecvBuffer[11] < '0' || m_pRecvBuffer[11] > '9')
			{
				// Invalid response code
				LogMessage(::Error, _("Invalid response code"));
				ResetOperation(FZ_REPLY_ERROR);
				return FZ_REPLY_ERROR;
			}

			pData->m_responseCode = (m_pRecvBuffer[9] - '0') * 100 + (m_pRecvBuffer[10] - '0') * 10 + m_pRecvBuffer[11] - '0';

			if (pData->m_responseCode >= 400)
			{
				// Failed request
				ResetOperation(FZ_REPLY_ERROR);
				return FZ_REPLY_ERROR;
			}

			if (pData->m_responseCode == 305)
			{
				// Unsupported redirect
				LogMessage(::Error, _("Unsupported redirect"));
				ResetOperation(FZ_REPLY_ERROR);
				return FZ_REPLY_ERROR;
			}
		}
		else
		{
			if (!i)
			{
				// End of header, data from now on

				// Redirect if neccessary
				if (pData->m_responseCode >= 300)
				{
					if (pData->m_redirectionCount++ == 5)
					{
						LogMessage(::Error, _("Too many redirects"));
						ResetOperation(FZ_REPLY_ERROR);
						return FZ_REPLY_ERROR;
					}

					ResetSocket();
					ResetHttpData(pData);

					wxString host;
					enum ServerProtocol protocol;
					int pos;
					if ((pos = pData->m_newLocation.Find(_T("://"))) != -1)
					{
						protocol = CServer::GetProtocolFromPrefix(pData->m_newLocation.Left(pos));
						host = pData->m_newLocation.Mid(pos + 3);
					}
					else
					{
						protocol = HTTP;
						host = pData->m_newLocation;
					}

					if ((pos = host.Find(_T("/"))) != -1)
						host = host.Left(pos);

					unsigned long port;
					if ((pos = host.Find(':', true)) != -1)
					{
						wxString strport = host.Mid(pos + 1);
						if (!strport.ToULong(&port) || port < 1 || port > 65535)
						{
							if (protocol == HTTPS)
								port = 443;
							else
								port = 80;
						}
						host = host.Left(pos);
					}
					else
					{
						if (protocol == HTTPS)
							port = 443;
						else
							port = 80;
					}

					if (host == _T(""))
					{
						// Unsupported redirect
						LogMessage(::Error, _("Redirection to invalid address"));
						ResetOperation(FZ_REPLY_ERROR);
						return FZ_REPLY_ERROR;
					}
					pData->m_newHostWithPort = wxString::Format(_T("%s:%d"), host.c_str(), (int)port);

					// International domain names
					host = ConvertDomainName(host);

					int res = InternalConnect(host, port, protocol == HTTPS);
					if (res == FZ_REPLY_WOULDBLOCK)
						res |= FZ_REPLY_REDIRECTED;
					return res;
				}

				pData->m_gotHeader = true;

				memmove(m_pRecvBuffer, m_pRecvBuffer + 2, m_recvBufferPos - 2);
				m_recvBufferPos -= 2;

				if (m_recvBufferPos)
				{
					int res;
					if (pData->m_transferEncoding == pData->chunked)
						res = OnChunkedData(pData);
					else
					{
						pData->m_receivedData += m_recvBufferPos;
						res = ProcessData(m_pRecvBuffer, m_recvBufferPos);
						m_recvBufferPos = 0;
					}
					return res;
				}

				return FZ_REPLY_WOULDBLOCK;
			}
			if (m_recvBufferPos > 12 && !memcmp(m_pRecvBuffer, "Location: ", 10))
			{
				pData->m_newLocation = wxString(m_pRecvBuffer + 10, wxConvLocal);
			}
			else if (m_recvBufferPos > 21 && !memcmp(m_pRecvBuffer, "Transfer-Encoding: ", 19))
			{
				if (!strcmp(m_pRecvBuffer + 19, "chunked"))
					pData->m_transferEncoding = CHttpOpData::chunked;
				else if (!strcmp(m_pRecvBuffer + 19, "identity"))
					pData->m_transferEncoding = CHttpOpData::identity;
				else
					pData->m_transferEncoding = CHttpOpData::unknown;
			}
			else if (i > 16 && !memcmp(m_pRecvBuffer, "Content-Length: ", 16))
			{
				pData->m_totalSize = 0;
				char* p = m_pRecvBuffer + 16;
				while (*p)
				{
					if (*p < '0' || *p > '9')
					{
						LogMessage(::Error, _("Malformed header: %s"), _("Invalid Content-Length"));
						ResetOperation(FZ_REPLY_ERROR);
						return FZ_REPLY_ERROR;
					}
					pData->m_totalSize = pData->m_totalSize * 10 + *p++ - '0';
				}
			}
		}

		memmove(m_pRecvBuffer, m_pRecvBuffer + i + 2, m_recvBufferPos - i - 2);
		m_recvBufferPos -= i + 2;

		if (!m_recvBufferPos)
			break;
	}

	return FZ_REPLY_WOULDBLOCK;
}
Ejemplo n.º 16
0
bool CTransferSocket::SetupPassiveTransfer(std::wstring const& host, int port)
{
	std::string ip;

	ResetSocket();

	m_pSocket = new CSocket(engine_.GetThreadPool(), this);

	if (controlSocket_.m_pProxyBackend) {
		m_pProxyBackend = new CProxySocket(this, m_pSocket, &controlSocket_);

		int res = m_pProxyBackend->Handshake(controlSocket_.m_pProxyBackend->GetProxyType(),
											 host, port,
											 controlSocket_.m_pProxyBackend->GetUser(), controlSocket_.m_pProxyBackend->GetPass());

		if (res != EINPROGRESS) {
			ResetSocket();
			return false;
		}
		int error;
		ip = controlSocket_.m_pSocket->GetPeerIP();
		port = controlSocket_.m_pSocket->GetRemotePort(error);
		if (ip.empty() || port < 1) {
			controlSocket_.LogMessage(MessageType::Debug_Warning, _T("Could not get peer address of control connection."));
			ResetSocket();
			return false;
		}
	}
	else {
		ip = fz::to_utf8(host);
	}

	SetSocketBufferSizes(m_pSocket);

	// Try to bind the source IP of the data connection to the same IP as the control connection.
	// We can do so either if 
	// 1) the destination IP of the data connection matches peer IP of the control connection or
	// 2) we are using a proxy.
	//
	// In case destination IPs of control and data connection are different, do not bind to the
	// same source.

	std::string bindAddress;
	if (m_pProxyBackend) {
		bindAddress = controlSocket_.m_pSocket->GetLocalIP();
		controlSocket_.LogMessage(MessageType::Debug_Info, _T("Binding data connection source IP to control connection source IP %s"), bindAddress);
	}
	else {
		if (controlSocket_.m_pSocket->GetPeerIP(true) == ip || controlSocket_.m_pSocket->GetPeerIP(false) == ip) {
			bindAddress = controlSocket_.m_pSocket->GetLocalIP();
			controlSocket_.LogMessage(MessageType::Debug_Info, _T("Binding data connection source IP to control connection source IP %s"), bindAddress);
		}
		else {
			controlSocket_.LogMessage(MessageType::Debug_Warning, _T("Destination IP of data connection does not match peer IP of control connection. Not binding source address of data connection."));
		}
	}

	int res = m_pSocket->Connect(fz::to_native(ip), port, CSocket::unspec, bindAddress);
	if (res && res != EINPROGRESS) {
		ResetSocket();
		return false;
	}

	return true;
}
Ejemplo n.º 17
0
int CRealControlSocket::DoClose(int nErrorCode /*=FZ_REPLY_DISCONNECTED*/)
{
	ResetSocket();

	return CControlSocket::DoClose(nErrorCode);
}