@@ -258,12 +258,20 @@ func queryV5(conn net.Conn, opt *QueryOptions) (*Response, error) {
258258 if err != nil {
259259 return nil , err
260260 }
261+ recvBuf = recvBuf [:n ]
261262
262263 // Keep track of the time the response message was received.
263264 clientRecvTime := opt .GetSystemTime ()
264265
266+ // Allow package extensions to process the response message.
267+ for i := len (opt .Extensions ) - 1 ; i >= 0 ; i -- {
268+ err = opt .Extensions [i ].ProcessResponse (recvBuf )
269+ if err != nil {
270+ return nil , err
271+ }
272+ }
273+
265274 // Parse the response message.
266- recvBuf = recvBuf [:n ]
267275 m , err := parseV5Response (recvBuf )
268276 if err != nil {
269277 return nil , err
@@ -280,29 +288,22 @@ func queryV5(conn net.Conn, opt *QueryOptions) (*Response, error) {
280288 return nil , ErrServerResponseMismatch
281289 }
282290
283- // Prepare the response struct.
284- r := & Response {
285- Version : 5 ,
286- }
287-
288- // Check for an authentication NAK.
289- if m .Flags & flagAuthNAK != 0 {
290- r .authErr = ErrAuthNAK
291- }
292-
293- // Convert timestamps.
291+ // Convert timestamps to times.
294292 serverRecvTime := timestamp (m .ReceiveTime ).Time (m .Era )
295293 serverXmitTime := timestamp (m .TransmitTime ).Time (m .Era )
296294
297- // Start filling in response fields.
298- r .Time = serverXmitTime
299- r .Precision = toInterval (m .Precision )
300- r .Stratum = m .Stratum
301- r .Leap = m .getLeap ()
302- r .Poll = toInterval (m .Poll )
303- r .Timescale = Timescale (m .Timescale )
304- r .Era = m .Era
305- r .ServerCookie = m .ServerCookie
295+ // Prepare the response struct.
296+ r := & Response {
297+ Time : serverXmitTime ,
298+ Precision : toInterval (m .Precision ),
299+ Version : 5 ,
300+ Stratum : m .Stratum ,
301+ Timescale : Timescale (m .Timescale ),
302+ Era : m .Era ,
303+ Leap : m .getLeap (),
304+ Poll : toInterval (m .Poll ),
305+ ServerCookie : m .ServerCookie ,
306+ }
306307
307308 // Determine response flags.
308309 if m .Flags & flagSynchronized != 0 {
@@ -312,36 +313,24 @@ func queryV5(conn net.Conn, opt *QueryOptions) (*Response, error) {
312313 r .Flags |= FlagInterleaved
313314 }
314315
315- // Assign brief timestamp and correction variables for readability (will
316- // be optimized away).
316+ // Check for an authentication NAK.
317+ if m .Flags & flagAuthNAK != 0 {
318+ r .authErr = ErrAuthNAK
319+ }
320+
321+ // Assign brief timestamp variables for readability (will be optimized
322+ // away).
317323 t1 := clientXmitTime
318324 t2 := serverRecvTime
319325 t3 := serverXmitTime
320326 t4 := clientRecvTime
321- c0 := r .Correction .OriginDelay
322- c1 := r .Correction .ReturnDelay
323-
324- // Handle unrepresentable or negative delay corrections by ignoring them.
325- validCorrection := true
326- if c0 == DelayUnrepresentable || c1 == DelayUnrepresentable || c0 < 0 || c1 < 0 {
327- validCorrection = false
328- }
329327
330328 // Calculate the uncorrected clock offset.
331329 r .ClockOffset = (t2 .Sub (t1 ) + t3 .Sub (t4 )) / 2
332330
333331 // Calculate the uncorrected round-trip time.
334332 r .RTT = max (t4 .Sub (t1 )- t3 .Sub (t2 ), 0 )
335333
336- // If valid correction values are present, adjust the offset and RTT.
337- if validCorrection {
338- rtt := r .RTT - time .Duration (float64 (c0 + c1 )* (1.0 - maxFrequencyError ))
339- if rtt >= 0 {
340- r .RTT = rtt
341- r .ClockOffset += (c1 - c0 ) / 2
342- }
343- }
344-
345334 // Calculate root dispersion and distance.
346335 r .RootDelay = m .RootDelay .Duration ()
347336 r .RootDispersion = m .RootDisp .Duration ()
@@ -399,6 +388,15 @@ func queryV5(conn net.Conn, opt *QueryOptions) (*Response, error) {
399388 r .Correction .OriginPathID = binary .BigEndian .Uint16 (body [8 :10 ])
400389 r .Correction .ReturnDelay = timeCorrectionV5 (binary .BigEndian .Uint64 (body [12 :20 ])).Duration ()
401390 r .Correction .ReturnPathID = binary .BigEndian .Uint16 (body [20 :22 ])
391+ c0 := r .Correction .OriginDelay
392+ c1 := r .Correction .ReturnDelay
393+ if c0 >= 0 && c1 >= 0 {
394+ rtt := r .RTT - time .Duration (float64 (c0 + c1 )* (1.0 - maxFrequencyError ))
395+ if rtt >= 0 {
396+ r .RTT = rtt
397+ r .ClockOffset += (c1 - c0 ) / 2
398+ }
399+ }
402400
403401 case extRefTimestamp :
404402 if len (body ) != 8 {
@@ -435,14 +433,6 @@ func queryV5(conn net.Conn, opt *QueryOptions) (*Response, error) {
435433 curr = recvBuf [offset :]
436434 }
437435
438- // Allow package extensions to process the response.
439- for i := len (opt .Extensions ) - 1 ; i >= 0 ; i -- {
440- err = opt .Extensions [i ].ProcessResponse (recvBuf )
441- if err != nil {
442- return nil , err
443- }
444- }
445-
446436 return r , r .authErr
447437}
448438
0 commit comments