Index: remoting/host/heartbeat_sender.cc |
diff --git a/remoting/host/heartbeat_sender.cc b/remoting/host/heartbeat_sender.cc |
index fa234e35ae6039ec63c644b4667de1bb9e7de54c..4ad3d927c868b7a8b9f4ff6959594c576c138037 100644 |
--- a/remoting/host/heartbeat_sender.cc |
+++ b/remoting/host/heartbeat_sender.cc |
@@ -6,70 +6,111 @@ |
#include "base/logging.h" |
#include "base/message_loop.h" |
+#include "base/string_util.h" |
+#include "base/time.h" |
#include "remoting/base/constants.h" |
#include "remoting/host/host_config.h" |
+#include "remoting/host/host_key_pair.h" |
#include "remoting/jingle_glue/iq_request.h" |
#include "remoting/jingle_glue/jingle_client.h" |
#include "remoting/jingle_glue/jingle_thread.h" |
-#include "talk/xmpp/constants.h" |
-#include "talk/xmllite/xmlelement.h" |
+#include "third_party/libjingle/source/talk/xmllite/xmlelement.h" |
+#include "third_party/libjingle/source/talk/xmpp/constants.h" |
namespace remoting { |
namespace { |
-const char * const kChromotingNamespace = "google:remoting"; |
-const buzz::QName kHeartbeatQuery(true, kChromotingNamespace, "heartbeat"); |
-const buzz::QName kHostIdAttr(true, kChromotingNamespace, "hostid"); |
+const char kHeartbeatQueryTag[] = "heartbeat"; |
+const char kHostIdAttr[] = "hostid"; |
+const char kHeartbeatSignatureTag[] = "signature"; |
+const char kSignatureTimeAttr[] = "time"; |
// TODO(sergeyu): Make this configurable by the cloud. |
const int64 kHeartbeatPeriodMs = 5 * 60 * 1000; // 5 minutes. |
} |
HeartbeatSender::HeartbeatSender() |
- : started_(false) { |
+ : state_(CREATED) { |
} |
-void HeartbeatSender::Start(MutableHostConfig* config, JingleClient* jingle_client) { |
- DCHECK(jingle_client); |
- DCHECK(!started_); |
+HeartbeatSender::~HeartbeatSender() { |
+ DCHECK(state_ != STARTED); |
awong
2010/08/02 19:53:49
Should this be a positive filter? That is, specif
Sergey Ulanov
2010/08/03 02:10:39
Done.
|
+} |
- started_ = true; |
+bool HeartbeatSender::Init(MutableHostConfig* config, |
+ JingleClient* jingle_client) { |
+ DCHECK(jingle_client); |
+ DCHECK(state_ == CREATED); |
jingle_client_ = jingle_client; |
config_ = config; |
if (!config_->GetString(kHostIdConfigPath, &host_id_)) { |
LOG(ERROR) << "host_id is not defined in the config."; |
- return; |
+ return false; |
} |
+ key_pair_ = new HostKeyPair(); |
+ if (!key_pair_->Load(config)) { |
+ return false; |
+ } |
+ |
+ state_ = INITIALIZED; |
+ |
+ return true; |
+} |
+ |
+void HeartbeatSender::Start() { |
+ DCHECK(state_ == INITIALIZED); |
+ state_ = STARTED; |
jingle_client_->message_loop()->PostTask( |
FROM_HERE, NewRunnableMethod(this, &HeartbeatSender::DoStart)); |
} |
+void HeartbeatSender::Stop() { |
+ DCHECK(state_ == STARTED); |
+ state_ = STOPPED; |
+ jingle_client_->message_loop()->PostTask( |
+ FROM_HERE, NewRunnableMethod(this, &HeartbeatSender::DoStop)); |
+} |
+ |
void HeartbeatSender::DoStart() { |
DCHECK(MessageLoop::current() == jingle_client_->message_loop()); |
- request_.reset(new IqRequest(jingle_client_)); |
+ request_.reset(jingle_client_->CreateIqRequest()); |
request_->set_callback(NewCallback(this, &HeartbeatSender::ProcessResponse)); |
jingle_client_->message_loop()->PostTask( |
FROM_HERE, NewRunnableMethod(this, &HeartbeatSender::DoSendStanza)); |
} |
-void HeartbeatSender::DoSendStanza() { |
+void HeartbeatSender::DoStop() { |
DCHECK(MessageLoop::current() == jingle_client_->message_loop()); |
- LOG(INFO) << "Sending heartbeat stanza to " << kChromotingBotJid; |
+ request_.reset(NULL); |
+} |
+ |
+void HeartbeatSender::DoSendStanza() { |
+ if (state_ == STARTED) { |
+ // |jingle_client_| may be already destroyed if |state_| is set to |
+ // |STOPPED|, so don't touch it here unless we are in |STARTED| state. |
+ DCHECK(MessageLoop::current() == jingle_client_->message_loop()); |
+ |
+ LOG(INFO) << "Sending heartbeat stanza to " << kChromotingBotJid; |
+ |
+ buzz::XmlElement* query = new buzz::XmlElement( |
+ buzz::QName(kChromotingXmlNamespace, kHeartbeatQueryTag)); |
+ query->AddAttr(buzz::QName(kChromotingXmlNamespace, kHostIdAttr), host_id_); |
+ |
+ query->AddElement(CreateSignature(jingle_client_->GetFullJid())); |
- buzz::XmlElement* stanza = new buzz::XmlElement(kHeartbeatQuery); |
- stanza->AddAttr(kHostIdAttr, host_id_); |
- request_->SendIq(buzz::STR_SET, kChromotingBotJid, stanza); |
+ request_->SendIq(buzz::STR_SET, kChromotingBotJid, query); |
- // Schedule next heartbeat. |
- jingle_client_->message_loop()->PostDelayedTask( |
- FROM_HERE, NewRunnableMethod(this, &HeartbeatSender::DoSendStanza), |
- kHeartbeatPeriodMs); |
+ // Schedule next heartbeat. |
+ jingle_client_->message_loop()->PostDelayedTask( |
+ FROM_HERE, NewRunnableMethod(this, &HeartbeatSender::DoSendStanza), |
+ kHeartbeatPeriodMs); |
+ } |
} |
void HeartbeatSender::ProcessResponse(const buzz::XmlElement* response) { |
@@ -79,4 +120,20 @@ void HeartbeatSender::ProcessResponse(const buzz::XmlElement* response) { |
} |
} |
+buzz::XmlElement* HeartbeatSender::CreateSignature(const std::string& jid) { |
awong
2010/08/02 19:53:49
Somewhere, probably at the top of the .h file for
Sergey Ulanov
2010/08/03 02:10:39
Added info to the .h file. BTW this info is alread
awong
2010/08/03 19:21:02
ah...forgot to look there. :) More reason to put
|
+ buzz::XmlElement* signature_tag = new buzz::XmlElement( |
+ buzz::QName(kChromotingXmlNamespace, kHeartbeatSignatureTag)); |
+ |
+ int64 time = static_cast<int64>(base::Time::Now().ToDoubleT()); |
+ std::string time_str(Int64ToString(time)); |
+ signature_tag->AddAttr( |
+ buzz::QName(kChromotingXmlNamespace, kSignatureTimeAttr), time_str); |
+ |
+ std::string message = jid + ' ' + time_str; |
awong
2010/08/02 19:53:49
So we only sign the jid + time_str?
Sergey Ulanov
2010/08/03 02:10:39
Yes. Do we need to sign anything else?
awong
2010/08/03 19:21:02
Don't think so, but I was expecting to see somethi
Sergey Ulanov
2010/08/04 01:41:12
Yeah, that was my firth thought too, but the probl
|
+ std::string signature(key_pair_->GetSignature(message)); |
+ signature_tag->AddText(signature); |
+ |
+ return signature_tag; |
+} |
+ |
} // namespace remoting |