diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2015-05-23 15:27:03 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2015-05-23 15:27:03 +0300 |
commit | ffe7c151508b63fbe7f345df684305ece27c473a (patch) | |
tree | 3588f0f2f07a44a7258e48f0171580bdb160817e /dgd | |
parent | 1866566b9abb7ee4d3cd4f04fe9a88959db8fc4e (diff) | |
download | dnstools-ffe7c151508b63fbe7f345df684305ece27c473a.tar.gz dnstools-ffe7c151508b63fbe7f345df684305ece27c473a.tar.bz2 |
dgd: various improvements.
* dgd/dgd (get_default_gw): Rename to get_default_iface. Compare
gateway interface name, instead of the gw address. All uses changed.
(scan_links): Add missing conditional.
Never exit on 'no active link configured'.
(updown): If $name argument is a hash reference, read link parameters
from it and pass it to the script in the command line.
(serialize_link, cmplinks): New functions.
(SIGHUP handler): Save away active link before reconfiguring. Call
'down', if it was removed.
Diffstat (limited to 'dgd')
-rwxr-xr-x | dgd/dgd | 84 |
1 files changed, 60 insertions, 24 deletions
@@ -324,18 +324,20 @@ sub readconfig { return $err; } -sub get_default_gw { - my $gw; +sub get_default_iface { + my $ret; open(my $fd, '-|', "netstat -rn") or abend(EX_OSFILE, "can't start netstat: $!"); while (<$fd>) { - if (/^0\.0\.0\.0\s+(\S+)/) { - $gw = $1; + chomp; + my ($dest,$gw,undef,undef,undef,undef,undef,$iface) = split /\s+/; + if ($dest eq "0.0.0.0") { + $ret = $iface; last; } } close $fd; - return $gw; + return $ret; } sub scan_links { @@ -356,24 +358,28 @@ sub scan_links { for ($active_link = 0; $active_link <= $#links; ++$active_link) { last if $links[$active_link]->{name} eq $config{core}{active}; } - error("no link corresponding to the active one"); - $active_link = undef; - delete $config{core}{active}; + if ($active_link > $#links) { + error("no link corresponding to the active one"); + $active_link = undef; + delete $config{core}{active}; + } } unless (defined($active_link)) { - my $gw = get_default_gw(); - if (defined($gw)) { - debug(1, "default gw $gw"); + my $iface = get_default_iface(); + if (defined($iface)) { + debug(1, "default gw via $iface"); for ($active_link = 0; $active_link <= $#links; ++$active_link) { - last if $links[$active_link]->{gw} eq $gw; + last if $links[$active_link]->{if} eq $iface; } - abend(EX_CONFIG, "no active link configured") - if ($active_link > $#links); - - debug(1, "active link $links[$active_link]->{name}"); + if ($active_link > $#links) { + debug(1, "no active link configured"); + $active_link = undef; + } else { + debug(1, "active link $links[$active_link]->{name}"); + } } else { debug(1, "no active link configured"); $active_link = undef; @@ -403,12 +409,13 @@ sub runcmd { sub updown { my ($what, $name) = @_; - - my $cmd = defined($config{link}{$name}{$what}) - ? $config{link}{$name}{$what} - : $config{core}{$what}; + my $link = (ref($name) eq 'HASH') ? $name : $config{link}{$name}; + my $cmd = defined($link->{$what}) ? $link->{$what} : $config{core}{$what}; if (defined($cmd)) { - runcmd("$cmd $name"); + $cmd .= " '$link->{name}'"; + $cmd .= " '$link->{if}' '$link->{ip}' '$link->{gw}' '$link->{ns}' '$link->{net}'" + if (ref($name) eq 'HASH'); + runcmd($cmd); } elsif ($what eq 'up') { runcmd("route add default gw $config{link}{gw}"); } elsif ($what eq 'down') { @@ -429,7 +436,7 @@ sub check_links { foreach $link (@links) { $link->{alive} = 0; } - debug(1, "checking links"); + debug(1, "checking links ".($#links+1).", probes $config{core}{probes}"); my $p = Net::Ping->new("icmp", $config{core}{timeout}); for (my $i = 0; $i < $config{core}{probes}; $i++) { foreach $link (@links) { @@ -467,6 +474,23 @@ sub newlink { error("no fallback link"); } +sub serialize_link { + my $link = shift; + + my $s; + foreach my $k (sort keys %{$link}) { + next if ($k eq 'alive'); + $s .= ';' if defined $s; + $s .= "$k=$link->{$k}"; + } + return $s; +} + +sub cmplinks { + my ($aref, $bref) = @_; + return serialize_link($aref) eq serialize_link($bref); +} + # ######## my $foreground; @@ -528,12 +552,24 @@ unless ($foreground) { } $SIG{HUP} = sub { + my %save_link = %{$links[$active_link]} if defined $active_link; my %t = %defconfig; diag('info', "re-reading configuration file"); if (readconfig($conffile, \%t) == 0) { %config = %t; @links = (); scan_links; + if (keys(%save_link)) { + my $i; + for ($i = 0; $i <= $#links; ++$i) { + last if cmplinks(\%save_link, $links[$i]); + } + if ($i > $#links) { + debug(1, "active link $save_link{name} was removed"); + updown('down', \%save_link); + $active_link = undef; + } + } } }; @@ -673,8 +709,8 @@ marked as I<alive>. Default is 2 =item B<active => I<STRING> -Name of the active link. If not defined, the link whose B<gw> variable -matches the default gateway address is assumed active. +Name of the active link. If not defined, the link whose B<if> variable +matches the interface name of the default gateway is assumed active. =item B<logpriority => B<0>|B<1> |