Bug 1235509 - Link monitor should not fire link change events for the refresh of the ipv6 lifetime. r=bagder

This commit is contained in:
Dragana Damjanovic 2016-01-11 06:42:36 -08:00
Родитель e5e2a31836
Коммит d8f3e608b5
2 изменённых файлов: 89 добавлений и 2 удалений

Просмотреть файл

@ -157,8 +157,13 @@ void nsNotifyAddrListener::OnNetlinkMessage(int aNetlinkSocket)
char buffer[4095];
struct rtattr *attr;
int attr_len;
const struct ifaddrmsg* newifam;
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));
if (rc < 0) {
return;
@ -178,7 +183,9 @@ void nsNotifyAddrListener::OnNetlinkMessage(int aNetlinkSocket)
switch(nlh->nlmsg_type) {
case RTM_DELROUTE:
LOG(("nsNotifyAddrListener::OnNetlinkMessage deleted route"));
case RTM_NEWROUTE:
LOG(("nsNotifyAddrListener::OnNetlinkMessage new/deleted route"));
// Get the route data
route_entry = static_cast<struct rtmsg *>(NLMSG_DATA(nlh));
@ -217,9 +224,83 @@ void nsNotifyAddrListener::OnNetlinkMessage(int aNetlinkSocket)
}
break;
case RTM_DELADDR:
LOG(("nsNotifyAddrListener::OnNetlinkMessage deleted address"));
case RTM_NEWADDR:
LOG(("OnNetlinkMessage: new address\n"));
networkChange = true;
LOG(("nsNotifyAddrListener::OnNetlinkMessage: new/deleted address"
"\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;
default:

Просмотреть файл

@ -23,6 +23,7 @@
#include "mozilla/Atomics.h"
#include "mozilla/TimeStamp.h"
#include "nsITimer.h"
#include "nsClassHashtable.h"
class nsNotifyAddrListener : public nsINetworkLinkService,
public nsIRunnable,
@ -88,6 +89,11 @@ private:
// Time stamp for first event during coalescing
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_ */