in reply to Time check on group of servers

Create your own time daemon?

#!/usr/bin/env perl use IO::Socket::INET; # auto-flush on socket $| = 1; # creating a listening socket my $socket = new IO::Socket::INET ( LocalHost => '0.0.0.0', LocalPort => '5101', Proto => 'tcp', Listen => 10, Reuse => 1 ); die "cannot create socket $!\n" unless $socket; print "server waiting for client connection on port 5101\n"; while(1) { # waiting for a new client connection my $client_socket = $socket->accept(); # get information about a newly connected client my $client_address = $client_socket->peerhost(); my $client_port = $client_socket->peerport(); print "connection from $client_address:$client_port\n"; # read up to 16 characters from the connected client my $theirtime = 0; $client_socket->recv($theirtime, 16); print "received data: $theirtime\n"; $theirtime =~s/[^\d]//g; # untaint # write response data to the connected client my $their_drift = time - $theirtime ; $client_socket->send($their_drift); # notify client that response has been sent shutdown($client_socket, 1); } $socket->close(); __END__ Problem Your program has forked and you want to tell the other end that you're + done sending data. You've tried close on the socket, but the remote +end never gets an EOF or SIGPIPE. Solution Use shutdown: shutdown(SOCKET, 0); # I/we have stopped reading data shutdown(SOCKET, 1); # I/we have stopped writing data shutdown(SOCKET, 2); # I/we have stopped using this soc +ket

can be tested with:

(perl -e 'print time';sleep 2) | telnet 127.0.0.1 5101 2>/dev/null|tai +l -1

try time+3 to simulate time drifting...

Addendum: a small perl client:

#!/usr/bin/env perl use IO::Socket::INET; # auto-flush on socket $| = 1; # create a connecting socket my $socket = new IO::Socket::INET ( PeerHost => 'localhost', PeerPort => '5101', Proto => 'tcp', ); die "cannot connect to the server $!\n" unless $socket; print "connected to the server\n"; # data to send to a server my $mytime = time; my $size = $socket->send($mytime); print "sent data of length $size\n"; # notify server that request has been sent shutdown($socket, 1); # receive a response of up to 256 characters from server my $response = ""; $socket->recv($response, 256); print "received response: $response\n"; $socket->close(); my $threshold=5; # seconds if(abs($response)>$threshold){ exit 1; }else{ exit 0; }

edit: forgot g in the untaint...

Replies are listed 'Best First'.
Re^2: Time check on group of servers
by FreeBeerReekingMonk (Deacon) on May 09, 2016 at 20:09 UTC
    forgot the hashbang and the "Listen => 5" should be 10 to be able to service all the machines at once. Also: use strict and warnings... Depending on the the connection time, you might want to add fallbacks, like a retry to create a socket, counting the seconds it took to get the anwser, and maybe substract half of this time from your result. Even use Time::HiRes; to get better data... But your thresholds seem to be very tolerant, so keeping it as integers is a quick duktape/chewingum solution while you roll out your ntp thing..

    If you have systemd read this: systemd-timesyncd

    Set up 1 server that gets it's time from the internet, and all others should get their time from that server

Re^2: Time check on group of servers
by FreeBeerReekingMonk (Deacon) on May 21, 2016 at 00:35 UTC