| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "net/base/address_tracker_linux.h" | 5 #include "net/base/address_tracker_linux.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <linux/if.h> | 8 #include <linux/if.h> |
| 9 #include <sys/ioctl.h> | 9 #include <sys/ioctl.h> |
| 10 | 10 |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 is_offline_ = false; | 206 is_offline_ = false; |
| 207 is_offline_initialized_ = true; | 207 is_offline_initialized_ = true; |
| 208 is_offline_initialized_cv_.Signal(); | 208 is_offline_initialized_cv_.Signal(); |
| 209 } | 209 } |
| 210 | 210 |
| 211 AddressTrackerLinux::AddressMap AddressTrackerLinux::GetAddressMap() const { | 211 AddressTrackerLinux::AddressMap AddressTrackerLinux::GetAddressMap() const { |
| 212 base::AutoLock lock(address_map_lock_); | 212 base::AutoLock lock(address_map_lock_); |
| 213 return address_map_; | 213 return address_map_; |
| 214 } | 214 } |
| 215 | 215 |
| 216 base::hash_set<int> AddressTrackerLinux::GetOnlineLinks() const { |
| 217 base::AutoLock lock(online_links_lock_); |
| 218 return online_links_; |
| 219 } |
| 220 |
| 216 NetworkChangeNotifier::ConnectionType | 221 NetworkChangeNotifier::ConnectionType |
| 217 AddressTrackerLinux::GetCurrentConnectionType() { | 222 AddressTrackerLinux::GetCurrentConnectionType() { |
| 218 // http://crbug.com/125097 | 223 // http://crbug.com/125097 |
| 219 base::ThreadRestrictions::ScopedAllowWait allow_wait; | 224 base::ThreadRestrictions::ScopedAllowWait allow_wait; |
| 220 base::AutoLock lock(is_offline_lock_); | 225 base::AutoLock lock(is_offline_lock_); |
| 221 // Make sure the initial offline state is set before returning. | 226 // Make sure the initial offline state is set before returning. |
| 222 while (!is_offline_initialized_) { | 227 while (!is_offline_initialized_) { |
| 223 is_offline_initialized_cv_.Wait(); | 228 is_offline_initialized_cv_.Wait(); |
| 224 } | 229 } |
| 225 // TODO(droger): Return something more detailed than CONNECTION_UNKNOWN. | 230 // TODO(droger): Return something more detailed than CONNECTION_UNKNOWN. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 249 } | 254 } |
| 250 if (rv < 0) { | 255 if (rv < 0) { |
| 251 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) | 256 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) |
| 252 break; | 257 break; |
| 253 PLOG(ERROR) << "Failed to recv from netlink socket"; | 258 PLOG(ERROR) << "Failed to recv from netlink socket"; |
| 254 return; | 259 return; |
| 255 } | 260 } |
| 256 HandleMessage(buffer, rv, address_changed, link_changed, tunnel_changed); | 261 HandleMessage(buffer, rv, address_changed, link_changed, tunnel_changed); |
| 257 }; | 262 }; |
| 258 if (*link_changed) { | 263 if (*link_changed) { |
| 264 bool is_offline; |
| 265 { |
| 266 base::AutoLock lock(online_links_lock_); |
| 267 is_offline = online_links_.empty(); |
| 268 } |
| 259 base::AutoLock lock(is_offline_lock_); | 269 base::AutoLock lock(is_offline_lock_); |
| 260 is_offline_ = online_links_.empty(); | 270 is_offline_ = is_offline; |
| 261 } | 271 } |
| 262 } | 272 } |
| 263 | 273 |
| 264 void AddressTrackerLinux::HandleMessage(char* buffer, | 274 void AddressTrackerLinux::HandleMessage(char* buffer, |
| 265 size_t length, | 275 size_t length, |
| 266 bool* address_changed, | 276 bool* address_changed, |
| 267 bool* link_changed, | 277 bool* link_changed, |
| 268 bool* tunnel_changed) { | 278 bool* tunnel_changed) { |
| 269 DCHECK(buffer); | 279 DCHECK(buffer); |
| 270 for (struct nlmsghdr* header = reinterpret_cast<struct nlmsghdr*>(buffer); | 280 for (struct nlmsghdr* header = reinterpret_cast<struct nlmsghdr*>(buffer); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 base::AutoLock lock(address_map_lock_); | 322 base::AutoLock lock(address_map_lock_); |
| 313 if (address_map_.erase(address)) | 323 if (address_map_.erase(address)) |
| 314 *address_changed = true; | 324 *address_changed = true; |
| 315 } | 325 } |
| 316 } break; | 326 } break; |
| 317 case RTM_NEWLINK: { | 327 case RTM_NEWLINK: { |
| 318 const struct ifinfomsg* msg = | 328 const struct ifinfomsg* msg = |
| 319 reinterpret_cast<struct ifinfomsg*>(NLMSG_DATA(header)); | 329 reinterpret_cast<struct ifinfomsg*>(NLMSG_DATA(header)); |
| 320 if (!(msg->ifi_flags & IFF_LOOPBACK) && (msg->ifi_flags & IFF_UP) && | 330 if (!(msg->ifi_flags & IFF_LOOPBACK) && (msg->ifi_flags & IFF_UP) && |
| 321 (msg->ifi_flags & IFF_LOWER_UP) && (msg->ifi_flags & IFF_RUNNING)) { | 331 (msg->ifi_flags & IFF_LOWER_UP) && (msg->ifi_flags & IFF_RUNNING)) { |
| 332 base::AutoLock lock(online_links_lock_); |
| 322 if (online_links_.insert(msg->ifi_index).second) { | 333 if (online_links_.insert(msg->ifi_index).second) { |
| 323 *link_changed = true; | 334 *link_changed = true; |
| 324 if (IsTunnelInterface(msg)) | 335 if (IsTunnelInterface(msg)) |
| 325 *tunnel_changed = true; | 336 *tunnel_changed = true; |
| 326 } | 337 } |
| 327 } else { | 338 } else { |
| 339 base::AutoLock lock(online_links_lock_); |
| 328 if (online_links_.erase(msg->ifi_index)) { | 340 if (online_links_.erase(msg->ifi_index)) { |
| 329 *link_changed = true; | 341 *link_changed = true; |
| 330 if (IsTunnelInterface(msg)) | 342 if (IsTunnelInterface(msg)) |
| 331 *tunnel_changed = true; | 343 *tunnel_changed = true; |
| 332 } | 344 } |
| 333 } | 345 } |
| 334 } break; | 346 } break; |
| 335 case RTM_DELLINK: { | 347 case RTM_DELLINK: { |
| 336 const struct ifinfomsg* msg = | 348 const struct ifinfomsg* msg = |
| 337 reinterpret_cast<struct ifinfomsg*>(NLMSG_DATA(header)); | 349 reinterpret_cast<struct ifinfomsg*>(NLMSG_DATA(header)); |
| 350 base::AutoLock lock(online_links_lock_); |
| 338 if (online_links_.erase(msg->ifi_index)) { | 351 if (online_links_.erase(msg->ifi_index)) { |
| 339 *link_changed = true; | 352 *link_changed = true; |
| 340 if (IsTunnelInterface(msg)) | 353 if (IsTunnelInterface(msg)) |
| 341 *tunnel_changed = true; | 354 *tunnel_changed = true; |
| 342 } | 355 } |
| 343 } break; | 356 } break; |
| 344 default: | 357 default: |
| 345 break; | 358 break; |
| 346 } | 359 } |
| 347 } | 360 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 369 netlink_fd_ = -1; | 382 netlink_fd_ = -1; |
| 370 } | 383 } |
| 371 | 384 |
| 372 bool AddressTrackerLinux::IsTunnelInterface(const struct ifinfomsg* msg) const { | 385 bool AddressTrackerLinux::IsTunnelInterface(const struct ifinfomsg* msg) const { |
| 373 // Linux kernel drivers/net/tun.c uses "tun" name prefix. | 386 // Linux kernel drivers/net/tun.c uses "tun" name prefix. |
| 374 return strncmp(get_interface_name_(msg->ifi_index), "tun", 3) == 0; | 387 return strncmp(get_interface_name_(msg->ifi_index), "tun", 3) == 0; |
| 375 } | 388 } |
| 376 | 389 |
| 377 } // namespace internal | 390 } // namespace internal |
| 378 } // namespace net | 391 } // namespace net |
| OLD | NEW |