Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid

perl daemon surviving changing ppp-links

by raphi72 (Initiate)
on Oct 19, 2005 at 22:05 UTC ( #501449=perlquestion: print w/replies, xml ) Need Help??

raphi72 has asked for the wisdom of the Perl Monks concerning the following question:

I've written a daemon process, that regularly fetches some urls from the net. When my ppp-link goes down "ifdown ppp0" and I reconnect to a different provider "ifup ppp1" (different IP-address and nameservers), my script keeps failing to fetch those urls. A simple restart of my script makes it work again. I could reduce the script to:
use Net::Ping; while (1) { my $p = Net::Ping->new(udp); if $p->ping($host) { print "success\n"; } else { print "failed\n"; } undef $p; sleep 3; }
use LWP::Simple; while (1) { my $content = get($url); if (defined $content) { print "success\n"; } else { print "failed\n"; } sleep 4; }
How can I fix my script, so I don't have to restart it, if I need to change my ppp-link?

Replies are listed 'Best First'.
Re: perl daemon surviving changing ppp-links
by ybiC (Prior) on Oct 20, 2005 at 03:45 UTC

    This smells like it may be a routing persistance issue rather than an error in your code.   How do LWP::Simple or core Perl know internally that the active network interface and default gateway have changed mid-stream?   Not that they couldn't necessarily be made to refresh - I'm just asking, eh.

    One possible (potentially hack-ish) workaround would be to automagically kill and re-launch your script using your Unix distribution's standard mechanisms.   With Debian Linux that would be scriptlets added to /etc/network/if-up.d/ and if-down.d/ directories.


      striving toward Perl Adept
      (it's pronounced "why-bick")

      That may not be so hack-ish at all. In fact, it's a pretty good solution for other reasons, namely that the application won't be generating a bunch of errors that can be ignored. I hate what I call "erroneous errors" - errors that really should be dealt with by the application rather than the user. This is one of those cases - while ppp is down, you end up with a bunch of failures to download. All errors which you can ignore. Embedded in there may be other errors which are not ignorable, but they get lost in the clutter of ignorable errors, and you don't pay attention.

      By following your suggestion, the errors that are left are likely to be interesting/important errors that need to be addressed. Or there are no further errors, and you can more deservedly have a nice, warm, cozy feeling about how good of a job your script is doing in fetching whatever it is supposed to be fetching.

      Thank you for that suggestion.
      Using if-up if-down scripts is probably the best work-around.

      Still I'd like to know, whether it's possible to "refresh" the network parameters of a running perl script. Is it possible in C? The resolver library is part of libc, so how could I make my program reread /etc/resolv.conf?
Re: perl daemon surviving changing ppp-links
by kwaping (Priest) on Oct 19, 2005 at 22:50 UTC
    I think you're going to have to post your real code for this one. I don't see anything wrong with the "distilled" code you posted.
Re: perl daemon surviving changing ppp-links
by ybiC (Prior) on Oct 20, 2005 at 13:09 UTC

    Or to stick with a self-contained-within-your-own-original-script approach...

    Have your daemon note which network-interface it used last.   Then before each subsequent iteration, check to see if that same interface is still up.   If not, have the daemon bounce itself.   Of course you'd need some delay or counter or somesuch to avoid flapping.   Or else use an interface that *is* up, perhaps from a configured list of permissable interfaces.

    You may find it necessary to think "ip address" instead of "network interface", depending on implementation.

    Searching CPAN and searching The Monastery on "network interface" turned up some potentially relevant hits.


      striving toward Perl Adept
      (it's pronounced "why-bick")
      Thanks for that hint. I now use IO::Interface to get my local ppp0 ip-address:
      use IO::Socket; use IO::Interface qw(:flags); sub get_local_addr { my $if = shift; my $s = IO::Socket::INET->new(Proto => 'udp'); unless ($s->if_flags($if) & IFF_RUNNING) { return undef; } else { return $s->if_addr($if); } }
      and then in my script I test, if the ip-address of the ppp0 interface changed:
      use Net::Ping; my $addr = get_local_addr("ppp0"); unless(defined $addr) { die "I'm offline\n"; } while (1) { my $p = Net::Ping->new(udp); if $p->ping($host) { print "success\n"; } else { print "failed\n"; my $cur_addr = get_local_addr("ppp0"); if ($addr ne $cur_addr) { die "I'm offline\n"; } } undef $p; sleep 3; }
      There's no need to restart the script, because it will get started by my if-up script.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://501449]
Approved by ghenry
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (3)
As of 2021-05-16 19:14 GMT
Find Nodes?
    Voting Booth?
    Perl 7 will be out ...

    Results (152 votes). Check out past polls.