Subject: [ntpwg] IPv6 REFIDs

From: Harlan Stenn <[email-masked]>
Date: Sat, 23 May 2015 19:32:47 +0000

Folks,

We're seeing complaints and confusion because using a 32-bit hash of an
IPv6 address for a refid will display as a perfectly resonable IPv4
address.

I'm recommending we change this to either using a 24-bit hash with the
first octet being 255, or if we really think it's worthwhile, reserve
the top 5 bits (11110xxx) and use 27 bits for the hash.  Or perhaps use
the top 4 bits (1111xxxx) and use 28 bits for the hash.

Can we get some discussion about this and add it to the agenda for the
meeting on 4 June?
-- 
Harlan Stenn <[email-masked]>
http://networktimefoundation.org  - be a member!
_______________________________________________
ntpwg mailing list
[email-masked]
http://lists.ntp.org/listinfo/ntpwg

---

From: Miroslav Lichvar <[email-masked]>
Date: Mon, 25 May 2015 09:21:12 +0200

> IPv6 address for a refid will display as a perfectly resonable IPv4

Yes, this seems to be quite confusing for users. Would it make sense
to display refid values (for stratum > 1) as a hexadecimal number
instead of the quad dotted notation to prevent that confusion?

> the top 4 bits (1111xxxx) and use 28 bits for the hash.

Wouldn't that be an incompatible change in the protocol, breaking the
detection of synchronization loops?

If peer A using the new refid definition was synchronized to peer B
using the old 32-bit hash, peer B wouldn't be able to tell that A
is synchronized to it.
 
-- 
Miroslav Lichvar

---

From: Harlan Stenn <[email-masked]>
Date: Mon, 25 May 2015 21:20:51 +0000

> instead of the quad dotted notation to prevent that confusion?

It will still be confusing if a random IPv6 hash decodes to a valid IPv4
hash.

> using the old 32-bit hash, peer B wouldn't be able to tell that A

We don't have good loop detection on machines with multiple network
interfaces already.  This proposal does not make that situation worse.

It sheds light on the question "what is a loop?"  Is there a loop if you
get time from different sources that use the same model/firmware of a
GPS receiver?

H

---

From: Rob Seaman <[email-masked]>
Date: Mon, 25 May 2015 16:37:01 -0700

> the top 4 bits (1111xxxx) and use 28 bits for the hash.

There are discussions going back a dozen years advocating limiting the
hash to the Class E address space.  This is equivalent to Harlan’s last
suggestion.  It appears this got lost along the way for:

	"first four octets of the MD5 hash of the IPv6 address”

Any idea when that happened?

Rob Seaman
[email-masked]

---

From: "Ulrich Windl" <[email-masked]>
Date: Tue, 26 May 2015 08:21:49 +0200

>>> Miroslav Lichvar <[email-masked]> schrieb am 25.05.2015 um 09:21 in
> detection of synchronization loops?

I wonder whether it would have bee the right decision to include the address family (like AF_INET, AF_INET6) in the protocol when moving to IPv6. Obviously you cannot map the union of IPv4 and IPv6 addresses into IPv4 addresses in a way where you can clearly see whether it was IPv4 or IPv6, not to talk about the actual IPv6 address.

Maybe NTP should use some pseudo IPv4 address (as used for reference clocks) in cases where IPv6 is used AND add an extension field where the mapping to the true IPv6 address is explained.

> using the old 32-bit hash, peer B wouldn't be able to tell that A

Yes, it's always best to start correctly ;-)

Regards,
Ulrich Windl

---

From: Harlan Stenn <[email-masked]>
Date: Tue, 26 May 2015 08:34:45 +0000

"Ulrich Windl" writes:
> Miroslav wrote:

Yes, and sometimes that is impossible.

Sometimes there are Good Reasons to upgrade software.

---

From: Miroslav Lichvar <[email-masked]>
Date: Tue, 26 May 2015 10:34:44 +0200

> It will still be confusing if a random IPv6 hash decodes to a valid IPv4

If the refid was handled as a random number and not an IPv4 address,
what exactly would be confusing?

With IPv6 addresses collisions in the hash are expected to happen
and if the space was reduced from 32 bits to 27-28 bits, they will be
even more likely.

> interfaces already. 

I think that is a problem of the implementation, independent from
refid definition. ntpd tracks addresses of local interfaces, so it
could check the peer refid against all of them and not just the one
used to send packets to the peer.

> This proposal does not make that situation worse.

I think it does. It makes collisions more likely and it breaks the
loop detection completely between peers using different definition of
refid.

> get time from different sources that use the same model/firmware of a

In my understanding a synchronization loop happens when a server is
synchronized to itself through other servers and then all of them
drift away until one of them reselects due to the increase in stratum
or root distance. In a directed graph representing NTP synchronization
it's a cycle.

In NTPv3 cycles of any length were prevented reliably by simply not
accepting sources with higher stratum than local. But it was too
restrictive and it was removed in NTPv4. It seems to me the refid
field is now the only thing that prevents cycles and only for length
of 2.

---

From: Miroslav Lichvar <[email-masked]>
Date: Tue, 26 May 2015 10:47:08 +0200

> Maybe NTP should use some pseudo IPv4 address (as used for reference clocks) in cases where IPv6 is used AND add an extension field where the mapping to the true IPv6 address is explained.

I think the best solution depends on how many bytes are we willing to
allocate for it in the NTP packet. Ideally, the server would announce
its own randomly generated refid and send also refids of all upstream
sources. All loops could be detected and it would also reliably fix
the problem with NTP clients unknowingly using the same server
multiple times with different addresses.

---

From: Harlan Stenn <[email-masked]>
Date: Tue, 26 May 2015 18:46:04 +0000

Danny Mayer writes:
> I've been reading all of these responses and concluded that you are all
> nuts! :)
> 
> The subject line itself is an oxymoron (a self-contradiction). There is
> no such thing as an IPv6 RefID or an IPv4 RefID. There is only a RefID.
> The reference implementation happened to use an IPv4 address as the
> RefID and that was wrong but it got got worse with IPv6. In reality a
> system should have one and only one RefID so that no matter which IP
> address is used the same RefID will be emitted in the packet. People
> have been saying that using the address as the RefID is helpful to them
> for tracing back where the timestamp originated which is not the purpose
> of the RefID. The RefID is described in Section 7.3 of RFC5905. To quote
> from that section:
> 
> "Above stratum 1 (secondary servers and clients): this is the reference
> identifier of the server and can be used to detect timing loops."
> 
> Beyond that it talks about IPv4 and IPv6 addresses and that should be
> updated to remove that from that document. The RefID should just be any
> 32-bit unsigned integer which would used on ALL interfaces for that
> system and could be a random number generated every time the system is
> restarted. We do need to detect timing loops but not pretend that the
> RefID is an actual IP address.

Of course you are correct.  And 30 years ago the easiest way to identify
a machine was by its IPv4 address.

Using anything else would involve a "dance" to make sure that the refid
you chose was not being used by at least your neighbor's neighbors.

I think this topic needs more documentation.

There are a variety of different problems here, some worse than others.

If "A" is sending time to B and several other machines, and somebody
jumps in there and gets time from A and B, what are the various
scenarios where this new machine would not want to get time from either
A or B because "it's kind of a loop"?  What if the time from B is
"better" than the time directly from A?

What about the case where there are multiple network paths and A wants
to detect that some of its peers  are getting time from A?

There is a difference between "I think I have >N sources of time" and
discovering that's not really the case because some sources are sync'd
to the same upstream, and "because of poll times, etc, am I part of a
loop/cycle of machines that follows itself?"

Do I want to follow completely different computers each of which is
getting its time from a GPS that is "the same" as the other computers,
or do I want to make sure that I'm getting my time from a variety of
upstream sources?  On those upstream sources, each of those ends up at
an S0, if you follow my intent, so is that a loop or is that just the
"ultimate source"?

This is stuff the Wizards understand and the protocol is designed to
prevent at least the obvious problems.

The concept of a REFID was clearly understood and reasonably
implemented, for the time this was done.  The concept of a "loop" is
also more complicated.

I'd love to have this usefully documented so more folks could understand
the issues.
-- 
Harlan Stenn <[email-masked]>
http://networktimefoundation.org - be a member!

---

From: Danny Mayer <[email-masked]>
Date: Tue, 26 May 2015 15:13:11 -0400

Danny

---

From: Danny Mayer <[email-masked]>
Date: Tue, 26 May 2015 14:10:04 -0400

Danny

---

From: "Ulrich Windl" <[email-masked]>
Date: Wed, 27 May 2015 08:20:38 +0200

>>> Danny Mayer <[email-masked]> schrieb am 26.05.2015 um 20:10 in
> system should have one and only one RefID so that no matter which IP

s/system/clock source/: Don't do reference clocks have their own reference ID (from 127/8 range)? Well with IPv4 in mind there's nothing wrong to restrict the ID to 32 bit and while you have the routines mimic as IPv4 addresses, but as you said, for IPv6 this fails in several aspects.

> of the RefID. The RefID is described in Section 7.3 of RFC5905. To quote

Well, it depends on "where": If you just want to compare for equality, you can find out whether your servers get their time from the "same" source, however not saying which it actually is.

> identifier of the server and can be used to detect timing loops."

Another important question would be this (having no concrete implementation in mind): Will the ref ID be stable across restarts of the NTP daemon? If you one could use just some random ID, or a node-id based UUID (which is longer than 32 bit).

> updated to remove that from that document. The RefID should just be any

The other thing is that you can still use NTPv3 tools to process NTPv4 (control) responses, and (as said before) this will fail, because NTPv3 tools make invalid assumptions about the packets, and (probably worse) the control message protocol has no mechanism (yet) to find out whether it's NTPv3 or NTPv4 spoken in the server.

> RefID is an actual IP address.

Well one people believed 32 bit is enough for the world, later came GIDs (EUI-64, 64 bit) which should be enough for the globe, and then there are UUIDs (which are believed to be really enough).

So there is a very small likelihood that the ref id will be non unique when departing from the original "NTPv3 IPv4 32-bit ref id" schema. Personally I believe with IPv6 we simple need more bits. Everything else is just a work-around.

Regards,
Ulrich

---

From: "Ulrich Windl" <[email-masked]>
Date: Wed, 27 May 2015 08:28:07 +0200

>>> Harlan Stenn <[email-masked]> schrieb am 26.05.2015 um 20:46 in Nachricht
> Danny Mayer writes:

[...]
> implemented, for the time this was done.  The concept of a "loop" is

I think, best solution would be a two-step approach:

1) Define what a "loop" is, (and why to avoid such)

2) Invent a mechanism how to avoid those

However 1) may not rely on 2), because then we would have a loop ;-)

[...]

Regards,
Ulrich

---

From: Miroslav Lichvar <[email-masked]>
Date: Thu, 28 May 2015 09:18:27 +0200

> "better" than the time directly from A?

I'm not sure this case would be described as a synchronization loop.
There are multiple paths to the same time source, but there is no
cycle and no source is synchronized to itself here.

> to detect that some of its peers  are getting time from A?

The solution I think is the same as for detecting loops. Each server
would need to send in replies to client/peers its own (randomly
generated) refid and also refids of the chain of its upstream sources
up to stratum 1. The clients would then have a complete description of
the network and could detect any loops or multiple paths to the same
source.

If this was implemented as an NTP extension using 32-bit refids and
sending them all at once, it would take 4 + 15 * 4 = 64 bytes in the
worst case of a stratum 15 server. That would more than double the
size of the NTP packet and there would be a problem with traffic
amplification.

To save some bandwidth, the extension field could be limited to
contain only 3 refids (this would make it a minimal extension field
of 16 bytes) and the clients would request in which strata they are
interested. Over several iterations they would get the complete chain
of refids.

---

From: "Ulrich Windl" <[email-masked]>
Date: Thu, 28 May 2015 10:34:14 +0200

>>> Miroslav Lichvar <[email-masked]> schrieb am 28.05.2015 um 09:18 in
> size of the NTP packet and there would be a problem with traffic

If the 32-bit ref id is no IPv4 address, why not try this:
stratum-1 server takes the ref id of it sync peer (whatever that is) and hashes it with ist own id (whatever it is) like IPv4_of (md5(my_ref_id, peer_ref_id)).
Then the server using that stratum-1 server would do the same (hash its own id with the id of ist current peer)
With this schema the refid of a server would change, however if ist sync source changed (recursively). As said before, it all depends on how you would define a sync loop.

If you like the server could hash not just ist primary source ('*'), but all sync candidates ('+')...

> interested. Over several iterations they would get the complete chain

I think people will not like the idea of servers changing ref ids while running ;-)

Regards,
Ulrich

---

From: Miroslav Lichvar <[email-masked]>
Date: Thu, 28 May 2015 12:02:31 +0200

> With this schema the refid of a server would change, however if ist sync source changed (recursively). As said before, it all depends on how you would define a sync loop.

This would be only able to detect identical paths to a stratum 1
source over different addresses, or not? If there was a loop the refid
would change with every iteration and the server wouldn't be tell the
upstream refid was already hashed with its own.

> I think people will not like the idea of servers changing ref ids while running ;-)

Yes, ideally refid of a server would be constant and independent from
any addressing. The question is how to distribute it in the network.

Anyway, a new refid system would probably need to be separate from the
current one to not break compatibility with older implementations.

---

From: "Ulrich Windl" <[email-masked]>
Date: Thu, 28 May 2015 12:48:20 +0200

>>> Miroslav Lichvar <[email-masked]> schrieb am 28.05.2015 um 12:02 in
Nachricht <20150528100231.GV19470@localhost>:
>> stratum-1 server takes the ref id of it sync peer (whatever that is) and 
> hashes it with ist own id (whatever it is) like IPv4_of (md5(my_ref_id, 
> peer_ref_id)).
>> With this schema the refid of a server would change, however if ist sync 
> source changed (recursively). As said before, it all depends on how you would 
> define a sync loop.
> 

In my view the same server synced to the same sources (recursively) would show the same ref id, so you could prevent using the same server via different network paths, but, depending on the definition of a loop, a server cannot detect whether its source used itself a source.
But with the definition from the previous message (a server S syncing from A is not having a loop if A is synching from S and another source).

An interesting question is what is considered to be the "seed" of a server's time: is it just the reference clock at the statum-1 server, or is it the set of all participating servers? Pure graph theory would prefer the first variant. Depending on what you prefer, the definition of loop is different.

> current one to not break compatibility with older implementations.

"compatibility for ref ids" is still to be defined ;-)

Regards,
Ulrich

---

From: Danny Mayer <[email-masked]>
Date: Thu, 28 May 2015 08:36:08 -0400

On 5/27/2015 2:20 AM, Ulrich Windl wrote:
> s/system/clock source/: Don't do reference clocks have their own
reference ID (from 127/8 range)? Well with IPv4 in mind there's nothing
wrong to restrict the ID to 32 bit and while you have the routines mimic
as IPv4 addresses, but as you said, for IPv6 this fails in several aspects.

Reference Clocks are defined separately in the RFC and are for Stratum 1
only. These RefID's are for Stratum 2 and greater.

While it was okay to use an IPv4 address at the time since server
usually only had one interface and one IP address it totally fails today
when almost all systems have multiple interfaces and even more IP
addresses. Even worse than this is that the RefID was formatted as an
IPv4 address even though that was never its purpose.

> Well, it depends on "where": If you just want to compare for
> equality,
you can find out whether your servers get their time from the "same"
source, however not saying which it actually is.

And this strategy is failing today because the server uses a different
ID for each IP address. The server needs to use one and only one RefID
for ALL interface addresses so that if a receiving server gets packets
from two different IP addresses it can recognize that they come from the
same server. An obvious example is if one packet is sent from an IPv4
address and another from an IPv6 address, how do you know they came from
the same system?

> Another important question would be this (having no concrete
implementation in mind): Will the ref ID be stable across restarts of
the NTP daemon? If you one could use just some random ID, or a node-id
based UUID (which is longer than 32 bit).

I think that it should be a randomly generated ID and change with each
restart so that it would be considered a different system for the
purposes of checking.

> The other thing is that you can still use NTPv3 tools to process
> NTPv4
(control) responses, and (as said before) this will fail, because NTPv3
tools make invalid assumptions about the packets, and (probably worse)
the control message protocol has no mechanism (yet) to find out whether
it's NTPv3 or NTPv4 spoken in the server.

While one should use NTPv3 tools with NTPv4 servers it really doesn't
matter since the refID is for display only.
> Well one people believed 32 bit is enough for the world, later came
GIDs (EUI-64, 64 bit) which should be enough for the globe, and then
there are UUIDs (which are believed to be really enough).
> 
> So there is a very small likelihood that the ref id will be non
> unique
when departing from the original "NTPv3 IPv4 32-bit ref id" schema.
Personally I believe with IPv6 we simple need more bits. Everything else
is just a work-around.

While it is possible to change this I don't think that the number of
bits is an issue here. It's not about routing packets.

Danny

---

From: Harlan Stenn <[email-masked]>
Date: Fri, 29 May 2015 05:07:49 +0000

I hope I'm not too tired to be writing this.

There is something to be said for not changing the refid until NTPv5.

There is also a cost for that choice.

Similarly, there is something to be said for changing it now, in NTPv4.
There is a cost for this choice, too.

There are good number of tradeoffs no matter what we do.  To put it a
slightly different way, there are clear costs and benefits to each
choice, and there are good number of choices.

This includes the situation where we decide to use a random number for
each refid.  In that case the odds are probably small that any peer to,
say, 3 degrees (do we need to go to 4?) will be in conflict.

I'm loathe to say "then let's have a config file option to specify the
UID" because that turns in to another maintenance headache.

I'm liking, more and more, the idea where we at least look at a
situation where we see if we can do a "data exchange" between the N
degrees of associations we care about to see if there is a collision,
and hosts with colliding refids can generate new ones and re-check.

I'm sure there are problems with this idea too.  I wonder about how it
could be abused.

I can see that things get better (for NTF's NTP Reference
Implementation, at least) once http://bugs.ntp.org/2778 gets fixed.

RFC5905 probably needs to be changed - the premise that:

 Above stratum 1 (secondary servers and clients): this is the
 reference identifier of the server and can be used to detect timing
 loops.  If using the IPv4 address family, the identifier is the four-
 octet IPv4 address.  If using the IPv6 address family, it is the
 first four octets of the MD5 hash of the IPv6 address.  Note that,
 when using the IPv6 address family on an NTPv4 server with a NTPv3
 client, the Reference Identifier field appears to be a random value
 and a timing loop might not be detected.

sure looks wrong to me - will we detct a timing loop if one path is thru
the IPv4 address and the other is thru the IPv6 address?

I'm also not sure how there will be more confusion to an NTPv3 host that
sees a refid that comes from an IPv6 upstream.  I'm not aware of anybody
who has implemented NTPv3 on IPv6 machines.  But maybe somebody has.  If
so, they would have solved this problem, right?

We don't want to use the first 4 octets of the MD5 hash of the IPv6
address.  I'm liking the idea of using at least the first 4 bits as 1s
for an IPv6 refid more and more.

I can see saying for this host's refid, use the refid value calculation
we agree on for all interfaces/associations from a host based on:

- a non-local IPv6 or non-RFC1918 IPv4 address, and if we can't find one,
- the first non-host-local IPv6 or RFC1918 IPv4 address

I'm sure the above definitions can be improved.

Q: If the interface we got the above address on goes down, should we
come up with a new refid?  I currently think so.

Q: If an interface comes up, should we re-run the above refid selection
process?  I currently think so.

And now I'm again wondering *exactly* what do we mean by a 'timing
loop'.

I see no problem with changing a host's refid during the operational
lifetime of the associations it has.  While there might be some
confusion for a while, that will sort itself out over the course of a
few poll intervals, right?
-- 
Harlan Stenn <[email-masked]>
http://networktimefoundation.org - be a member!
_______________________________________________
ntpwg mailing list
[email-masked]
http://lists.ntp.org/listinfo/ntpwg

---

From: "Ulrich Windl" <[email-masked]>
Date: Fri, 29 May 2015 09:24:11 +0200

>>> Harlan Stenn <[email-masked]> schrieb am 29.05.2015 um 07:07 in Nachricht
> I hope I'm not too tired to be writing this.

Hi!

> UID" because that turns in to another maintenance headache.

Also people may be copying such files without thinking enough, creating duplicate UIDs...

> degrees of associations we care about to see if there is a collision,

I'm nur quite sure what your "N degrees" are: Is it width or depth, i.e. are you examining N sources, or every source N nodes deep? It seems you are talking about depth, however...

>  octet IPv4 address.  If using the IPv6 address family, it is the

"address" of what, BTW? If you have mltiple interfaces, this definition keeps you standing in the rain (so to say).

>  first four octets of the MD5 hash of the IPv6 address.  Note that,

(same remark on "address")

>  and a timing loop might not be detected.

That's also confusing, because the reason in not that the ID seems random, but it might not be "really unique". Maybe the text should clarify that.

> the IPv4 address and the other is thru the IPv6 address?

No, just as if you use the same server through different (IPv4) interfaces, I guess.

> so, they would have solved this problem, right?

AFAIK HP-UX 11.31 still shipped the old xntp3 while claiming to support IPv6. I don't know the details, because we retired our HP-UX machines.

> for an IPv6 refid more and more.

If so, explain in detail what the four ones make it special, and let me remark from my personal experience that there is a high probability of MD5 having collision if you only pick a few bytes. maybe just use that number of bytes, but XOR every other bytes from MD5 with that.

Maybe you want to simulate that.

> we agree on for all interfaces/associations from a host based on:

(that tsentence is hard to understand (for me))

> come up with a new refid?  I currently think so.

Maybe if the system has a "nodeid" it should be used (assuming there won't be multiple independent NTP daemons running on one node). Some machines also have UUIDs that can be queried.

> process?  I currently think so.

I think it depends on which interface. However if the ID should be a "daemon ID" instead of a "NIC ID" I don't see why.

> And now I'm again wondering *exactly* what do we mean by a 'timing

Yes. Let's formalize it! Really.

> few poll intervals, right?

Maybe some people will believe in a man-in-the-middle-attack seeing such?

Regards,
Ulrich

---

From: Danny Mayer <[email-masked]>
Date: Fri, 29 May 2015 12:21:41 -0400

> There is something to be said for not changing the refid until NTPv5.
Why? Nothing in the code cares about the actual value as long as it can
be compared. It's just a 32 bit number.

> There is also a cost for that choice.

There is zero cost unless you want to change ntpq as well.

> There is a cost for this choice, too.

See above.

> and hosts with colliding refids can generate new ones and re-check.

If you generate a random 32-bit number that's one chance in 4 billion.

> the IPv4 address and the other is thru the IPv6 address?

We don't detect the timing loop through the IP address, we detect a
timing loop through the RefID which could be anything.

> so, they would have solved this problem, right?

Why does that matter? It's just a number. If you look at the reference
implementation the peer_unfit() function in ntp_proto.c just uses it as
a number of loop detection.

> - the first non-host-local IPv6 or RFC1918 IPv4 address

None of the above. The RefID needs to be the same for all interfaces and
IP addresses otherwise your loop detection algorithm will fail to find
if it's the same server.

> come up with a new refid?  I currently think so.

If you use a random number for the RefID just generate a new random number.

> process?  I currently think so.

No, See above.

> And now I'm again wondering *exactly* what do we mean by a 'timing

See the reference implementation mentioned above.

> few poll intervals, right?

Why would you want to change the RefID while it's up? Is there a reason
to do so? You have potential problems with detecting timing loops if you
did so.

Danny

---

From: Harlan Stenn <[email-masked]>
Date: Fri, 29 May 2015 21:31:47 +0000

> be compared. It's just a 32 bit number.

No it's not - it's currently used to trace the time chain.  If we can
make it easy for folks to do something else that's great, but we have to
solve both problems.

> There is zero cost unless you want to change ntpq as well.

Zero cost to whom?

There is a cost to people who do the work (which is to be expected) and
there is a cost to people who are experiencing the problem.

> >=20

Yes.  See above.

There is a cost to doing nothing, and there is a cost to doing something
that "causes a change".  There are benefits to doing nothing, and
benefits to making changes that fix current problems.

What are you advocating?

>> This includes the situation where we decide to use a random number
>> for each refid.  In that case the odds are probably small that any
>> peer to, say, 3 degrees (do we need to go to 4?) will be in conflict.
>>
>> I'm loathe to say "then let's have a config file option to specify
>> the UID" because that turns in to another maintenance headache.
>>

More like N than 1, but N is usually less then 100, unless it's not.

>> I'm sure there are problems with this idea too.  I wonder about how
>> it could be abused.
>>
>>  loops.  If using the IPv4 address family, the identifier is the
>>  four- octet IPv4 address.  If using the IPv6 address family, it is
>>  the first four octets of the MD5 hash of the IPv6 address.  Note
>>  that, when using the IPv6 address family on an NTPv4 server with a
>>  NTPv3 client, the Reference Identifier field appears to be a random
>>  value and a timing loop might not be detected.
>>
>> sure looks wrong to me - will we detct a timing loop if one path is
>> thru the IPv4 address and the other is thru the IPv6 address?
> 

Not today.  The refid is based on the IP address.  And the RFC currently
*does* use the IP as part of the spec for loop detection.  See below.

>> I'm also not sure how there will be more confusion to an NTPv3 host
>> that sees a refid that comes from an IPv6 upstream.  I'm not aware of
>> anybody who has implemented NTPv3 on IPv6 machines.  But maybe
>> somebody has.  If so, they would have solved this problem, right?
>>
> 

But that's not the only place it's used.  It's traditionally been used
to "look up the chain" and that expected feature will be lost.

I think I've got a solution for this.  But we have to solve both the
refid/loop detection problem and the "How do I figure out where my time
sources get their time from?" problem.

>> address.  I'm liking the idea of using at least the first 4 bits as
>> 1s for an IPv6 refid more and more.
>>
>> I can see saying for this host's refid, use the refid value
>> calculation we agree on for all interfaces/associations from a host
>> based on:
>>

Re-read what I wrote: >... for this host's refid, use ...<

> If you use a random number for the RefID just generate a new random

So that was a "yes"?

>> Q: If an interface comes up, should we re-run the above refid
>> selection process?  I currently think so.
> 
> No, See above.

I think you're wrong here.  If we were using a 1918 IP and a new
interface comes up that's using an IP address with "more global"
visibility, we must change our refid to reflect our more visible scope.

> See the reference implementation mentioned above.

I see the following in A.5.5.3:

        /*
         * A loop error occurs if the remote peer is synchronized to the
         * local peer or the remote peer is synchronized to the current
         * system peer.  Note this is the behavior for IPv4; for IPv6
         * the MD5 hash is used instead.
         */
        if (p->refid == p->dstaddr || p->refid == s.refid)
                return (FALSE);

and ntp_proto.c:local_refid() contains:

        if (unicast_ep != NULL && p->refid == unicast_ep->addr_refid)
                return TRUE;

If I read A.5.5.3 correctly, it's comparing an IP address with a 4-byte
refid.  Won't work with IPv6...

> >=20

What if a new associations is spinning up and we detect a false-positive
refid collision and have to change a refid?

If we decide to change the "how do we choose a refid", at some point a
machine in an NTP network will go from refid format X to refid format Y.

So if A has an association with B and A changes its refid, on the next
exchange B will get A's new refid.

If there was a loop before, and we were checking {A,B}, B will send A's
old refid back to A, and A will not notice this instantly.  But as soon
as B gets A's new refid, A will detect this.

I don't think this case is a big deal.

It looks to me that the current "situation" is that the intent is to
make sure that in a set of N instances of NTP, if A and B are peers, the
current situation is we want to make sure if B is sync'd to A, and A
asks B what time it has, A won't then decide to get time from B because
B is syncing its clock from A.  That is the *only* situation that the
code and RFC are designed to check.

Is that sufficient?  Do we need to worry about a loop involving {A,B,C}?

Do we know enough to know if we need to worry about {A,B,C}?

If we decide we *only* need to care about a loop involving {A,B} then
the refid idea is OK, but we *must* be able to detect the situation
where A and B happen to choose the same refid and they also must
exchange time.

Oh, in the above "how do I choose the my refid, if we use something
based on an IP, what about anycast?"

What about the case where A and B are VMs on the same physical box?  Is
that a timing loop?

---

From: "Ulrich Windl" <[email-masked]>
Date: Mon, 01 Jun 2015 08:11:28 +0200

>>> Harlan Stenn <[email-masked]> schrieb am 29.05.2015 um 23:31 in Nachricht
<[email-masked]>:
[...]
> *does* use the IP as part of the spec for loop detection.  See below.

That's probably a consequence when you mix the concept with the implementation: When the daemon used an IP address as refid, ist implementation could use the IP address instead of the refid. Of course an implementation should not do that, and a specification not at all.

[...]
>          * the MD5 hash is used instead.

Are we mixing specification with implemetation again?

[...]
> What about the case where A and B are VMs on the same physical box?  Is

I'd consider this case equivalent to "two servers being located in the same machine room" or "two servers being the same hardware type". Actually we have VMs running NTP, and you can clearly find out from the frequency, on which physical host the VMs are running (all VMs on one physical host have a very similar frequency). But the hosts (and their time) are still mostly independent, so I'd say: NO, not a timing loop.

Regards,
Ulrich