зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1235509 - Link monitor should not fire link change events for the refresh of the ipv6 lifetime. r=bagder
This commit is contained in:
Родитель
e5e2a31836
Коммит
d8f3e608b5
|
@ -157,8 +157,13 @@ void nsNotifyAddrListener::OnNetlinkMessage(int aNetlinkSocket)
|
||||||
char buffer[4095];
|
char buffer[4095];
|
||||||
struct rtattr *attr;
|
struct rtattr *attr;
|
||||||
int attr_len;
|
int attr_len;
|
||||||
|
const struct ifaddrmsg* newifam;
|
||||||
bool link_local;
|
bool link_local;
|
||||||
|
|
||||||
|
// inspired by check_pf.c.
|
||||||
|
nsAutoPtr<char> addr;
|
||||||
|
nsAutoPtr<char> localaddr;
|
||||||
|
|
||||||
ssize_t rc = EINTR_RETRY(recv(aNetlinkSocket, buffer, sizeof(buffer), 0));
|
ssize_t rc = EINTR_RETRY(recv(aNetlinkSocket, buffer, sizeof(buffer), 0));
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
return;
|
return;
|
||||||
|
@ -178,7 +183,9 @@ void nsNotifyAddrListener::OnNetlinkMessage(int aNetlinkSocket)
|
||||||
|
|
||||||
switch(nlh->nlmsg_type) {
|
switch(nlh->nlmsg_type) {
|
||||||
case RTM_DELROUTE:
|
case RTM_DELROUTE:
|
||||||
|
LOG(("nsNotifyAddrListener::OnNetlinkMessage deleted route"));
|
||||||
case RTM_NEWROUTE:
|
case RTM_NEWROUTE:
|
||||||
|
LOG(("nsNotifyAddrListener::OnNetlinkMessage new/deleted route"));
|
||||||
// Get the route data
|
// Get the route data
|
||||||
route_entry = static_cast<struct rtmsg *>(NLMSG_DATA(nlh));
|
route_entry = static_cast<struct rtmsg *>(NLMSG_DATA(nlh));
|
||||||
|
|
||||||
|
@ -217,9 +224,83 @@ void nsNotifyAddrListener::OnNetlinkMessage(int aNetlinkSocket)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case RTM_DELADDR:
|
||||||
|
LOG(("nsNotifyAddrListener::OnNetlinkMessage deleted address"));
|
||||||
case RTM_NEWADDR:
|
case RTM_NEWADDR:
|
||||||
LOG(("OnNetlinkMessage: new address\n"));
|
LOG(("nsNotifyAddrListener::OnNetlinkMessage: new/deleted address"
|
||||||
networkChange = true;
|
"\n"));
|
||||||
|
newifam = reinterpret_cast<struct ifaddrmsg*>(NLMSG_DATA(nlh));
|
||||||
|
|
||||||
|
if ((newifam->ifa_family != AF_INET) &&
|
||||||
|
(newifam->ifa_family != AF_INET6)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
attr = IFA_RTA (newifam);
|
||||||
|
attr_len = IFA_PAYLOAD (nlh);
|
||||||
|
for (;attr_len && RTA_OK (attr, attr_len);
|
||||||
|
attr = RTA_NEXT (attr, attr_len)) {
|
||||||
|
if (attr->rta_type == IFA_ADDRESS) {
|
||||||
|
if (newifam->ifa_family == AF_INET) {
|
||||||
|
struct in_addr* in = (struct in_addr*)RTA_DATA(attr);
|
||||||
|
addr = (char*)malloc(INET_ADDRSTRLEN);
|
||||||
|
inet_ntop(AF_INET, in, addr.get(), INET_ADDRSTRLEN);
|
||||||
|
} else {
|
||||||
|
struct in6_addr* in = (struct in6_addr*)RTA_DATA(attr);
|
||||||
|
addr = (char*)malloc(INET6_ADDRSTRLEN);
|
||||||
|
inet_ntop(AF_INET6, in, addr.get(), INET6_ADDRSTRLEN);
|
||||||
|
}
|
||||||
|
} else if (attr->rta_type == IFA_LOCAL) {
|
||||||
|
if (newifam->ifa_family == AF_INET) {
|
||||||
|
struct in_addr* in = (struct in_addr*)RTA_DATA(attr);
|
||||||
|
localaddr = (char*)malloc(INET_ADDRSTRLEN);
|
||||||
|
inet_ntop(AF_INET, in, localaddr.get(), INET_ADDRSTRLEN);
|
||||||
|
} else {
|
||||||
|
struct in6_addr* in = (struct in6_addr*)RTA_DATA(attr);
|
||||||
|
localaddr = (char*)malloc(INET6_ADDRSTRLEN);
|
||||||
|
inet_ntop(AF_INET6, in, localaddr.get(), INET6_ADDRSTRLEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (localaddr) {
|
||||||
|
addr = localaddr;
|
||||||
|
}
|
||||||
|
if (!addr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (nlh->nlmsg_type == RTM_NEWADDR) {
|
||||||
|
LOG(("nsNotifyAddrListener::OnNetlinkMessage: a new address "
|
||||||
|
"- %s.", addr.get()));
|
||||||
|
struct ifaddrmsg* ifam;
|
||||||
|
nsCString addrStr;
|
||||||
|
addrStr.Assign(addr);
|
||||||
|
if (mAddressInfo.Get(addrStr, &ifam)) {
|
||||||
|
LOG(("nsNotifyAddrListener::OnNetlinkMessage: the address "
|
||||||
|
"already known."));
|
||||||
|
if (memcmp(ifam, newifam, sizeof(struct ifaddrmsg))) {
|
||||||
|
LOG(("nsNotifyAddrListener::OnNetlinkMessage: but "
|
||||||
|
"the address info has been changed."));
|
||||||
|
networkChange = true;
|
||||||
|
memcpy(ifam, newifam, sizeof(struct ifaddrmsg));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
networkChange = true;
|
||||||
|
ifam = (struct ifaddrmsg*)malloc(sizeof(struct ifaddrmsg));
|
||||||
|
memcpy(ifam, newifam, sizeof(struct ifaddrmsg));
|
||||||
|
mAddressInfo.Put(addrStr,ifam);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOG(("nsNotifyAddrListener::OnNetlinkMessage: an address "
|
||||||
|
"has been deleted - %s.", addr.get()));
|
||||||
|
networkChange = true;
|
||||||
|
nsCString addrStr;
|
||||||
|
addrStr.Assign(addr);
|
||||||
|
mAddressInfo.Remove(addrStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean it up.
|
||||||
|
localaddr = nullptr;
|
||||||
|
addr = nullptr;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "mozilla/Atomics.h"
|
#include "mozilla/Atomics.h"
|
||||||
#include "mozilla/TimeStamp.h"
|
#include "mozilla/TimeStamp.h"
|
||||||
#include "nsITimer.h"
|
#include "nsITimer.h"
|
||||||
|
#include "nsClassHashtable.h"
|
||||||
|
|
||||||
class nsNotifyAddrListener : public nsINetworkLinkService,
|
class nsNotifyAddrListener : public nsINetworkLinkService,
|
||||||
public nsIRunnable,
|
public nsIRunnable,
|
||||||
|
@ -88,6 +89,11 @@ private:
|
||||||
|
|
||||||
// Time stamp for first event during coalescing
|
// Time stamp for first event during coalescing
|
||||||
mozilla::TimeStamp mChangeTime;
|
mozilla::TimeStamp mChangeTime;
|
||||||
|
|
||||||
|
// Seen Ip addresses. For Ipv6 addresses some time router renews their
|
||||||
|
// lifetime and we should not detect this as a network link change, so we
|
||||||
|
// keep info about all seen addresses.
|
||||||
|
nsClassHashtable<nsCStringHashKey, struct ifaddrmsg> mAddressInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* NSNOTIFYADDRLISTENER_LINUX_H_ */
|
#endif /* NSNOTIFYADDRLISTENER_LINUX_H_ */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче