#!/usr/bin/perl

# This script should be run each 15 minutes.

# This script fetches actual tel.t-online.de entries and puts them to the rpz of the running named if there have been any changes detected.
# If there is a change detected, reRegister the telekom trunks!

use strict;
use Data::Dumper;

my $para=$ARGV[0];

# Address of own Nameserver wich should handle the rpz's
my $ownNsAddress='192.168.62.13';

# The lines of the rpz updates
my @updateLines;

# Workingdir - go to RAM
my $workingDir='/var/run/asterisk/';

# The file containing the RPZ updates
my $updateFile=$workingDir.'rpzupdate';

# Set nameserver address for t-online name server (the leading nameserver)
my $nsAddress='2003:180:2:a000::53';
my $nsAddress1='2003:180:2:b000::53'; 

sub createWorkingDir() {
if (! -d $workingDir) {
    mkdir ($workingDir,'0755');
    chown ("asterisk", "asterisk", $workingDir);
    }
}

sub create_update(@) {
my (@llines)=@_;
foreach my $line (@llines) {
    #_sips._tcp.tel.t-online.de. 1411 IN     SRV     30 0 5061 d-eps-100.edns.t-ipnet.de.
    $line =~ s/\. (\d+[	 ]+IN)/.rpz-tonline./;
    $line =~ s/SRV/60 SRV/;
#    next if ($line =~ /s-eps-110/);
#    next if ($line =~ /h2-eps-100/);
    push @updateLines, "update add ".$line;
    last; # create just one entry. 
    }
}

sub create_update_napster(@) {
my (@llines)=@_;
foreach my $line (@llines) {
    # tel.t-online.de.        4398    IN      NAPTR   10 0 "s" "SIPS+D2T" "" _sips._tcp.tel.t-online.de.
    next if ($line =~ /\_udp/);
    $line =~ s/(tel\.t\-online\.de\.)/${1}rpz-tonline./;
    $line =~ s/IN//;
    $line =~ s/\d+		NAPTR/60	NAPTR/;
    push @updateLines, "update add ".$line;
    }
}


sub unregister() {
`logger -t check-t-online "unregister trunk entries ..."`;
`/usr/sbin/asterisk -x "pjsip send unregister telekomPJSIP-a"`;
`/usr/sbin/asterisk -x "pjsip send unregister telekomPJSIP-b"`;
`/usr/sbin/asterisk -x "pjsip send unregister telekomPJSIP-c"`;
`/usr/sbin/asterisk -x "pjsip send unregister telekomPJSIP-d"`;
sleep 1;
}

sub register() {
`logger -t check-t-online "register trunk entries ..."`;
`/usr/sbin/asterisk -x "pjsip send register telekomPJSIP-a"`;
sleep 3;
`/usr/sbin/asterisk -x "pjsip send register telekomPJSIP-b"`;
sleep 3;
`/usr/sbin/asterisk -x "pjsip send register telekomPJSIP-c"`;
sleep 3;
`/usr/sbin/asterisk -x "pjsip send register telekomPJSIP-d"`;
}

sub updateNs() {
`logger -t check-t-online "update new ns entries ..."`;
my $rc=`nsupdate $updateFile 2>&1`;
if ( $? > 0 ) {
    `logger -t check-t-online "Error at nsupdate <$?> <$!> <$rc>"`;
    # In case of an error, the existing updateFile must be always deleted to be sure not to overwrite the old md5 sum file on start up (it's only written if there is an existing updateFile)
    unlink $updateFile;
    exit 1;
    }
}

sub writeRpzFile() {
open F, ">$updateFile";
foreach my $line (@updateLines) {
    print F $line;
    }
close F;
}

createWorkingDir;

# If start is the first time (to remove old file at first) use the parameter "initial"
if (defined $para && $para eq 'initial') {
    if (-f ${updateFile}.'md5') {
	unlink (${updateFile}.'md5');
	}
    if (-f $updateFile) {
	unlink ($updateFile);
	}
    }

push @updateLines, "server $ownNsAddress\n";
push @updateLines, "zone rpz-tonline\n";
push @updateLines, "update delete tel.t-online.de.rpz-tonline.\n";
push @updateLines, "update delete _sips._tcp.tel.t-online.de.rpz-tonline.\nupdate delete _sip._tcp.tel.t-online.de.rpz-tonline.\n";

# create md5 sum for old DNS entries and check the newly created updateFile against this md5 sum later.
# If the newly created updateFile differs from the existing one, try to apply it and reregister Asterisk
# if this breaks, remove the newly created update file.
if (-f $updateFile) {
    `md5sum $updateFile > ${updateFile}.md5`;
    }

my @naptr = `dig +noall +answer tel.t-online.de NAPTR \@$nsAddress | sort -u`;
if ($#naptr <= 0) {
    `logger -t check-t-online "No result from T-DNS"`;
    exit 0;
    }
create_update_napster(@naptr);


my @lines = `dig +noall +answer _sips._tcp.tel.t-online.de SRV \@$nsAddress | sort -u`;
create_update(@lines);
if ($#lines <= 0) {
    `logger -t check-t-online "No result from T-DNS"`;
    exit 0;
    }

@lines = `dig +noall +answer _sip._tcp.tel.t-online.de SRV \@$nsAddress | sort -u`;
create_update(@lines);
push @updateLines, "send\n";

writeRpzFile;

# check if there are any changes compared to the md5sum the file had before
my $out=`md5sum -c ${updateFile}.md5`;
if ( $? > 0 ) {
    `logger -t check-t-online "DNS-Change detected!"`;
    # oh, there have been changes!
    # Are there any calls active in Asterisk?
    while (1) {
	my @channels=`/usr/sbin/asterisk -x "pjsip show channels"`;
	if ($#channels > 4) {
	    `logger -t check-t-online "There are active calls - try again 60s later .."`;
	    sleep 60;
	    }
	else {
	    unregister;
	    updateNs;
	    register;
	    exit 0;
	    }
	}
    }
else {
    # `logger -t check-t-online "No DNS change detected. Do nothing."`;
    }
