You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "jason mathews (JIRA)" <ji...@apache.org> on 2014/02/19 21:37:21 UTC

[jira] [Updated] (NET-525) Added missing set methods on NTP class and interface

     [ https://issues.apache.org/jira/browse/NET-525?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

jason mathews updated NET-525:
------------------------------

    Description: 
I was the original contributor of the NTP implementation and have recently cleaned the source and submitting the relevant changes.

Here is the summary of changes:

src/main/java/org/apache/commons/net/ntp/TimeInfo.java
-Added missing equals() and hashCode() methods
-Added new method: getAddress() 

src/main/java/org/apache/commons/net/ntp/NtpV3Packet.java
-Added missing methods: setPrecision(), setRootDelay(), and setRootDispersion()

src/main/java/org/apache/commons/net/ntp/NtpV3Impl.java
-Added missing equals() and hashCode() methods
-Added missing set methods: setRootDelay(), setRootDispersion(), 
-Added validation check to setDatagramPacket()

Added additional tests:
-src/test/java/org/apache/commons/net/ntp/TestNtpPacket.java
-src/test/java/org/apache/commons/net/ntp/TestTimeInfo.java

See attached patch.

Index: src/test/java/org/apache/commons/net/ntp/TestNtpPacket.java
===================================================================
--- src/test/java/org/apache/commons/net/ntp/TestNtpPacket.java	(revision 0)
+++ src/test/java/org/apache/commons/net/ntp/TestNtpPacket.java	(revision 0)
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.commons.net.ntp;
+
+import org.junit.Test;
+import org.junit.Assert;
+
+import java.net.DatagramPacket;
+
+/**
+ * @author Jason Mathews, MITRE Corp
+ * Date: 5/30/13 6:51 PM
+ */
+public class TestNtpPacket {
+
+	// pre-canned NTP packet
+	// [version:3, mode:4, poll:4, refId=0x81531472, precision:-17, delay:100, dispersion(ms):51.605224609375, id:129.83.20.114, xmitTime:Thu, May 30 2013 17:46:01.295, etc. ]
+	static final byte[] ntpPacket = hexStringToByteArray("1c0304ef0000006400000d3681531472d552447fec1d6000d5524718ac49ba5ed55247194b6d9000d55247194b797000");
+
+	@Test
+	public void testCreate() {
+		NtpV3Packet message = new NtpV3Impl();
+		message.setLeapIndicator(0);			 // byte 0 [bit numbers 7-6]
+		message.setVersion(NtpV3Packet.VERSION_3); // byte 0 [bit numbers 5-4]
+		message.setMode(4);						 // byte 0 [bit numbers 3-0]
+		message.setStratum(3);					 // byte 1
+		message.setPoll(4);					 	 // byte 2
+		message.setPrecision(-17);				 // byte 3
+		message.setRootDelay(100);				 // bytes 4-7
+		message.setRootDispersion(3382);		 // bytes 8-11
+		message.setReferenceId(0x81531472);		 // byte 12-15
+		message.setReferenceTime(new TimeStamp(0xd552447fec1d6000L));
+		message.setOriginateTimeStamp(new TimeStamp(0xd5524718ac49ba5eL));
+		message.setReceiveTimeStamp(new TimeStamp(0xd55247194b6d9000L));
+		message.setTransmitTime(new TimeStamp(0xd55247194b797000L));
+
+		Assert.assertEquals(-17, message.getPrecision());
+		Assert.assertEquals(4, message.getPoll());
+		Assert.assertEquals(100, message.getRootDelay());
+		Assert.assertEquals(3382, message.getRootDispersion());
+		Assert.assertEquals(0x81531472, message.getReferenceId());
+		Assert.assertNotNull(message.getReferenceTimeStamp());
+		Assert.assertEquals("NTP", message.getType());
+		Assert.assertEquals("Server", message.getModeName());
+		Assert.assertEquals("129.83.20.114", message.getReferenceIdString());
+		Assert.assertEquals(51, message.getRootDispersionInMillis());
+		Assert.assertEquals(message.getRootDelay() / 65.536, message.getRootDelayInMillisDouble(), 1e-13);
+
+		DatagramPacket dp = message.getDatagramPacket(); // this creates a new datagram
+		Assert.assertNotNull(dp);
+		Assert.assertEquals(48, dp.getLength()); // fixed 48-byte length
+
+		NtpV3Packet message2 = new NtpV3Impl();
+		DatagramPacket dp2 = new DatagramPacket(ntpPacket, ntpPacket.length);
+		message2.setDatagramPacket(dp2);
+
+		Assert.assertEquals(message2, message);
+		Assert.assertEquals(message2.hashCode(), message.hashCode());
+		Assert.assertEquals(message2.toString(), message.toString());
+	}
+
+	@Test
+	public void testCreateAndSetByte0() {
+		// LI + VN + Mode all part of first byte -- make sure set order does not matter
+		NtpV3Packet message = new NtpV3Impl();
+
+		message.setLeapIndicator(2);
+		message.setMode(4);
+		message.setVersion(NtpV3Packet.VERSION_3);
+
+		Assert.assertEquals(4, message.getMode());
+		Assert.assertEquals(NtpV3Packet.VERSION_3, message.getVersion());
+		Assert.assertEquals(2, message.getLeapIndicator());
+
+		message.setLeapIndicator(2);
+		message.setVersion(NtpV3Packet.VERSION_3);
+		message.setMode(4);
+
+		Assert.assertEquals(4, message.getMode());
+		Assert.assertEquals(NtpV3Packet.VERSION_3, message.getVersion());
+		Assert.assertEquals(2, message.getLeapIndicator());
+
+		message.setMode(4);
+		message.setLeapIndicator(2);
+		message.setVersion(NtpV3Packet.VERSION_3);
+
+		Assert.assertEquals(4, message.getMode());
+		Assert.assertEquals(NtpV3Packet.VERSION_3, message.getVersion());
+		Assert.assertEquals(2, message.getLeapIndicator());
+
+		message.setMode(4);
+		message.setVersion(NtpV3Packet.VERSION_3);
+		message.setLeapIndicator(2);
+
+		Assert.assertEquals(4, message.getMode());
+		Assert.assertEquals(NtpV3Packet.VERSION_3, message.getVersion());
+		Assert.assertEquals(2, message.getLeapIndicator());
+
+		message.setVersion(NtpV3Packet.VERSION_3);
+		message.setMode(4);
+		message.setLeapIndicator(2);
+
+		Assert.assertEquals(4, message.getMode());
+		Assert.assertEquals(NtpV3Packet.VERSION_3, message.getVersion());
+		Assert.assertEquals(2, message.getLeapIndicator());
+
+		message.setVersion(NtpV3Packet.VERSION_3);
+		message.setLeapIndicator(2);
+		message.setMode(4);
+
+		Assert.assertEquals(4, message.getMode());
+		Assert.assertEquals(NtpV3Packet.VERSION_3, message.getVersion());
+		Assert.assertEquals(2, message.getLeapIndicator());
+	}
+
+	@Test
+	public void testCreateNtpV4() {
+		NtpV3Packet message = new NtpV3Impl();
+		message.setVersion(NtpV3Packet.VERSION_4);
+		message.setStratum(3);
+		message.setReferenceId(0x81531472);
+		// force hex-string reference id string
+		Assert.assertEquals("81531472", message.getReferenceIdString());
+
+		message.setVersion(NtpV3Packet.VERSION_4);
+		message.setStratum(1);
+		message.setReferenceId(0x55534E4F); // USNO
+		// force raw-string reference id string
+		Assert.assertEquals("USNO", message.getReferenceIdString());
+
+		message.setReferenceId(0x47505300); // GPS
+		Assert.assertEquals("GPS", message.getReferenceIdString());
+	}
+
+	@Test
+	public void testCreateFromBytes() {
+		NtpV3Packet message = new NtpV3Impl();
+		DatagramPacket dp = new DatagramPacket(ntpPacket, ntpPacket.length);
+		message.setDatagramPacket(dp);
+		Assert.assertEquals(4, message.getMode());
+	}
+
+	@Test(expected=IllegalArgumentException.class)
+	public void testCreateFromBadPacket() {
+		NtpV3Packet message = new NtpV3Impl();
+		DatagramPacket dp = new DatagramPacket(ntpPacket, ntpPacket.length-4); // drop 4-bytes from packet
+		message.setDatagramPacket(dp);
+	}
+
+	@Test(expected=IllegalArgumentException.class)
+	public void testCreateFromNullPacket() {
+		NtpV3Packet message = new NtpV3Impl();
+		message.setDatagramPacket(null);
+	}
+
+	@Test
+	public void testEquals() {
+		NtpV3Packet message1 = new NtpV3Impl();
+		DatagramPacket dp = new DatagramPacket(ntpPacket, ntpPacket.length);
+		message1.setDatagramPacket(dp);
+		NtpV3Packet message2 = new NtpV3Impl();
+		message2.setDatagramPacket(dp);
+		Assert.assertEquals("hashCode", message1.hashCode(), message2.hashCode());
+		Assert.assertEquals(message1, message2);
+
+		// now change the packet to force equals() => false
+		message2.setMode(2);
+		Assert.assertTrue(message1.getMode() != message2.getMode());
+		Assert.assertFalse(message1.equals(message2));
+	}
+
+	private static byte[] hexStringToByteArray(String s) {
+		int len = s.length();
+		byte[] data = new byte[len / 2];
+		for (int i = 0; i < len; i += 2) {
+			data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+					+ Character.digit(s.charAt(i+1), 16));
+		}
+		return data;
+	}
+
+}

Property changes on: src/test/java/org/apache/commons/net/ntp/TestNtpPacket.java
___________________________________________________________________
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain

Index: src/test/java/org/apache/commons/net/ntp/TestTimeInfo.java
===================================================================
--- src/test/java/org/apache/commons/net/ntp/TestTimeInfo.java	(revision 0)
+++ src/test/java/org/apache/commons/net/ntp/TestTimeInfo.java	(revision 0)
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.commons.net.ntp;
+
+import org.junit.Test;
+import org.junit.Assert;
+
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Jason Mathews, MITRE Corporation
+ * Date: 6/6/13 9:48 PM
+ */
+public class TestTimeInfo {
+
+	@Test
+	public void testEquals() {
+		NtpV3Packet packet = new NtpV3Impl();
+		final long returnTime = System.currentTimeMillis();
+		TimeInfo info = new TimeInfo(packet, returnTime);
+		info.addComment("this is a comment");
+		TimeInfo other = new TimeInfo(packet, returnTime);
+		other.addComment("this is a comment");
+		Assert.assertEquals(info, other); // fails
+		Assert.assertEquals(info.hashCode(), other.hashCode());
+		other.addComment("another comment");
+		//Assert.assertFalse(info.equals(other)); // comments not used for equality
+
+		TimeInfo another = new TimeInfo(packet, returnTime, new ArrayList<String>());
+		Assert.assertEquals(info, another);
+	}
+
+	@Test
+	public void testComputeDetails() {
+		// if (origTime > returnTime) // assert destTime >= origTime
+		NtpV3Packet packet = new NtpV3Impl();
+		long returnTime = System.currentTimeMillis();
+
+		// example
+		// returntime=1370571658178
+		// origTime=  1370571659178
+
+		// originate time as defined in RFC-1305 (t1)
+		packet.setOriginateTimeStamp(TimeStamp.getNtpTime(returnTime + 1000));
+		// Receive Time is time request received by server (t2)
+		packet.setReceiveTimeStamp(packet.getOriginateTimeStamp());
+		// Transmit time is time reply sent by server (t3)
+		packet.setTransmitTime(packet.getOriginateTimeStamp());
+		packet.setReferenceTime(packet.getOriginateTimeStamp());
+
+		//long origTime = packet.getOriginateTimeStamp().getTime();
+		//System.out.println("returntime=" + returnTime);
+		//System.out.println("origTime=  " + origTime);
+
+		TimeInfo info = new TimeInfo(packet, returnTime);
+		info.computeDetails();
+
+		Assert.assertSame(packet, info.getMessage());
+		Assert.assertEquals(returnTime, info.getReturnTime());
+		Assert.assertEquals(Long.valueOf(500), info.getOffset());
+		Assert.assertEquals(Long.valueOf(-1000), info.getDelay());
+
+		// comments: [Warning: processing time > total network time, Error: OrigTime > DestRcvTime]
+		Assert.assertEquals(2, info.getComments().size());
+	}
+
+	@Test(expected=IllegalArgumentException.class)
+	public void testException() {
+		NtpV3Packet packet = null;
+		new TimeInfo(packet, 1L);
+	}
+
+	@Test
+	public void testAddress() {
+		NtpV3Packet packet = new NtpV3Impl();
+		TimeInfo info = new TimeInfo(packet, System.currentTimeMillis());
+		Assert.assertNull(info.getAddress());
+		packet.getDatagramPacket().setAddress(InetAddress.getLoopbackAddress());
+		Assert.assertNotNull(info.getAddress());
+	}
+
+	@Test
+	public void testZeroTime() {
+		NtpV3Packet packet = new NtpV3Impl();
+		TimeInfo info = new TimeInfo(packet, 0);
+		info.computeDetails();
+		Assert.assertNull(info.getDelay());
+		Assert.assertNull(info.getOffset());
+		Assert.assertEquals(0L, info.getReturnTime());
+		// comments: Error: zero orig time -- cannot compute delay/offset
+		final List<String> comments = info.getComments();
+		Assert.assertEquals(1, comments.size());
+		Assert.assertTrue(comments.get(0).contains("zero orig time"));
+	}
+
+	@Test
+	public void testNotEquals() {
+		NtpV3Packet packet = new NtpV3Impl();
+		long returnTime = System.currentTimeMillis();
+		TimeInfo info = new TimeInfo(packet, returnTime);
+
+		// 1. different return time
+		NtpV3Packet packet2 = new NtpV3Impl();
+		Assert.assertEquals(packet, packet2);
+		TimeInfo info2 = new TimeInfo(packet2, returnTime + 1);
+		Assert.assertFalse(info.equals(info2));
+
+		// 2. different message / same time
+		packet2.setStratum(3);
+		packet2.setRootDelay(25);
+		TimeInfo info3 = new TimeInfo(packet2, returnTime);
+		Assert.assertFalse(info.equals(info3));
+
+		// 3. different class
+		Object  other = this;
+		Assert.assertFalse(info.equals(other));
+
+		// 4. null comparison
+		other = null;
+		Assert.assertFalse(info.equals(other));
+	}
+
+}

Property changes on: src/test/java/org/apache/commons/net/ntp/TestTimeInfo.java
___________________________________________________________________
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain

Index: src/test/java/org/apache/commons/net/ntp/TimeStampTest.java
===================================================================
--- src/test/java/org/apache/commons/net/ntp/TimeStampTest.java	(revision 1569890)
+++ src/test/java/org/apache/commons/net/ntp/TimeStampTest.java	(working copy)
@@ -79,4 +79,14 @@
     assertEquals(refDate, tsDate);
     }
 
+    public void testNotSame() {
+        TimeStamp time = TimeStamp.getCurrentTime();
+        Object other = Integer.valueOf(0);
+        if(time.equals(other))
+          fail("TimeStamp cannot equal Date");
+        other = null;
+        if(time.equals(other))
+        fail("TimeStamp cannot equal null");
+    }
+
 }
Index: src/main/java/org/apache/commons/net/ntp/TimeInfo.java
===================================================================
--- src/main/java/org/apache/commons/net/ntp/TimeInfo.java	(revision 1569890)
+++ src/main/java/org/apache/commons/net/ntp/TimeInfo.java	(working copy)
@@ -17,6 +17,8 @@
  */
 
 
+import java.net.DatagramPacket;
+import java.net.InetAddress;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -286,6 +288,15 @@
     }
 
     /**
+	 * Get host address from message datagram if available
+	 * @return host address of available otherwise null
+     */
+	public InetAddress getAddress() {
+		DatagramPacket pkt = _message.getDatagramPacket();
+		return pkt == null ? null : pkt.getAddress();
+	}
+
+    /**
      * Returns time at which time message packet was received by local machine.
      *
      * @return packet return time.
@@ -295,4 +306,38 @@
         return _returnTime;
     }
 
+    /**
+	 * Compares this object against the specified object.
+	 * The result is <code>true</code> if and only if the argument is
+	 * not <code>null</code> and is a <code>TimeStamp</code> object that
+	 * contains the same values as this object.
+	 *
+	 * @param   obj   the object to compare with.
+	 * @return  <code>true</code> if the objects are the same;
+	 *          <code>false</code> otherwise.
+     */
+    public boolean equals(Object obj)
+    {
+        if (this == obj)
+            return true;
+        if (obj == null || getClass() != obj.getClass())
+            return false;
+        TimeInfo other = (TimeInfo) obj;
+        return _returnTime == other._returnTime && _message.equals(other._message);
+    }
+
+    /**
+	 * Computes a hashcode for this object. The result is the exclusive
+	 * OR of the return time and the message hash code.
+	 *
+	 * @return  a hash code value for this object.
+     */
+	public int hashCode()
+	{
+		final int prime = 31;
+		int result = (int)_returnTime;
+		result = prime * result + _message.hashCode();
+		return result;
+	}
+
 }
Index: src/main/java/org/apache/commons/net/ntp/NtpV3Impl.java
===================================================================
--- src/main/java/org/apache/commons/net/ntp/NtpV3Impl.java	(revision 1569890)
+++ src/main/java/org/apache/commons/net/ntp/NtpV3Impl.java	(working copy)
@@ -89,6 +89,7 @@
 
     /***
      * Set mode as defined in RFC-1305.
+     *
      * @param mode
      */
 //    @Override
@@ -114,6 +115,7 @@
 
     /***
      * Set leap indicator as defined in RFC-1305.
+     *
      * @param li leap indicator.
      */
 //    @Override
@@ -230,6 +232,17 @@
     }
 
     /***
+     * Set root delay as defined in RFC-1305.
+     *
+     * @param delay root delay
+     */
+//    @Override
+    public void setRootDelay(int delay) 
+    {
+        setInt(ROOT_DELAY_INDEX, delay);
+    }
+
+	/**
      * Return root delay as defined in RFC-1305 in milliseconds, which is
      * the total roundtrip delay to the primary reference source, in
      * seconds. Values can take positive and negative values, depending
@@ -255,6 +268,17 @@
     }
 
     /***
+     * Set root dispersion as defined in RFC-1305.
+     *
+     * @param dispersion root dispersion
+     */
+//    @Override
+    public void setRootDispersion(int disperson) 
+    {
+        setInt(ROOT_DISPERSION_INDEX, disperson);
+    }
+
+    /***
      * Returns root dispersion (as defined in RFC-1305) in milliseconds.
      *
      * @return root dispersion in milliseconds
@@ -288,10 +312,7 @@
 //    @Override
     public void setReferenceId(int refId)
     {
-        for (int i = 3; i >= 0; i--) {
-            buf[REFERENCE_ID_INDEX + i] = (byte) (refId & 0xff);
-            refId >>>= 8; // shift right one-byte
-        }
+	setInt(REFERENCE_ID_INDEX, refId);
     }
 
     /***
@@ -489,6 +510,20 @@
     }
 
     /***
+     * Set integer value at index position.
+     *
+     * @param idx index position
+     * @param value 32-bit int value
+     */
+    private void setInt(int idx, int value)
+    {
+        for (int i=3; i >= 0; i--) {
+            buf[idx + i] = (byte) (value & 0xff);
+            value >>>= 8; // shift right one-byte
+        }
+    }
+
+	/**
      * Get NTP Timestamp at specified starting index.
      *
      * @param index index into data array
@@ -546,6 +581,9 @@
         if (dp == null) {
             dp = new DatagramPacket(buf, buf.length);
             dp.setPort(NTP_PORT);
+        } else {
+	// force Datagram payload to use byte array from this NtpPacket
+	dp.setData(buf);
         }
         return dp;
     }
@@ -553,21 +591,55 @@
     /***
      * Set the contents of this object from source datagram packet.
      *
-     * @param srcDp source DatagramPacket to copy contents from.
+     * @param srcDp source DatagramPacket to copy contents from, never null.
+     * @throws IllegalArgumentException if srcDp is null or byte length is less than minimum length of 48 bytes
      */
 //    @Override
     public void setDatagramPacket(DatagramPacket srcDp)
     {
+        if (srcDp == null || srcDp.getLength() < buf.length) throw new IllegalArgumentException();
         byte[] incomingBuf = srcDp.getData();
         int len = srcDp.getLength();
         if (len > buf.length) {
             len = buf.length;
         }
 
+        this.dp = srcDp;
         System.arraycopy(incomingBuf, 0, buf, 0, len);
     }
 
     /***
+     * Compares this object against the specified object.
+     * The result is <code>true</code> if and only if the argument is
+     * not <code>null</code> and is a <code>NtpV3Impl</code> object that
+     * contains the same values as this object.
+     *
+     * @param   obj   the object to compare with.
+     * @return  <code>true</code> if the objects are the same;
+     *          <code>false</code> otherwise.
+     */
+    public boolean equals(Object obj)
+    {
+        if (this == obj)
+            return true;
+        if (obj == null || getClass() != obj.getClass())
+            return false;
+        NtpV3Impl other = (NtpV3Impl) obj;
+        return java.util.Arrays.equals(buf, other.buf);
+    }
+
+    /***
+     * Computes a hashcode for this object. The result is the exclusive
+     * OR of the values of this object stored as a byte array.
+     *
+     * @return  a hash code value for this object.
+     */
+    public int hashCode()
+    {
+        return java.util.Arrays.hashCode(buf);
+    }
+
+    /***
      * Convert byte to unsigned integer.
      * Java only has signed types so we have to do
      * more work to get unsigned ops.
Index: src/main/java/org/apache/commons/net/ntp/NtpV3Packet.java
===================================================================
--- src/main/java/org/apache/commons/net/ntp/NtpV3Packet.java	(revision 1569890)
+++ src/main/java/org/apache/commons/net/ntp/NtpV3Packet.java	(working copy)
@@ -121,11 +121,23 @@
     public int getPrecision();
 
     /**
+     * Set precision as defined in RFC-1305
+     * @param precision Precision
+     */
+    void setPrecision(int precision);
+
+    /**
      * @return root delay as defined in RFC-1305
      */
     public int getRootDelay();
 
     /**
+     * Set root delay as defined in RFC-1305
+     * @param delay
+    */
+	void setRootDelay(int delay);
+
+    /**
      * @return root delay in milliseconds
      */
     public double getRootDelayInMillisDouble();
@@ -136,6 +148,12 @@
     public int getRootDispersion();
 
     /**
+	 *
+	 * @param disperson
+	 */
+	void setRootDispersion(int disperson);
+
+	/**
      * @return root dispersion in milliseconds
      */
     public long getRootDispersionInMillis();
@@ -153,7 +171,7 @@
     /**
      * Set version as defined in RFC-1305
      */
-    public void setVersion(int mode);
+    public void setVersion(int version);
 
     /**
      * @return stratum as defined in RFC-1305


  was:
I was the original contributor of the NTP implementation and have recently cleaned the source and submitting the relevant changes.

Here is the summary of changes:

src/main/java/org/apache/commons/net/ntp/TimeInfo.java
-Added missing equals() and hashCode() methods
-Added new method: getAddress() 

src/main/java/org/apache/commons/net/ntp/NtpV3Packet.java
-Added missing methods: setPrecision(), setRootDelay(), and setRootDispersion()

src/main/java/org/apache/commons/net/ntp/NtpV3Impl.java
-Added missing equals() and hashCode() methods
-Added missing set methods: setRootDelay(), setRootDispersion(), 
-Added validation check to setDatagramPacket()

Added additional tests:
-src/test/java/org/apache/commons/net/ntp/TestNtpPacket.java
-src/test/java/org/apache/commons/net/ntp/TestTimeInfo.java

See attached patch.


> Added missing set methods on NTP class and interface
> ----------------------------------------------------
>
>                 Key: NET-525
>                 URL: https://issues.apache.org/jira/browse/NET-525
>             Project: Commons Net
>          Issue Type: Improvement
>    Affects Versions: 3.3
>            Reporter: jason mathews
>              Labels: ntp
>
> I was the original contributor of the NTP implementation and have recently cleaned the source and submitting the relevant changes.
> Here is the summary of changes:
> src/main/java/org/apache/commons/net/ntp/TimeInfo.java
> -Added missing equals() and hashCode() methods
> -Added new method: getAddress() 
> src/main/java/org/apache/commons/net/ntp/NtpV3Packet.java
> -Added missing methods: setPrecision(), setRootDelay(), and setRootDispersion()
> src/main/java/org/apache/commons/net/ntp/NtpV3Impl.java
> -Added missing equals() and hashCode() methods
> -Added missing set methods: setRootDelay(), setRootDispersion(), 
> -Added validation check to setDatagramPacket()
> Added additional tests:
> -src/test/java/org/apache/commons/net/ntp/TestNtpPacket.java
> -src/test/java/org/apache/commons/net/ntp/TestTimeInfo.java
> See attached patch.
> Index: src/test/java/org/apache/commons/net/ntp/TestNtpPacket.java
> ===================================================================
> --- src/test/java/org/apache/commons/net/ntp/TestNtpPacket.java	(revision 0)
> +++ src/test/java/org/apache/commons/net/ntp/TestNtpPacket.java	(revision 0)
> @@ -0,0 +1,196 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements.  See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You 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 org.apache.commons.net.ntp;
> +
> +import org.junit.Test;
> +import org.junit.Assert;
> +
> +import java.net.DatagramPacket;
> +
> +/**
> + * @author Jason Mathews, MITRE Corp
> + * Date: 5/30/13 6:51 PM
> + */
> +public class TestNtpPacket {
> +
> +	// pre-canned NTP packet
> +	// [version:3, mode:4, poll:4, refId=0x81531472, precision:-17, delay:100, dispersion(ms):51.605224609375, id:129.83.20.114, xmitTime:Thu, May 30 2013 17:46:01.295, etc. ]
> +	static final byte[] ntpPacket = hexStringToByteArray("1c0304ef0000006400000d3681531472d552447fec1d6000d5524718ac49ba5ed55247194b6d9000d55247194b797000");
> +
> +	@Test
> +	public void testCreate() {
> +		NtpV3Packet message = new NtpV3Impl();
> +		message.setLeapIndicator(0);			 // byte 0 [bit numbers 7-6]
> +		message.setVersion(NtpV3Packet.VERSION_3); // byte 0 [bit numbers 5-4]
> +		message.setMode(4);						 // byte 0 [bit numbers 3-0]
> +		message.setStratum(3);					 // byte 1
> +		message.setPoll(4);					 	 // byte 2
> +		message.setPrecision(-17);				 // byte 3
> +		message.setRootDelay(100);				 // bytes 4-7
> +		message.setRootDispersion(3382);		 // bytes 8-11
> +		message.setReferenceId(0x81531472);		 // byte 12-15
> +		message.setReferenceTime(new TimeStamp(0xd552447fec1d6000L));
> +		message.setOriginateTimeStamp(new TimeStamp(0xd5524718ac49ba5eL));
> +		message.setReceiveTimeStamp(new TimeStamp(0xd55247194b6d9000L));
> +		message.setTransmitTime(new TimeStamp(0xd55247194b797000L));
> +
> +		Assert.assertEquals(-17, message.getPrecision());
> +		Assert.assertEquals(4, message.getPoll());
> +		Assert.assertEquals(100, message.getRootDelay());
> +		Assert.assertEquals(3382, message.getRootDispersion());
> +		Assert.assertEquals(0x81531472, message.getReferenceId());
> +		Assert.assertNotNull(message.getReferenceTimeStamp());
> +		Assert.assertEquals("NTP", message.getType());
> +		Assert.assertEquals("Server", message.getModeName());
> +		Assert.assertEquals("129.83.20.114", message.getReferenceIdString());
> +		Assert.assertEquals(51, message.getRootDispersionInMillis());
> +		Assert.assertEquals(message.getRootDelay() / 65.536, message.getRootDelayInMillisDouble(), 1e-13);
> +
> +		DatagramPacket dp = message.getDatagramPacket(); // this creates a new datagram
> +		Assert.assertNotNull(dp);
> +		Assert.assertEquals(48, dp.getLength()); // fixed 48-byte length
> +
> +		NtpV3Packet message2 = new NtpV3Impl();
> +		DatagramPacket dp2 = new DatagramPacket(ntpPacket, ntpPacket.length);
> +		message2.setDatagramPacket(dp2);
> +
> +		Assert.assertEquals(message2, message);
> +		Assert.assertEquals(message2.hashCode(), message.hashCode());
> +		Assert.assertEquals(message2.toString(), message.toString());
> +	}
> +
> +	@Test
> +	public void testCreateAndSetByte0() {
> +		// LI + VN + Mode all part of first byte -- make sure set order does not matter
> +		NtpV3Packet message = new NtpV3Impl();
> +
> +		message.setLeapIndicator(2);
> +		message.setMode(4);
> +		message.setVersion(NtpV3Packet.VERSION_3);
> +
> +		Assert.assertEquals(4, message.getMode());
> +		Assert.assertEquals(NtpV3Packet.VERSION_3, message.getVersion());
> +		Assert.assertEquals(2, message.getLeapIndicator());
> +
> +		message.setLeapIndicator(2);
> +		message.setVersion(NtpV3Packet.VERSION_3);
> +		message.setMode(4);
> +
> +		Assert.assertEquals(4, message.getMode());
> +		Assert.assertEquals(NtpV3Packet.VERSION_3, message.getVersion());
> +		Assert.assertEquals(2, message.getLeapIndicator());
> +
> +		message.setMode(4);
> +		message.setLeapIndicator(2);
> +		message.setVersion(NtpV3Packet.VERSION_3);
> +
> +		Assert.assertEquals(4, message.getMode());
> +		Assert.assertEquals(NtpV3Packet.VERSION_3, message.getVersion());
> +		Assert.assertEquals(2, message.getLeapIndicator());
> +
> +		message.setMode(4);
> +		message.setVersion(NtpV3Packet.VERSION_3);
> +		message.setLeapIndicator(2);
> +
> +		Assert.assertEquals(4, message.getMode());
> +		Assert.assertEquals(NtpV3Packet.VERSION_3, message.getVersion());
> +		Assert.assertEquals(2, message.getLeapIndicator());
> +
> +		message.setVersion(NtpV3Packet.VERSION_3);
> +		message.setMode(4);
> +		message.setLeapIndicator(2);
> +
> +		Assert.assertEquals(4, message.getMode());
> +		Assert.assertEquals(NtpV3Packet.VERSION_3, message.getVersion());
> +		Assert.assertEquals(2, message.getLeapIndicator());
> +
> +		message.setVersion(NtpV3Packet.VERSION_3);
> +		message.setLeapIndicator(2);
> +		message.setMode(4);
> +
> +		Assert.assertEquals(4, message.getMode());
> +		Assert.assertEquals(NtpV3Packet.VERSION_3, message.getVersion());
> +		Assert.assertEquals(2, message.getLeapIndicator());
> +	}
> +
> +	@Test
> +	public void testCreateNtpV4() {
> +		NtpV3Packet message = new NtpV3Impl();
> +		message.setVersion(NtpV3Packet.VERSION_4);
> +		message.setStratum(3);
> +		message.setReferenceId(0x81531472);
> +		// force hex-string reference id string
> +		Assert.assertEquals("81531472", message.getReferenceIdString());
> +
> +		message.setVersion(NtpV3Packet.VERSION_4);
> +		message.setStratum(1);
> +		message.setReferenceId(0x55534E4F); // USNO
> +		// force raw-string reference id string
> +		Assert.assertEquals("USNO", message.getReferenceIdString());
> +
> +		message.setReferenceId(0x47505300); // GPS
> +		Assert.assertEquals("GPS", message.getReferenceIdString());
> +	}
> +
> +	@Test
> +	public void testCreateFromBytes() {
> +		NtpV3Packet message = new NtpV3Impl();
> +		DatagramPacket dp = new DatagramPacket(ntpPacket, ntpPacket.length);
> +		message.setDatagramPacket(dp);
> +		Assert.assertEquals(4, message.getMode());
> +	}
> +
> +	@Test(expected=IllegalArgumentException.class)
> +	public void testCreateFromBadPacket() {
> +		NtpV3Packet message = new NtpV3Impl();
> +		DatagramPacket dp = new DatagramPacket(ntpPacket, ntpPacket.length-4); // drop 4-bytes from packet
> +		message.setDatagramPacket(dp);
> +	}
> +
> +	@Test(expected=IllegalArgumentException.class)
> +	public void testCreateFromNullPacket() {
> +		NtpV3Packet message = new NtpV3Impl();
> +		message.setDatagramPacket(null);
> +	}
> +
> +	@Test
> +	public void testEquals() {
> +		NtpV3Packet message1 = new NtpV3Impl();
> +		DatagramPacket dp = new DatagramPacket(ntpPacket, ntpPacket.length);
> +		message1.setDatagramPacket(dp);
> +		NtpV3Packet message2 = new NtpV3Impl();
> +		message2.setDatagramPacket(dp);
> +		Assert.assertEquals("hashCode", message1.hashCode(), message2.hashCode());
> +		Assert.assertEquals(message1, message2);
> +
> +		// now change the packet to force equals() => false
> +		message2.setMode(2);
> +		Assert.assertTrue(message1.getMode() != message2.getMode());
> +		Assert.assertFalse(message1.equals(message2));
> +	}
> +
> +	private static byte[] hexStringToByteArray(String s) {
> +		int len = s.length();
> +		byte[] data = new byte[len / 2];
> +		for (int i = 0; i < len; i += 2) {
> +			data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
> +					+ Character.digit(s.charAt(i+1), 16));
> +		}
> +		return data;
> +	}
> +
> +}
> Property changes on: src/test/java/org/apache/commons/net/ntp/TestNtpPacket.java
> ___________________________________________________________________
> Added: svn:eol-style
>    + native
> Added: svn:mime-type
>    + text/plain
> Index: src/test/java/org/apache/commons/net/ntp/TestTimeInfo.java
> ===================================================================
> --- src/test/java/org/apache/commons/net/ntp/TestTimeInfo.java	(revision 0)
> +++ src/test/java/org/apache/commons/net/ntp/TestTimeInfo.java	(revision 0)
> @@ -0,0 +1,139 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements.  See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You 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 org.apache.commons.net.ntp;
> +
> +import org.junit.Test;
> +import org.junit.Assert;
> +
> +import java.net.InetAddress;
> +import java.util.ArrayList;
> +import java.util.List;
> +
> +/**
> + * @author Jason Mathews, MITRE Corporation
> + * Date: 6/6/13 9:48 PM
> + */
> +public class TestTimeInfo {
> +
> +	@Test
> +	public void testEquals() {
> +		NtpV3Packet packet = new NtpV3Impl();
> +		final long returnTime = System.currentTimeMillis();
> +		TimeInfo info = new TimeInfo(packet, returnTime);
> +		info.addComment("this is a comment");
> +		TimeInfo other = new TimeInfo(packet, returnTime);
> +		other.addComment("this is a comment");
> +		Assert.assertEquals(info, other); // fails
> +		Assert.assertEquals(info.hashCode(), other.hashCode());
> +		other.addComment("another comment");
> +		//Assert.assertFalse(info.equals(other)); // comments not used for equality
> +
> +		TimeInfo another = new TimeInfo(packet, returnTime, new ArrayList<String>());
> +		Assert.assertEquals(info, another);
> +	}
> +
> +	@Test
> +	public void testComputeDetails() {
> +		// if (origTime > returnTime) // assert destTime >= origTime
> +		NtpV3Packet packet = new NtpV3Impl();
> +		long returnTime = System.currentTimeMillis();
> +
> +		// example
> +		// returntime=1370571658178
> +		// origTime=  1370571659178
> +
> +		// originate time as defined in RFC-1305 (t1)
> +		packet.setOriginateTimeStamp(TimeStamp.getNtpTime(returnTime + 1000));
> +		// Receive Time is time request received by server (t2)
> +		packet.setReceiveTimeStamp(packet.getOriginateTimeStamp());
> +		// Transmit time is time reply sent by server (t3)
> +		packet.setTransmitTime(packet.getOriginateTimeStamp());
> +		packet.setReferenceTime(packet.getOriginateTimeStamp());
> +
> +		//long origTime = packet.getOriginateTimeStamp().getTime();
> +		//System.out.println("returntime=" + returnTime);
> +		//System.out.println("origTime=  " + origTime);
> +
> +		TimeInfo info = new TimeInfo(packet, returnTime);
> +		info.computeDetails();
> +
> +		Assert.assertSame(packet, info.getMessage());
> +		Assert.assertEquals(returnTime, info.getReturnTime());
> +		Assert.assertEquals(Long.valueOf(500), info.getOffset());
> +		Assert.assertEquals(Long.valueOf(-1000), info.getDelay());
> +
> +		// comments: [Warning: processing time > total network time, Error: OrigTime > DestRcvTime]
> +		Assert.assertEquals(2, info.getComments().size());
> +	}
> +
> +	@Test(expected=IllegalArgumentException.class)
> +	public void testException() {
> +		NtpV3Packet packet = null;
> +		new TimeInfo(packet, 1L);
> +	}
> +
> +	@Test
> +	public void testAddress() {
> +		NtpV3Packet packet = new NtpV3Impl();
> +		TimeInfo info = new TimeInfo(packet, System.currentTimeMillis());
> +		Assert.assertNull(info.getAddress());
> +		packet.getDatagramPacket().setAddress(InetAddress.getLoopbackAddress());
> +		Assert.assertNotNull(info.getAddress());
> +	}
> +
> +	@Test
> +	public void testZeroTime() {
> +		NtpV3Packet packet = new NtpV3Impl();
> +		TimeInfo info = new TimeInfo(packet, 0);
> +		info.computeDetails();
> +		Assert.assertNull(info.getDelay());
> +		Assert.assertNull(info.getOffset());
> +		Assert.assertEquals(0L, info.getReturnTime());
> +		// comments: Error: zero orig time -- cannot compute delay/offset
> +		final List<String> comments = info.getComments();
> +		Assert.assertEquals(1, comments.size());
> +		Assert.assertTrue(comments.get(0).contains("zero orig time"));
> +	}
> +
> +	@Test
> +	public void testNotEquals() {
> +		NtpV3Packet packet = new NtpV3Impl();
> +		long returnTime = System.currentTimeMillis();
> +		TimeInfo info = new TimeInfo(packet, returnTime);
> +
> +		// 1. different return time
> +		NtpV3Packet packet2 = new NtpV3Impl();
> +		Assert.assertEquals(packet, packet2);
> +		TimeInfo info2 = new TimeInfo(packet2, returnTime + 1);
> +		Assert.assertFalse(info.equals(info2));
> +
> +		// 2. different message / same time
> +		packet2.setStratum(3);
> +		packet2.setRootDelay(25);
> +		TimeInfo info3 = new TimeInfo(packet2, returnTime);
> +		Assert.assertFalse(info.equals(info3));
> +
> +		// 3. different class
> +		Object  other = this;
> +		Assert.assertFalse(info.equals(other));
> +
> +		// 4. null comparison
> +		other = null;
> +		Assert.assertFalse(info.equals(other));
> +	}
> +
> +}
> Property changes on: src/test/java/org/apache/commons/net/ntp/TestTimeInfo.java
> ___________________________________________________________________
> Added: svn:eol-style
>    + native
> Added: svn:mime-type
>    + text/plain
> Index: src/test/java/org/apache/commons/net/ntp/TimeStampTest.java
> ===================================================================
> --- src/test/java/org/apache/commons/net/ntp/TimeStampTest.java	(revision 1569890)
> +++ src/test/java/org/apache/commons/net/ntp/TimeStampTest.java	(working copy)
> @@ -79,4 +79,14 @@
>      assertEquals(refDate, tsDate);
>      }
>  
> +    public void testNotSame() {
> +        TimeStamp time = TimeStamp.getCurrentTime();
> +        Object other = Integer.valueOf(0);
> +        if(time.equals(other))
> +          fail("TimeStamp cannot equal Date");
> +        other = null;
> +        if(time.equals(other))
> +        fail("TimeStamp cannot equal null");
> +    }
> +
>  }
> Index: src/main/java/org/apache/commons/net/ntp/TimeInfo.java
> ===================================================================
> --- src/main/java/org/apache/commons/net/ntp/TimeInfo.java	(revision 1569890)
> +++ src/main/java/org/apache/commons/net/ntp/TimeInfo.java	(working copy)
> @@ -17,6 +17,8 @@
>   */
>  
>  
> +import java.net.DatagramPacket;
> +import java.net.InetAddress;
>  import java.util.ArrayList;
>  import java.util.List;
>  
> @@ -286,6 +288,15 @@
>      }
>  
>      /**
> +	 * Get host address from message datagram if available
> +	 * @return host address of available otherwise null
> +     */
> +	public InetAddress getAddress() {
> +		DatagramPacket pkt = _message.getDatagramPacket();
> +		return pkt == null ? null : pkt.getAddress();
> +	}
> +
> +    /**
>       * Returns time at which time message packet was received by local machine.
>       *
>       * @return packet return time.
> @@ -295,4 +306,38 @@
>          return _returnTime;
>      }
>  
> +    /**
> +	 * Compares this object against the specified object.
> +	 * The result is <code>true</code> if and only if the argument is
> +	 * not <code>null</code> and is a <code>TimeStamp</code> object that
> +	 * contains the same values as this object.
> +	 *
> +	 * @param   obj   the object to compare with.
> +	 * @return  <code>true</code> if the objects are the same;
> +	 *          <code>false</code> otherwise.
> +     */
> +    public boolean equals(Object obj)
> +    {
> +        if (this == obj)
> +            return true;
> +        if (obj == null || getClass() != obj.getClass())
> +            return false;
> +        TimeInfo other = (TimeInfo) obj;
> +        return _returnTime == other._returnTime && _message.equals(other._message);
> +    }
> +
> +    /**
> +	 * Computes a hashcode for this object. The result is the exclusive
> +	 * OR of the return time and the message hash code.
> +	 *
> +	 * @return  a hash code value for this object.
> +     */
> +	public int hashCode()
> +	{
> +		final int prime = 31;
> +		int result = (int)_returnTime;
> +		result = prime * result + _message.hashCode();
> +		return result;
> +	}
> +
>  }
> Index: src/main/java/org/apache/commons/net/ntp/NtpV3Impl.java
> ===================================================================
> --- src/main/java/org/apache/commons/net/ntp/NtpV3Impl.java	(revision 1569890)
> +++ src/main/java/org/apache/commons/net/ntp/NtpV3Impl.java	(working copy)
> @@ -89,6 +89,7 @@
>  
>      /***
>       * Set mode as defined in RFC-1305.
> +     *
>       * @param mode
>       */
>  //    @Override
> @@ -114,6 +115,7 @@
>  
>      /***
>       * Set leap indicator as defined in RFC-1305.
> +     *
>       * @param li leap indicator.
>       */
>  //    @Override
> @@ -230,6 +232,17 @@
>      }
>  
>      /***
> +     * Set root delay as defined in RFC-1305.
> +     *
> +     * @param delay root delay
> +     */
> +//    @Override
> +    public void setRootDelay(int delay) 
> +    {
> +        setInt(ROOT_DELAY_INDEX, delay);
> +    }
> +
> +	/**
>       * Return root delay as defined in RFC-1305 in milliseconds, which is
>       * the total roundtrip delay to the primary reference source, in
>       * seconds. Values can take positive and negative values, depending
> @@ -255,6 +268,17 @@
>      }
>  
>      /***
> +     * Set root dispersion as defined in RFC-1305.
> +     *
> +     * @param dispersion root dispersion
> +     */
> +//    @Override
> +    public void setRootDispersion(int disperson) 
> +    {
> +        setInt(ROOT_DISPERSION_INDEX, disperson);
> +    }
> +
> +    /***
>       * Returns root dispersion (as defined in RFC-1305) in milliseconds.
>       *
>       * @return root dispersion in milliseconds
> @@ -288,10 +312,7 @@
>  //    @Override
>      public void setReferenceId(int refId)
>      {
> -        for (int i = 3; i >= 0; i--) {
> -            buf[REFERENCE_ID_INDEX + i] = (byte) (refId & 0xff);
> -            refId >>>= 8; // shift right one-byte
> -        }
> +	setInt(REFERENCE_ID_INDEX, refId);
>      }
>  
>      /***
> @@ -489,6 +510,20 @@
>      }
>  
>      /***
> +     * Set integer value at index position.
> +     *
> +     * @param idx index position
> +     * @param value 32-bit int value
> +     */
> +    private void setInt(int idx, int value)
> +    {
> +        for (int i=3; i >= 0; i--) {
> +            buf[idx + i] = (byte) (value & 0xff);
> +            value >>>= 8; // shift right one-byte
> +        }
> +    }
> +
> +	/**
>       * Get NTP Timestamp at specified starting index.
>       *
>       * @param index index into data array
> @@ -546,6 +581,9 @@
>          if (dp == null) {
>              dp = new DatagramPacket(buf, buf.length);
>              dp.setPort(NTP_PORT);
> +        } else {
> +	// force Datagram payload to use byte array from this NtpPacket
> +	dp.setData(buf);
>          }
>          return dp;
>      }
> @@ -553,21 +591,55 @@
>      /***
>       * Set the contents of this object from source datagram packet.
>       *
> -     * @param srcDp source DatagramPacket to copy contents from.
> +     * @param srcDp source DatagramPacket to copy contents from, never null.
> +     * @throws IllegalArgumentException if srcDp is null or byte length is less than minimum length of 48 bytes
>       */
>  //    @Override
>      public void setDatagramPacket(DatagramPacket srcDp)
>      {
> +        if (srcDp == null || srcDp.getLength() < buf.length) throw new IllegalArgumentException();
>          byte[] incomingBuf = srcDp.getData();
>          int len = srcDp.getLength();
>          if (len > buf.length) {
>              len = buf.length;
>          }
>  
> +        this.dp = srcDp;
>          System.arraycopy(incomingBuf, 0, buf, 0, len);
>      }
>  
>      /***
> +     * Compares this object against the specified object.
> +     * The result is <code>true</code> if and only if the argument is
> +     * not <code>null</code> and is a <code>NtpV3Impl</code> object that
> +     * contains the same values as this object.
> +     *
> +     * @param   obj   the object to compare with.
> +     * @return  <code>true</code> if the objects are the same;
> +     *          <code>false</code> otherwise.
> +     */
> +    public boolean equals(Object obj)
> +    {
> +        if (this == obj)
> +            return true;
> +        if (obj == null || getClass() != obj.getClass())
> +            return false;
> +        NtpV3Impl other = (NtpV3Impl) obj;
> +        return java.util.Arrays.equals(buf, other.buf);
> +    }
> +
> +    /***
> +     * Computes a hashcode for this object. The result is the exclusive
> +     * OR of the values of this object stored as a byte array.
> +     *
> +     * @return  a hash code value for this object.
> +     */
> +    public int hashCode()
> +    {
> +        return java.util.Arrays.hashCode(buf);
> +    }
> +
> +    /***
>       * Convert byte to unsigned integer.
>       * Java only has signed types so we have to do
>       * more work to get unsigned ops.
> Index: src/main/java/org/apache/commons/net/ntp/NtpV3Packet.java
> ===================================================================
> --- src/main/java/org/apache/commons/net/ntp/NtpV3Packet.java	(revision 1569890)
> +++ src/main/java/org/apache/commons/net/ntp/NtpV3Packet.java	(working copy)
> @@ -121,11 +121,23 @@
>      public int getPrecision();
>  
>      /**
> +     * Set precision as defined in RFC-1305
> +     * @param precision Precision
> +     */
> +    void setPrecision(int precision);
> +
> +    /**
>       * @return root delay as defined in RFC-1305
>       */
>      public int getRootDelay();
>  
>      /**
> +     * Set root delay as defined in RFC-1305
> +     * @param delay
> +    */
> +	void setRootDelay(int delay);
> +
> +    /**
>       * @return root delay in milliseconds
>       */
>      public double getRootDelayInMillisDouble();
> @@ -136,6 +148,12 @@
>      public int getRootDispersion();
>  
>      /**
> +	 *
> +	 * @param disperson
> +	 */
> +	void setRootDispersion(int disperson);
> +
> +	/**
>       * @return root dispersion in milliseconds
>       */
>      public long getRootDispersionInMillis();
> @@ -153,7 +171,7 @@
>      /**
>       * Set version as defined in RFC-1305
>       */
> -    public void setVersion(int mode);
> +    public void setVersion(int version);
>  
>      /**
>       * @return stratum as defined in RFC-1305



--
This message was sent by Atlassian JIRA
(v6.1.5#6160)