| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/local_discovery/service_discovery_client_mac.h" | 5 #include "chrome/browser/local_discovery/service_discovery_client_mac.h" |
| 6 | 6 |
| 7 #import <Foundation/Foundation.h> | 7 #import <Foundation/Foundation.h> |
| 8 #import <arpa/inet.h> | 8 #import <arpa/inet.h> |
| 9 #import <net/if_dl.h> | 9 #import <net/if_dl.h> |
| 10 | 10 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 | 76 |
| 77 return !domain->empty() && | 77 return !domain->empty() && |
| 78 !type->empty() && | 78 !type->empty() && |
| 79 (!is_service_name || !instance->empty()); | 79 (!is_service_name || !instance->empty()); |
| 80 } | 80 } |
| 81 | 81 |
| 82 void ParseTxtRecord(NSData* record, std::vector<std::string>* output) { | 82 void ParseTxtRecord(NSData* record, std::vector<std::string>* output) { |
| 83 if (record == nil || [record length] <= 1) | 83 if (record == nil || [record length] <= 1) |
| 84 return; | 84 return; |
| 85 | 85 |
| 86 const uint8* record_bytes = reinterpret_cast<const uint8*>([record bytes]); | 86 VLOG(1) << "ParseTxtRecord: " << [record length]; |
| 87 const uint8* const record_end = record_bytes + [record length]; | 87 |
| 88 const char* record_bytes = reinterpret_cast<const char*>([record bytes]); |
| 89 const char* const record_end = record_bytes + [record length]; |
| 88 // TODO(justinlin): More strict bounds checking. | 90 // TODO(justinlin): More strict bounds checking. |
| 89 while (record_bytes < record_end) { | 91 while (record_bytes < record_end) { |
| 90 uint8 size = *record_bytes++; | 92 uint8 size = *record_bytes++; |
| 91 if (size <= 0) | 93 if (size <= 0) |
| 92 continue; | 94 continue; |
| 93 | 95 |
| 94 if (record_bytes + size <= record_end) { | 96 if (record_bytes + size <= record_end) { |
| 97 VLOG(1) << "TxtRecord: " |
| 98 << std::string(record_bytes, static_cast<size_t>(size)); |
| 95 output->push_back( | 99 output->push_back( |
| 96 [[[NSString alloc] initWithBytes:record_bytes | 100 [[[NSString alloc] initWithBytes:record_bytes |
| 97 length:size | 101 length:size |
| 98 encoding:NSUTF8StringEncoding] UTF8String]); | 102 encoding:NSUTF8StringEncoding] UTF8String]); |
| 99 } | 103 } |
| 100 record_bytes += size; | 104 record_bytes += size; |
| 101 } | 105 } |
| 102 } | 106 } |
| 103 | 107 |
| 104 } // namespace | 108 } // namespace |
| 105 | 109 |
| 106 ServiceDiscoveryClientMac::ServiceDiscoveryClientMac() {} | 110 ServiceDiscoveryClientMac::ServiceDiscoveryClientMac() {} |
| 107 ServiceDiscoveryClientMac::~ServiceDiscoveryClientMac() {} | 111 ServiceDiscoveryClientMac::~ServiceDiscoveryClientMac() {} |
| 108 | 112 |
| 109 scoped_ptr<ServiceWatcher> ServiceDiscoveryClientMac::CreateServiceWatcher( | 113 scoped_ptr<ServiceWatcher> ServiceDiscoveryClientMac::CreateServiceWatcher( |
| 110 const std::string& service_type, | 114 const std::string& service_type, |
| 111 const ServiceWatcher::UpdatedCallback& callback) { | 115 const ServiceWatcher::UpdatedCallback& callback) { |
| 116 VLOG(1) << "CreateServiceWatcher: " << service_type; |
| 112 return scoped_ptr<ServiceWatcher>(new ServiceWatcherImplMac(service_type, | 117 return scoped_ptr<ServiceWatcher>(new ServiceWatcherImplMac(service_type, |
| 113 callback)); | 118 callback)); |
| 114 } | 119 } |
| 115 | 120 |
| 116 scoped_ptr<ServiceResolver> ServiceDiscoveryClientMac::CreateServiceResolver( | 121 scoped_ptr<ServiceResolver> ServiceDiscoveryClientMac::CreateServiceResolver( |
| 117 const std::string& service_name, | 122 const std::string& service_name, |
| 118 const ServiceResolver::ResolveCompleteCallback& callback) { | 123 const ServiceResolver::ResolveCompleteCallback& callback) { |
| 124 VLOG(1) << "CreateServiceResolver: " << service_name; |
| 119 return scoped_ptr<ServiceResolver>(new ServiceResolverImplMac(service_name, | 125 return scoped_ptr<ServiceResolver>(new ServiceResolverImplMac(service_name, |
| 120 callback)); | 126 callback)); |
| 121 } | 127 } |
| 122 | 128 |
| 123 scoped_ptr<LocalDomainResolver> | 129 scoped_ptr<LocalDomainResolver> |
| 124 ServiceDiscoveryClientMac::CreateLocalDomainResolver( | 130 ServiceDiscoveryClientMac::CreateLocalDomainResolver( |
| 125 const std::string& domain, | 131 const std::string& domain, |
| 126 net::AddressFamily address_family, | 132 net::AddressFamily address_family, |
| 127 const LocalDomainResolver::IPAddressCallback& callback) { | 133 const LocalDomainResolver::IPAddressCallback& callback) { |
| 128 NOTIMPLEMENTED(); // TODO(justinlin): Implement. | 134 NOTIMPLEMENTED(); // TODO(justinlin): Implement. |
| 135 VLOG(1) << "CreateLocalDomainResolver: " << domain; |
| 129 return scoped_ptr<LocalDomainResolver>(); | 136 return scoped_ptr<LocalDomainResolver>(); |
| 130 } | 137 } |
| 131 | 138 |
| 132 ServiceWatcherImplMac::ServiceWatcherImplMac( | 139 ServiceWatcherImplMac::ServiceWatcherImplMac( |
| 133 const std::string& service_type, | 140 const std::string& service_type, |
| 134 const ServiceWatcher::UpdatedCallback& callback) | 141 const ServiceWatcher::UpdatedCallback& callback) |
| 135 : service_type_(service_type), callback_(callback), started_(false) {} | 142 : service_type_(service_type), callback_(callback), started_(false) {} |
| 136 | 143 |
| 137 ServiceWatcherImplMac::~ServiceWatcherImplMac() {} | 144 ServiceWatcherImplMac::~ServiceWatcherImplMac() {} |
| 138 | 145 |
| 139 void ServiceWatcherImplMac::Start() { | 146 void ServiceWatcherImplMac::Start() { |
| 140 DCHECK(!started_); | 147 DCHECK(!started_); |
| 148 VLOG(1) << "ServiceWatcherImplMac::Start"; |
| 141 delegate_.reset([[NetServiceBrowserDelegate alloc] | 149 delegate_.reset([[NetServiceBrowserDelegate alloc] |
| 142 initWithServiceWatcher:this]); | 150 initWithServiceWatcher:this]); |
| 143 browser_.reset([[NSNetServiceBrowser alloc] init]); | 151 browser_.reset([[NSNetServiceBrowser alloc] init]); |
| 144 [browser_ setDelegate:delegate_]; | 152 [browser_ setDelegate:delegate_]; |
| 145 started_ = true; | 153 started_ = true; |
| 146 } | 154 } |
| 147 | 155 |
| 148 // TODO(justinlin): Implement flushing DNS cache to respect parameter. | 156 // TODO(justinlin): Implement flushing DNS cache to respect parameter. |
| 149 void ServiceWatcherImplMac::DiscoverNewServices(bool force_update) { | 157 void ServiceWatcherImplMac::DiscoverNewServices(bool force_update) { |
| 150 DCHECK(started_); | 158 DCHECK(started_); |
| 151 | 159 VLOG(1) << "ServiceWatcherImplMac::DiscoverNewServices"; |
| 152 std::string instance; | 160 std::string instance; |
| 153 std::string type; | 161 std::string type; |
| 154 std::string domain; | 162 std::string domain; |
| 155 | 163 |
| 156 if (!ExtractServiceInfo(service_type_, false, &instance, &type, &domain)) | 164 if (!ExtractServiceInfo(service_type_, false, &instance, &type, &domain)) |
| 157 return; | 165 return; |
| 158 | 166 |
| 159 DCHECK(instance.empty()); | 167 DCHECK(instance.empty()); |
| 160 DVLOG(1) << "Listening for service type '" << type | 168 DVLOG(1) << "Listening for service type '" << type |
| 161 << "' on domain '" << domain << "'"; | 169 << "' on domain '" << domain << "'"; |
| 162 | 170 |
| 163 [browser_ searchForServicesOfType:[NSString stringWithUTF8String:type.c_str()] | 171 [browser_ searchForServicesOfType:[NSString stringWithUTF8String:type.c_str()] |
| 164 inDomain:[NSString stringWithUTF8String:domain.c_str()]]; | 172 inDomain:[NSString stringWithUTF8String:domain.c_str()]]; |
| 165 } | 173 } |
| 166 | 174 |
| 167 void ServiceWatcherImplMac::SetActivelyRefreshServices( | 175 void ServiceWatcherImplMac::SetActivelyRefreshServices( |
| 168 bool actively_refresh_services) { | 176 bool actively_refresh_services) { |
| 169 DCHECK(started_); | 177 DCHECK(started_); |
| 178 VLOG(1) << "ServiceWatcherImplMac::SetActivelyRefreshServices"; |
| 170 // TODO(noamsml): Implement this method. | 179 // TODO(noamsml): Implement this method. |
| 171 } | 180 } |
| 172 | 181 |
| 173 std::string ServiceWatcherImplMac::GetServiceType() const { | 182 std::string ServiceWatcherImplMac::GetServiceType() const { |
| 174 return service_type_; | 183 return service_type_; |
| 175 } | 184 } |
| 176 | 185 |
| 177 void ServiceWatcherImplMac::OnServicesUpdate(ServiceWatcher::UpdateType update, | 186 void ServiceWatcherImplMac::OnServicesUpdate(ServiceWatcher::UpdateType update, |
| 178 const std::string& service) { | 187 const std::string& service) { |
| 188 VLOG(1) << "ServiceWatcherImplMac::OnServicesUpdate: " |
| 189 << service + "." + service_type_; |
| 179 callback_.Run(update, service + "." + service_type_); | 190 callback_.Run(update, service + "." + service_type_); |
| 180 } | 191 } |
| 181 | 192 |
| 182 ServiceResolverImplMac::ServiceResolverImplMac( | 193 ServiceResolverImplMac::ServiceResolverImplMac( |
| 183 const std::string& service_name, | 194 const std::string& service_name, |
| 184 const ServiceResolver::ResolveCompleteCallback& callback) | 195 const ServiceResolver::ResolveCompleteCallback& callback) |
| 185 : service_name_(service_name), callback_(callback), has_resolved_(false) { | 196 : service_name_(service_name), callback_(callback), has_resolved_(false) { |
| 186 std::string instance; | 197 std::string instance; |
| 187 std::string type; | 198 std::string type; |
| 188 std::string domain; | 199 std::string domain; |
| 189 | 200 |
| 190 if (ExtractServiceInfo(service_name, true, &instance, &type, &domain)) { | 201 if (ExtractServiceInfo(service_name, true, &instance, &type, &domain)) { |
| 202 VLOG(1) << "ServiceResolverImplMac::ServiceResolverImplMac: Success"; |
| 191 delegate_.reset([[NetServiceDelegate alloc] initWithServiceResolver:this]); | 203 delegate_.reset([[NetServiceDelegate alloc] initWithServiceResolver:this]); |
| 192 service_.reset( | 204 service_.reset( |
| 193 [[NSNetService alloc] | 205 [[NSNetService alloc] |
| 194 initWithDomain:[[NSString alloc] initWithUTF8String:domain.c_str()] | 206 initWithDomain:[[NSString alloc] initWithUTF8String:domain.c_str()] |
| 195 type:[[NSString alloc] initWithUTF8String:type.c_str()] | 207 type:[[NSString alloc] initWithUTF8String:type.c_str()] |
| 196 name:[[NSString alloc] initWithUTF8String:instance.c_str()]]); | 208 name:[[NSString alloc] initWithUTF8String:instance.c_str()]]); |
| 197 [service_ setDelegate:delegate_]; | 209 [service_ setDelegate:delegate_]; |
| 198 } | 210 } |
| 211 VLOG(1) << "ServiceResolverImplMac::ServiceResolverImplMac: " |
| 212 << service_name |
| 213 << ", instance: " << instance |
| 214 << ", type: " << type |
| 215 << ", domain: " << domain; |
| 199 } | 216 } |
| 200 | 217 |
| 201 ServiceResolverImplMac::~ServiceResolverImplMac() {} | 218 ServiceResolverImplMac::~ServiceResolverImplMac() {} |
| 202 | 219 |
| 203 void ServiceResolverImplMac::StartResolving() { | 220 void ServiceResolverImplMac::StartResolving() { |
| 204 if (!service_.get()) | 221 if (!service_.get()) |
| 205 return; | 222 return; |
| 206 | 223 |
| 207 DVLOG(1) << "Resolving service " << service_name_; | 224 VLOG(1) << "Resolving service " << service_name_; |
| 208 [service_ resolveWithTimeout:kResolveTimeout]; | 225 [service_ resolveWithTimeout:kResolveTimeout]; |
| 209 } | 226 } |
| 210 | 227 |
| 211 std::string ServiceResolverImplMac::GetName() const { | 228 std::string ServiceResolverImplMac::GetName() const { |
| 212 return service_name_; | 229 return service_name_; |
| 213 } | 230 } |
| 214 | 231 |
| 215 void ServiceResolverImplMac::OnResolveUpdate(RequestStatus status) { | 232 void ServiceResolverImplMac::OnResolveUpdate(RequestStatus status) { |
| 233 VLOG(1) << "ServiceResolverImplMac::OnResolveUpdate: " << service_name_ |
| 234 << ", " << status; |
| 216 if (status == STATUS_SUCCESS) { | 235 if (status == STATUS_SUCCESS) { |
| 217 service_description_.service_name = service_name_; | 236 service_description_.service_name = service_name_; |
| 218 | 237 |
| 219 for (NSData* address in [service_ addresses]) { | 238 for (NSData* address in [service_ addresses]) { |
| 220 const void* bytes = [address bytes]; | 239 const void* bytes = [address bytes]; |
| 221 // TODO(justinlin): Handle IPv6 addresses? | 240 // TODO(justinlin): Handle IPv6 addresses? |
| 222 if (static_cast<const sockaddr*>(bytes)->sa_family == AF_INET) { | 241 if (static_cast<const sockaddr*>(bytes)->sa_family == AF_INET) { |
| 223 const sockaddr_in* sock = static_cast<const sockaddr_in*>(bytes); | 242 const sockaddr_in* sock = static_cast<const sockaddr_in*>(bytes); |
| 224 char addr[INET_ADDRSTRLEN]; | 243 char addr[INET_ADDRSTRLEN]; |
| 225 inet_ntop(AF_INET, &sock->sin_addr, addr, INET_ADDRSTRLEN); | 244 inet_ntop(AF_INET, &sock->sin_addr, addr, INET_ADDRSTRLEN); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 local_discovery::ServiceResolver::STATUS_SUCCESS); | 328 local_discovery::ServiceResolver::STATUS_SUCCESS); |
| 310 } | 329 } |
| 311 | 330 |
| 312 - (void)netService:(NSNetService *)sender | 331 - (void)netService:(NSNetService *)sender |
| 313 didNotResolve:(NSDictionary *)errorDict { | 332 didNotResolve:(NSDictionary *)errorDict { |
| 314 serviceResolverImpl_->OnResolveUpdate( | 333 serviceResolverImpl_->OnResolveUpdate( |
| 315 local_discovery::ServiceResolver::STATUS_REQUEST_TIMEOUT); | 334 local_discovery::ServiceResolver::STATUS_REQUEST_TIMEOUT); |
| 316 } | 335 } |
| 317 | 336 |
| 318 @end | 337 @end |
| OLD | NEW |