On 2017-10-06 5:47 AM, Miroslav Lichvar wrote:
On Thu, Oct 05, 2017 at 05:20:00PM -0400, Will Miles wrote:
On 2017-10-05 5:05 AM, Miroslav Lichvar wrote:
I guess a completely different approach would be to allow multiplexing
with the SOCK driver. Multiple clients could connect to the socket and
each one would have a separate refclock. This could be tricky.
If I'm understanding you correctly, are you thinking of something based on
SOCK_SEQPACKET, where chrony could accept() to get a new fd for each client,
listen for an initial "refclock metadata" packet, then just readmsg() for
the measurement stream?
Yes, something like that. Maybe a metadata packet wouldn't be
necessary if a refid could be assigned automatically and all refclocks
added over the socket would share the other settings.
I don't think there's anything I can do to avoid it - I need to specify
at least poll, offset, delay, and filter parameters uniquely for each
source, and it's nice to have the refids be relatable to where the data
is coming from.
Unfortunately for me, QNX doesn't support SOCK_SEQPACKET, and replicating
that sort of per-client connection semantics using only SOCK_STREAM and
SOCK_DGRAM would be a pain for sure. :(
I'm wondering if it can be done with SOCK_DGRAM alone. If clients were
required to bind their sockets, chronyd could map refclocks to the
source address, right? When a refclock becomes unreachable (it stops
sending new samples), it will be removed.
Unfortunately it seems like with SOCK_DGRAM, somehow the client needs to
be informed of where to find chronyd's listener to send() to. Calling
connect() doesn't actually communicate at all with the other end, it
just validates and sets your "default" destination for send(). So for
the client to send messages back to chronyd, either A) chronyd needs to
send the client something from a unique socket for each client, so the
client can capture the return address via recvfrom(); or B) chronyd
would bind a common listening socket at a location the client knows
about, and then switch on the src_addr for every message. I'm not
thrilled with either approach -- for plan A, the client has to wait to
receive something before it can send, which makes writing clients
complicated; for plan B, the src_addrs are the client socket paths as
strings, so chronyd would have to hash them on every sample to map them
to the source instance. I think this is really why SOCK_SEQPACKET was
invented... you get the advantage of the kernel handling the mapping via
fds instead of having to roll it yourself.
And in any event, I still need to handle communicating the source
parameters as some kind of preamble. Given that, it seems just as
simple to create plain old refclock_sock instances on demand, rather
than build out a multiplexer. That said, I'm sketching an
implementation that does so via a seperate socket from the usual client
command protocol. It's not functionally any different than the
previous chronyc approach, except that it only works for refclock_sock
-- however it keeps the custom code better isolated so as to avoid
annoying merges on other changes to the client protocol.
-Will
--
To unsubscribe email chrony-dev-requ...@chrony.tuxfamily.org with "unsubscribe"
in the subject.
For help email chrony-dev-requ...@chrony.tuxfamily.org with "help" in the
subject.
Trouble? Email listmas...@chrony.tuxfamily.org.