aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Vakulenko <avakulenko@google.com>2015-12-17 11:21:09 -0800
committerAlex Vakulenko <avakulenko@google.com>2015-12-17 12:03:49 -0800
commit3dae2c9f756721a220f8b59c70306031568a3ff2 (patch)
treef48420d91da97121035d9736ce17d9b82e095570
parentf1a77fcb460c16e690306ea1e296d26ba7b90da2 (diff)
downloadweaved-3dae2c9f756721a220f8b59c70306031568a3ff2.tar.gz
Fix avahi host name resolution scenarios
When host name collision is detected, avahi picks a new host name, however it fails to update any published services with the new name which leads to wrong IP address resolution for the service. As a work-around, when we detect an avahi-client restart, we just re-publish our service, so it picks up the new host name. BUG: 26237307 Change-Id: I980735890c62957e1bc433a07c319eff646c358c
-rw-r--r--buffet/avahi_mdns_client.cc44
-rw-r--r--buffet/avahi_mdns_client.h8
2 files changed, 45 insertions, 7 deletions
diff --git a/buffet/avahi_mdns_client.cc b/buffet/avahi_mdns_client.cc
index 852f59a..c60b727 100644
--- a/buffet/avahi_mdns_client.cc
+++ b/buffet/avahi_mdns_client.cc
@@ -54,8 +54,9 @@ AvahiMdnsClient::AvahiMdnsClient()
int ret = 0;
- client_.reset(avahi_client_new(avahi_threaded_poll_get(thread_pool_.get()),
- {}, nullptr, this, &ret));
+ client_.reset(avahi_client_new(
+ avahi_threaded_poll_get(thread_pool_.get()), {},
+ &AvahiMdnsClient::OnAvahiClientStateUpdate, this, &ret));
CHECK(client_) << avahi_strerror(ret);
avahi_threaded_poll_start(thread_pool_.get());
@@ -71,14 +72,17 @@ AvahiMdnsClient::~AvahiMdnsClient() {
avahi_threaded_poll_stop(thread_pool_.get());
}
-// TODO(rginda): Report errors back to the caller.
-// TODO(rginda): Support publishing more than one service.
void AvahiMdnsClient::PublishService(const std::string& service_type,
uint16_t port,
const std::vector<std::string>& txt) {
CHECK(group_);
CHECK_EQ("_privet._tcp", service_type);
+ if (prev_port_ == port && prev_service_type_ == service_type &&
+ txt_records_ == txt) {
+ return;
+ }
+
// Create txt record.
std::unique_ptr<AvahiStringList, decltype(&avahi_string_list_free)> txt_list{
nullptr, &avahi_string_list_free};
@@ -95,8 +99,9 @@ void AvahiMdnsClient::PublishService(const std::string& service_type,
}
int ret = 0;
+ txt_records_ = txt;
- if (prev_port_ == port && prev_type_ == service_type) {
+ if (prev_port_ == port && prev_service_type_ == service_type) {
ret = avahi_entry_group_update_service_txt_strlst(
group_.get(), AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, {},
service_name_.c_str(), service_type.c_str(), nullptr, txt_list.get());
@@ -104,7 +109,7 @@ void AvahiMdnsClient::PublishService(const std::string& service_type,
CHECK_GE(ret, 0) << avahi_strerror(ret);
} else {
prev_port_ = port;
- prev_type_ = service_type;
+ prev_service_type_ = service_type;
avahi_entry_group_reset(group_.get());
CHECK(avahi_entry_group_is_empty(group_.get()));
@@ -123,6 +128,33 @@ void AvahiMdnsClient::PublishService(const std::string& service_type,
void AvahiMdnsClient::StopPublishing(const std::string& service_type) {
CHECK(group_);
avahi_entry_group_reset(group_.get());
+ prev_service_type_.clear();
+ prev_port_ = 0;
+ txt_records_.clear();
+}
+
+void AvahiMdnsClient::OnAvahiClientStateUpdate(AvahiClient* s,
+ AvahiClientState state,
+ void* userdata) {
+ // Avahi service has been re-initialized (probably due to host name conflict),
+ // so we need to republish the service if it has been previously published.
+ if (state == AVAHI_CLIENT_S_RUNNING) {
+ AvahiMdnsClient* self = static_cast<AvahiMdnsClient*>(userdata);
+ self->RepublishService();
+ }
+}
+
+void AvahiMdnsClient::RepublishService() {
+ // If we don't have a service to publish, there is nothing else to do here.
+ if (prev_service_type_.empty())
+ return;
+
+ LOG(INFO) << "Republishing mDNS service";
+ std::string service_type = std::move(prev_service_type_);
+ uint16_t port = prev_port_;
+ std::vector<std::string> txt = std::move(txt_records_);
+ StopPublishing(service_type);
+ PublishService(service_type, port, txt);
}
} // namespace buffet
diff --git a/buffet/avahi_mdns_client.h b/buffet/avahi_mdns_client.h
index 405180d..6bc896e 100644
--- a/buffet/avahi_mdns_client.h
+++ b/buffet/avahi_mdns_client.h
@@ -40,9 +40,15 @@ class AvahiMdnsClient : public MdnsClient {
void StopPublishing(const std::string& service_type) override;
private:
+ static void OnAvahiClientStateUpdate(AvahiClient* s,
+ AvahiClientState state,
+ void* userdata);
+ void RepublishService();
+
uint16_t prev_port_{0};
- std::string prev_type_;
+ std::string prev_service_type_;
std::string service_name_;
+ std::vector<std::string> txt_records_;
std::unique_ptr<AvahiThreadedPoll, decltype(&avahi_threaded_poll_free)>
thread_pool_{nullptr, &avahi_threaded_poll_free};
std::unique_ptr< ::AvahiClient, decltype(&avahi_client_free)> client_{