Various fixes in IpReachability event logging
- fold IpReachabilityMonitor* classes into a single IpReachabilityEvent. - only log an event for NUD_FAILED Netlink answers. - distinguish between NUD_FAILED with or without lost of provisioning. - do not record host ip addresses. - record interface name instead of interface index when losing provisioning. - also return an error code when probeNeighbor fails, and log this error code in IpReachability events. Bug: 28204408 Change-Id: I5f0def0ab1ace7e467a0c69b3b82d07ef2252307
This commit is contained in:
@ -26111,9 +26111,10 @@ package android.net.metrics {
|
||||
field public static final int IPCE_IPMGR_PROVISIONING_FAIL = 4097; // 0x1001
|
||||
field public static final int IPCE_IPMGR_PROVISIONING_OK = 4096; // 0x1000
|
||||
field public static final int IPCE_IPRM_BASE = 0; // 0x0
|
||||
field public static final int IPCE_IPRM_MESSAGE_RECEIVED = 1; // 0x1
|
||||
field public static final int IPCE_IPRM_PROBE_RESULT = 0; // 0x0
|
||||
field public static final int IPCE_IPRM_REACHABILITY_LOST = 2; // 0x2
|
||||
field public static final int IPCE_IPRM_NUD_FAILED = 2; // 0x2
|
||||
field public static final int IPCE_IPRM_PROBE_FAILURE = 1; // 0x1
|
||||
field public static final int IPCE_IPRM_PROBE_STARTED = 0; // 0x0
|
||||
field public static final int IPCE_IPRM_PROVISIONING_LOST = 3; // 0x3
|
||||
field public static final int IPCE_NETMON_BASE = 2048; // 0x800
|
||||
field public static final int IPCE_NETMON_CHECK_RESULT = 2049; // 0x801
|
||||
field public static final int IPCE_NETMON_STATE_CHANGE = 2048; // 0x800
|
||||
@ -26128,35 +26129,20 @@ package android.net.metrics {
|
||||
field public final java.lang.String ifName;
|
||||
}
|
||||
|
||||
public final class IpReachabilityMonitorLostEvent extends android.net.metrics.IpConnectivityEvent implements android.os.Parcelable {
|
||||
public final class IpReachabilityEvent extends android.net.metrics.IpConnectivityEvent implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public static void logEvent(java.lang.String);
|
||||
method public static void logNudFailed(java.lang.String);
|
||||
method public static void logProbeEvent(java.lang.String, int);
|
||||
method public static void logProvisioningLost(java.lang.String);
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator<android.net.metrics.IpReachabilityMonitorLostEvent> CREATOR;
|
||||
field public static final android.os.Parcelable.Creator<android.net.metrics.IpReachabilityEvent> CREATOR;
|
||||
field public static final int NUD_FAILED = 512; // 0x200
|
||||
field public static final int PROBE = 256; // 0x100
|
||||
field public static final int PROVISIONING_LOST = 768; // 0x300
|
||||
field public final int eventType;
|
||||
field public final java.lang.String ifName;
|
||||
}
|
||||
|
||||
public final class IpReachabilityMonitorMessageEvent extends android.net.metrics.IpConnectivityEvent implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public static void logEvent(java.lang.String, java.lang.String, int, int);
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator<android.net.metrics.IpReachabilityMonitorMessageEvent> CREATOR;
|
||||
field public final java.lang.String destination;
|
||||
field public final java.lang.String ifName;
|
||||
field public final int msgType;
|
||||
field public final int nudState;
|
||||
}
|
||||
|
||||
public final class IpReachabilityMonitorProbeEvent extends android.net.metrics.IpConnectivityEvent implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public static void logEvent(java.lang.String, java.lang.String, boolean);
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator<android.net.metrics.IpReachabilityMonitorProbeEvent> CREATOR;
|
||||
field public final java.lang.String destination;
|
||||
field public final java.lang.String ifName;
|
||||
field public final boolean success;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package android.net.nsd {
|
||||
|
@ -39,9 +39,10 @@ public abstract class IpConnectivityEvent {
|
||||
public static final int IPCE_IPMGR_BASE = 4 * 1024;
|
||||
public static final int IPCE_DNS_BASE = 5 * 1024;
|
||||
|
||||
public static final int IPCE_IPRM_PROBE_RESULT = IPCE_IPRM_BASE + 0;
|
||||
public static final int IPCE_IPRM_MESSAGE_RECEIVED = IPCE_IPRM_BASE + 1;
|
||||
public static final int IPCE_IPRM_REACHABILITY_LOST = IPCE_IPRM_BASE + 2;
|
||||
public static final int IPCE_IPRM_PROBE_STARTED = IPCE_IPRM_BASE + 0;
|
||||
public static final int IPCE_IPRM_PROBE_FAILURE = IPCE_IPRM_BASE + 1;
|
||||
public static final int IPCE_IPRM_NUD_FAILED = IPCE_IPRM_BASE + 2;
|
||||
public static final int IPCE_IPRM_PROVISIONING_LOST = IPCE_IPRM_BASE + 3;
|
||||
|
||||
public static final int IPCE_DHCP_RECV_ERROR = IPCE_DHCP_BASE + 0;
|
||||
public static final int IPCE_DHCP_PARSE_ERROR = IPCE_DHCP_BASE + 1;
|
||||
|
84
core/java/android/net/metrics/IpReachabilityEvent.java
Normal file
84
core/java/android/net/metrics/IpReachabilityEvent.java
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net.metrics;
|
||||
|
||||
import android.annotation.SystemApi;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
/**
|
||||
* {@hide}
|
||||
*/
|
||||
@SystemApi
|
||||
public final class IpReachabilityEvent extends IpConnectivityEvent implements Parcelable {
|
||||
|
||||
public static final int PROBE = 1 << 8;
|
||||
public static final int NUD_FAILED = 2 << 8;
|
||||
public static final int PROVISIONING_LOST = 3 << 8;
|
||||
|
||||
public final String ifName;
|
||||
// eventType byte format (MSB to LSB):
|
||||
// byte 0: unused
|
||||
// byte 1: unused
|
||||
// byte 2: type of event: PROBE, NUD_FAILED, PROVISIONING_LOST
|
||||
// byte 3: kernel errno from RTNetlink or IpReachabilityMonitor
|
||||
public final int eventType;
|
||||
|
||||
private IpReachabilityEvent(String ifName, int eventType) {
|
||||
this.ifName = ifName;
|
||||
this.eventType = eventType;
|
||||
}
|
||||
|
||||
private IpReachabilityEvent(Parcel in) {
|
||||
this.ifName = in.readString();
|
||||
this.eventType = in.readInt();
|
||||
}
|
||||
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeString(ifName);
|
||||
out.writeInt(eventType);
|
||||
}
|
||||
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<IpReachabilityEvent> CREATOR
|
||||
= new Parcelable.Creator<IpReachabilityEvent>() {
|
||||
public IpReachabilityEvent createFromParcel(Parcel in) {
|
||||
return new IpReachabilityEvent(in);
|
||||
}
|
||||
|
||||
public IpReachabilityEvent[] newArray(int size) {
|
||||
return new IpReachabilityEvent[size];
|
||||
}
|
||||
};
|
||||
|
||||
public static void logProbeEvent(String ifName, int nlErrorCode) {
|
||||
final int tag = (nlErrorCode == 0) ? IPCE_IPRM_PROBE_STARTED : IPCE_IPRM_PROBE_FAILURE;
|
||||
final int eventType = PROBE | (nlErrorCode & 0xFF);
|
||||
logEvent(tag, new IpReachabilityEvent(ifName, eventType));
|
||||
}
|
||||
|
||||
public static void logNudFailed(String ifName) {
|
||||
logEvent(IPCE_IPRM_NUD_FAILED, new IpReachabilityEvent(ifName, NUD_FAILED));
|
||||
}
|
||||
|
||||
public static void logProvisioningLost(String ifName) {
|
||||
logEvent(IPCE_IPRM_PROVISIONING_LOST, new IpReachabilityEvent(ifName, PROVISIONING_LOST));
|
||||
}
|
||||
};
|
@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net.metrics;
|
||||
|
||||
import android.annotation.SystemApi;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
/**
|
||||
* {@hide}
|
||||
*/
|
||||
@SystemApi
|
||||
public final class IpReachabilityMonitorLostEvent extends IpConnectivityEvent
|
||||
implements Parcelable {
|
||||
public final String ifName;
|
||||
|
||||
private IpReachabilityMonitorLostEvent(String ifName) {
|
||||
this.ifName = ifName;
|
||||
}
|
||||
|
||||
private IpReachabilityMonitorLostEvent(Parcel in) {
|
||||
this.ifName = in.readString();
|
||||
}
|
||||
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeString(ifName);
|
||||
}
|
||||
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<IpReachabilityMonitorLostEvent> CREATOR
|
||||
= new Parcelable.Creator<IpReachabilityMonitorLostEvent>() {
|
||||
public IpReachabilityMonitorLostEvent createFromParcel(Parcel in) {
|
||||
return new IpReachabilityMonitorLostEvent(in);
|
||||
}
|
||||
|
||||
public IpReachabilityMonitorLostEvent[] newArray(int size) {
|
||||
return new IpReachabilityMonitorLostEvent[size];
|
||||
}
|
||||
};
|
||||
|
||||
public static void logEvent(String ifName) {
|
||||
logEvent(IPCE_IPRM_REACHABILITY_LOST, new IpReachabilityMonitorLostEvent(ifName));
|
||||
}
|
||||
};
|
@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net.metrics;
|
||||
|
||||
import android.annotation.SystemApi;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
/**
|
||||
* {@hide}
|
||||
*/
|
||||
@SystemApi
|
||||
public final class IpReachabilityMonitorMessageEvent extends IpConnectivityEvent
|
||||
implements Parcelable {
|
||||
public final String ifName;
|
||||
public final String destination;
|
||||
public final int msgType;
|
||||
public final int nudState;
|
||||
|
||||
private IpReachabilityMonitorMessageEvent(String ifName, String destination, int msgType,
|
||||
int nudState) {
|
||||
this.ifName = ifName;
|
||||
this.destination = destination;
|
||||
this.msgType = msgType;
|
||||
this.nudState = nudState;
|
||||
}
|
||||
|
||||
private IpReachabilityMonitorMessageEvent(Parcel in) {
|
||||
this.ifName = in.readString();
|
||||
this.destination = in.readString();
|
||||
this.msgType = in.readInt();
|
||||
this.nudState = in.readInt();
|
||||
}
|
||||
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeString(ifName);
|
||||
out.writeString(destination);
|
||||
out.writeInt(msgType);
|
||||
out.writeInt(nudState);
|
||||
}
|
||||
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<IpReachabilityMonitorMessageEvent> CREATOR
|
||||
= new Parcelable.Creator<IpReachabilityMonitorMessageEvent>() {
|
||||
public IpReachabilityMonitorMessageEvent createFromParcel(Parcel in) {
|
||||
return new IpReachabilityMonitorMessageEvent(in);
|
||||
}
|
||||
|
||||
public IpReachabilityMonitorMessageEvent[] newArray(int size) {
|
||||
return new IpReachabilityMonitorMessageEvent[size];
|
||||
}
|
||||
};
|
||||
|
||||
public static void logEvent(String ifName, String destination, int msgType, int nudState) {
|
||||
logEvent(IPCE_IPRM_MESSAGE_RECEIVED,
|
||||
new IpReachabilityMonitorMessageEvent(ifName, destination, msgType, nudState));
|
||||
}
|
||||
};
|
@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net.metrics;
|
||||
|
||||
import android.annotation.SystemApi;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
/**
|
||||
* {@hide}
|
||||
*/
|
||||
@SystemApi
|
||||
public final class IpReachabilityMonitorProbeEvent extends IpConnectivityEvent
|
||||
implements Parcelable {
|
||||
public final String ifName;
|
||||
public final String destination;
|
||||
public final boolean success;
|
||||
|
||||
private IpReachabilityMonitorProbeEvent(String ifName, String destination, boolean success) {
|
||||
this.ifName = ifName;
|
||||
this.destination = destination;
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
private IpReachabilityMonitorProbeEvent(Parcel in) {
|
||||
this.ifName = in.readString();
|
||||
this.destination = in.readString();
|
||||
this.success = in.readByte() > 0 ? true : false;
|
||||
}
|
||||
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeString(ifName);
|
||||
out.writeString(destination);
|
||||
out.writeByte((byte)(success ? 1 : 0));
|
||||
}
|
||||
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<IpReachabilityMonitorProbeEvent> CREATOR
|
||||
= new Parcelable.Creator<IpReachabilityMonitorProbeEvent>() {
|
||||
public IpReachabilityMonitorProbeEvent createFromParcel(Parcel in) {
|
||||
return new IpReachabilityMonitorProbeEvent(in);
|
||||
}
|
||||
|
||||
public IpReachabilityMonitorProbeEvent[] newArray(int size) {
|
||||
return new IpReachabilityMonitorProbeEvent[size];
|
||||
}
|
||||
};
|
||||
|
||||
public static void logEvent(String ifName, String destination, boolean success) {
|
||||
logEvent(IPCE_IPRM_PROBE_RESULT,
|
||||
new IpReachabilityMonitorProbeEvent(ifName, destination, success));
|
||||
}
|
||||
};
|
@ -24,9 +24,7 @@ import android.net.LinkProperties;
|
||||
import android.net.LinkProperties.ProvisioningChange;
|
||||
import android.net.ProxyInfo;
|
||||
import android.net.RouteInfo;
|
||||
import android.net.metrics.IpReachabilityMonitorMessageEvent;
|
||||
import android.net.metrics.IpReachabilityMonitorProbeEvent;
|
||||
import android.net.metrics.IpReachabilityMonitorLostEvent;
|
||||
import android.net.metrics.IpReachabilityEvent;
|
||||
import android.net.netlink.NetlinkConstants;
|
||||
import android.net.netlink.NetlinkErrorMessage;
|
||||
import android.net.netlink.NetlinkMessage;
|
||||
@ -168,47 +166,54 @@ public class IpReachabilityMonitor {
|
||||
* Make the kernel perform neighbor reachability detection (IPv4 ARP or IPv6 ND)
|
||||
* for the given IP address on the specified interface index.
|
||||
*
|
||||
* @return true, if the request was successfully passed to the kernel; false otherwise.
|
||||
* @return 0 if the request was successfully passed to the kernel; otherwise return
|
||||
* a non-zero error code.
|
||||
*/
|
||||
public static boolean probeNeighbor(int ifIndex, InetAddress ip) {
|
||||
final long IO_TIMEOUT = 300L;
|
||||
private static int probeNeighbor(int ifIndex, InetAddress ip) {
|
||||
final String msgSnippet = "probing ip=" + ip.getHostAddress() + "%" + ifIndex;
|
||||
if (DBG) { Log.d(TAG, msgSnippet); }
|
||||
|
||||
final byte[] msg = RtNetlinkNeighborMessage.newNewNeighborMessage(
|
||||
1, ip, StructNdMsg.NUD_PROBE, ifIndex, null);
|
||||
boolean returnValue = false;
|
||||
|
||||
int errno = -OsConstants.EPROTO;
|
||||
try (NetlinkSocket nlSocket = new NetlinkSocket(OsConstants.NETLINK_ROUTE)) {
|
||||
final long IO_TIMEOUT = 300L;
|
||||
nlSocket.connectToKernel();
|
||||
nlSocket.sendMessage(msg, 0, msg.length, IO_TIMEOUT);
|
||||
final ByteBuffer bytes = nlSocket.recvMessage(IO_TIMEOUT);
|
||||
// recvMessage() guaranteed to not return null if it did not throw.
|
||||
final NetlinkMessage response = NetlinkMessage.parse(bytes);
|
||||
if (response != null && response instanceof NetlinkErrorMessage &&
|
||||
(((NetlinkErrorMessage) response).getNlMsgError() != null) &&
|
||||
(((NetlinkErrorMessage) response).getNlMsgError().error == 0)) {
|
||||
returnValue = true;
|
||||
} else {
|
||||
String errmsg;
|
||||
if (bytes == null) {
|
||||
errmsg = "null recvMessage";
|
||||
} else if (response == null) {
|
||||
bytes.position(0);
|
||||
errmsg = "raw bytes: " + NetlinkConstants.hexify(bytes);
|
||||
} else {
|
||||
(((NetlinkErrorMessage) response).getNlMsgError() != null)) {
|
||||
errno = ((NetlinkErrorMessage) response).getNlMsgError().error;
|
||||
if (errno != 0) {
|
||||
// TODO: consider ignoring EINVAL (-22), which appears to be
|
||||
// normal when probing a neighbor for which the kernel does
|
||||
// not already have / no longer has a link layer address.
|
||||
Log.e(TAG, "Error " + msgSnippet + ", errmsg=" + response.toString());
|
||||
}
|
||||
} else {
|
||||
String errmsg;
|
||||
if (response == null) {
|
||||
bytes.position(0);
|
||||
errmsg = "raw bytes: " + NetlinkConstants.hexify(bytes);
|
||||
} else {
|
||||
errmsg = response.toString();
|
||||
}
|
||||
Log.e(TAG, "Error " + msgSnippet + ", errmsg=" + errmsg);
|
||||
}
|
||||
} catch (ErrnoException | InterruptedIOException | SocketException e) {
|
||||
Log.d(TAG, "Error " + msgSnippet, e);
|
||||
} catch (ErrnoException e) {
|
||||
Log.e(TAG, "Error " + msgSnippet, e);
|
||||
errno = -e.errno;
|
||||
} catch (InterruptedIOException e) {
|
||||
Log.e(TAG, "Error " + msgSnippet, e);
|
||||
errno = -OsConstants.ETIMEDOUT;
|
||||
} catch (SocketException e) {
|
||||
Log.e(TAG, "Error " + msgSnippet, e);
|
||||
errno = -OsConstants.EIO;
|
||||
}
|
||||
IpReachabilityMonitorProbeEvent.logEvent("ifindex-" + ifIndex, ip.getHostAddress(),
|
||||
returnValue);
|
||||
return returnValue;
|
||||
return errno;
|
||||
}
|
||||
|
||||
public IpReachabilityMonitor(Context context, String ifName, Callback callback)
|
||||
@ -354,7 +359,7 @@ public class IpReachabilityMonitor {
|
||||
}
|
||||
|
||||
if (delta == ProvisioningChange.LOST_PROVISIONING) {
|
||||
IpReachabilityMonitorLostEvent.logEvent(mInterfaceName);
|
||||
IpReachabilityEvent.logProvisioningLost(mInterfaceName);
|
||||
final String logMsg = "FAILURE: LOST_PROVISIONING, " + msg;
|
||||
Log.w(TAG, logMsg);
|
||||
if (mCallback != null) {
|
||||
@ -362,6 +367,8 @@ public class IpReachabilityMonitor {
|
||||
// an InetAddress argument.
|
||||
mCallback.notifyLost(ip, logMsg);
|
||||
}
|
||||
} else {
|
||||
IpReachabilityEvent.logNudFailed(mInterfaceName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -385,7 +392,8 @@ public class IpReachabilityMonitor {
|
||||
if (!stillRunning()) {
|
||||
break;
|
||||
}
|
||||
probeNeighbor(mInterfaceIndex, target);
|
||||
final int returnValue = probeNeighbor(mInterfaceIndex, target);
|
||||
IpReachabilityEvent.logProbeEvent(mInterfaceName, returnValue);
|
||||
}
|
||||
}
|
||||
|
||||
@ -523,8 +531,6 @@ public class IpReachabilityMonitor {
|
||||
|
||||
final short msgType = neighMsg.getHeader().nlmsg_type;
|
||||
final short nudState = ndMsg.ndm_state;
|
||||
IpReachabilityMonitorMessageEvent.logEvent(mInterfaceName,
|
||||
destination.getHostAddress(), msgType, nudState);
|
||||
final String eventMsg = "NeighborEvent{"
|
||||
+ "elapsedMs=" + whenMs + ", "
|
||||
+ destination.getHostAddress() + ", "
|
||||
|
Reference in New Issue
Block a user