Part of the functionality in the LCFG::Client::Daemon
code is to send acknowledgement messages to the LCFG servers whenever a new profile has been applied. The ack is sent via UDP using the SendAck
method. The original code to do this took the traditional C-style approach:
return ::TransientError("can't open UDP socket",$!) unless (socket(ACKSOCK,PF_INET,SOCK_DGRAM,$proto)); return ::TransientError("can't bind UDP socket",$!) unless (bind(ACKSOCK,sockaddr_in(0,INADDR_ANY))); my $addr = inet_aton($name); return ::DataError("can't determine host address: $name") unless ($addr); my $res = send(ACKSOCK,$msg,0,sockaddr_in($aport,$addr)); return ::TransientError("can't send notification: $name",$!) unless ($res == length($msg));
with a smattering of weirdness and unless
thrown in for good measure. Things have moved on a bit since the days when this was the recommended approach. There is now a very handy suite of modules in the IO::Socket
namespace which can handle the dirty work for us. The replacement code looks like this:
my $port = AckPort(); my $socket = IO::Socket::INET->new ( PeerAddr => $server, PeerPort => $port, Proto => 'udp', ) or return LCFG::Client::TransientError( "can't connect to $server:$port", $! ); my $res = $socket->send($message); $socket->close(); if ( $res != length $message ) { return LCFG::Client::TransientError( "can't send notification: $server", $! ); }
That is, without a doubt, much easier to read and maintain. We are now relying on someone else to do the socket handling but that’s fine as this is a core Perl module which should be totally reliable.