Wait for server when requesting certificate files
Summary: [Step 2 of a protocol change between desktop app and agent] The flipper agent periodically tries to connect. When it doesn't have the required certs, instead of trying to connect, it requests them from the desktop. After requesting, it just continues the loop, trying to request. The problem with that is a) the desktop can take longer than one cycle to generate and provide the certs, meaning the agent will make overlapping requests, causing confusion and it to take longer than necessary. b) the desktop can take less time than a retry cycle, but the agent will still wait before trying to connect. Fixing a) by making the agent wait for a response from the desktop before continuing attempting to reconnect. This means on the next connection attempt, it's guaranteed that the desktop is finished processing the CSR. b) remains unfixed for now, but can be dealt with separately. This changes the agent to use requestResponse, instead of fireAndForget and wait for a response from Flipper before continuing. Also added a fallback to detect old versions of Flipper/Sonar and use the oldFireAndForget method in those cases. Reviewed By: passy Differential Revision: D9179393 fbshipit-source-id: e782b303b5e441f7d6c7faa3e5acdcbfb51e5e9c
This commit is contained in:
committed by
Facebook Github Bot
parent
e3d243e23e
commit
6dd97f58ef
@@ -255,20 +255,51 @@ void SonarWebSocketImpl::requestSignedCertFromSonar() {
|
||||
|
||||
folly::dynamic message = folly::dynamic::object("method", "signCertificate")(
|
||||
"csr", csr.c_str())("destination", absoluteFilePath("").c_str());
|
||||
auto sendingCSR = sonarState_->start("Send CSR to desktop");
|
||||
sonarEventBase_->add([this, message, sendingCSR]() {
|
||||
auto gettingCert = sonarState_->start("Getting cert from desktop");
|
||||
|
||||
sonarEventBase_->add([this, message, gettingCert]() {
|
||||
client_->getRequester()
|
||||
->fireAndForget(rsocket::Payload(folly::toJson(message)))
|
||||
->subscribe([this, sendingCSR]() {
|
||||
sendingCSR->complete();
|
||||
->requestResponse(rsocket::Payload(folly::toJson(message)))
|
||||
->subscribe([this, gettingCert](rsocket::Payload p) {
|
||||
gettingCert->complete();
|
||||
SONAR_LOG("Certificate exchange complete.");
|
||||
// Disconnect after message sending is complete.
|
||||
// This will trigger a reconnect which should use the secure channel.
|
||||
// TODO: Connect immediately, without waiting for reconnect
|
||||
client_ = nullptr;
|
||||
},
|
||||
[this, message](folly::exception_wrapper e) {
|
||||
e.handle(
|
||||
[&](rsocket::ErrorWithPayload& errorWithPayload) {
|
||||
std::string errorMessage = errorWithPayload.payload.moveDataToString();
|
||||
|
||||
if (errorMessage.compare("not implemented")) {
|
||||
SONAR_LOG(("Desktop failed to provide certificates. Error from sonar desktop:\n" + errorMessage).c_str());
|
||||
} else {
|
||||
sendLegacyCertificateRequest(message);
|
||||
}
|
||||
},
|
||||
[e](...) {
|
||||
SONAR_LOG(("Error during certificate exchange:" + e.what()).c_str());
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
failedConnectionAttempts_ = 0;
|
||||
}
|
||||
|
||||
void SonarWebSocketImpl::sendLegacyCertificateRequest(folly::dynamic message) {
|
||||
// Desktop is using an old version of Flipper.
|
||||
// Fall back to fireAndForget, instead of requestResponse.
|
||||
auto sendingRequest = sonarState_->start("Sending fallback certificate request");
|
||||
client_->getRequester()
|
||||
->fireAndForget(rsocket::Payload(folly::toJson(message)))
|
||||
->subscribe([this, sendingRequest]() {
|
||||
sendingRequest->complete();
|
||||
client_ = nullptr;
|
||||
});
|
||||
}
|
||||
|
||||
std::string SonarWebSocketImpl::loadStringFromFile(std::string fileName) {
|
||||
if (!fileExists(fileName)) {
|
||||
return "";
|
||||
|
||||
@@ -65,6 +65,7 @@ class SonarWebSocketImpl : public SonarWebSocket {
|
||||
void requestSignedCertFromSonar();
|
||||
bool ensureSonarDirExists();
|
||||
bool isRunningInOwnThread();
|
||||
void sendLegacyCertificateRequest(folly::dynamic message);
|
||||
};
|
||||
|
||||
} // namespace sonar
|
||||
|
||||
Reference in New Issue
Block a user