bd755a5dc25f9254cb3f91a2779ff0e53c972bb1
[sip-router] / modules_s / iptrtpproxy / examples / clean_rtpproxy_attrs
1 #!/usr/bin/env perl
2
3 # $Id$
4
5 # The script cleans up orphaned RTP proxy attributes from rtpproxy_attrs.
6 # The orphaned attribute is the attribute having none of its sessions.
7 # in iptrtpproxy session list.
8
9 use warnings;
10 #use strict;
11 use DBI;
12
13 my $version = "0.1";
14 my $defConfigFile = "/etc/iptrtpproxy.cfg";
15 my $configFile = $defConfigFile;
16 my $verbose = 0;
17
18 my $defmysqlhost = 'localhost';
19 my $mysqlhost = $defmysqlhost;
20 my $defmysqldb = 'ser';
21 my $mysqldb = $defmysqldb;
22 my $defmysqluser = 'ser';
23 my $mysqluser = $defmysqluser;
24 my $defmysqlpassword = 'heslo';
25 my $mysqlpassword = $defmysqlpassword;
26 my $defmysqlsock = "";
27 my $mysqlsock = $defmysqlsock;
28
29 use Config::IniFiles;
30
31 sub dbg {
32         if ($verbose) {
33                 print STDERR "DBG: $_[0]\n";
34         }
35 }
36
37 sub myexit ($$)
38 {
39         my ($msg, $exitcode ) = @_;
40         print "# ERROR: $msg\n";
41         DBI->disconnect_all();
42         exit $exitcode;
43 }
44
45
46 sub do_exec($) 
47 {
48         my $cmd = $_[0];
49         dbg "Exec: $cmd";
50         my @res = `$cmd`;
51         dbg "Exit code: $?";    
52         @res;
53 }
54
55
56 # parse config file to $cfg
57 sub parseConfigFile($)
58 {
59         my $fileName = $_[0];
60         dbg "Parsing config file '$fileName'\n" if $verbose;
61         my %switchboards = ();
62         goto ret unless -e $configFile;
63         my $cfg = Config::IniFiles->new( -file => $configFile, -default => "<default>" );
64
65         for my $section ($cfg->Sections) {
66                 if ($section =~ /^[a-zA-Z_]+$/) {
67                         print STDERR "Parsing section '$section'\n" if $verbose;
68                         for my $param ('addr-a', 'addr-b', 'port-a', 'port-b') {
69                                 my $val = $cfg->val($section, $param);
70                                 if ($val) {
71                                         $switchboards{$section}{$param} = $val;
72                                 }
73                         }
74                 }
75
76         }
77 ret:
78         return %switchboards;
79 }
80
81 my $scriptName = $0;
82 $scriptName =~ s!^.*/!!;
83
84 sub printUsage {
85         print "$scriptName, Version: $version\n";
86         print "usage: $scriptName [-f <iptrtpproxy_config>] [-v] [-h] [-H <db_host>] [-S <db_sock>] [-D <db_name>] [-u <db_user>] [-p <db_password>]\n";
87         print "  iptrtpproxy_config .. iptrtpproxy_helper config, default: $defConfigFile\n";
88         print "  db_host .. database MYSQL  host, default: $defmysqlhost\n";
89         print "  db_sock .. MYSQL socket, default: $defmysqlsock\n";
90         print "  db_name .. database name, default: $defmysqldb\n";
91         print "  db_user .. database user, default: $defmysqluser\n";
92         $_ = substr $defmysqlpassword, 1, length($defmysqlpassword)-2;
93         s/./\*/g;
94         my $psw = substr($defmysqlpassword, 0, 1) . $_ . substr($defmysqlpassword, length($defmysqlpassword)-1, 1);
95         print "  db_password .. database password, default: $psw\n";
96         print "  -v .. verbose\n";
97 }
98
99 my $command = '';
100 my $arg;
101
102 while ($#ARGV >= 0) {
103         $arg = shift(@ARGV);
104         if ($arg eq '-f') {
105                 if ($#ARGV < 0) {
106                         print STDERR "ERROR: config file name required\n";
107                         &printUsage();
108                         exit(1);
109                 } else {
110                         $configFile = shift(@ARGV);
111                 }
112         } elsif ($arg eq '-D') {
113                 if ($#ARGV < 0) {
114                         print STDERR "ERROR: database name required\n";
115                         &printUsage();
116                         exit(1);
117                 } else {
118                         $mysqldb = shift(@ARGV);
119                 }
120         } elsif ($arg eq '-u') {
121                 if ($#ARGV < 0) {
122                         print STDERR "ERROR: user name required\n";
123                         &printUsage();
124                         exit(1);
125                 } else {
126                         $mysqluser = shift(@ARGV);
127                 }
128         } elsif ($arg eq '-p') {
129                 if ($#ARGV < 0) {
130                         print STDERR "ERROR: password required\n";
131                         &printUsage();
132                         exit(1);
133                 } else {
134                         $mysqlpassword = shift(@ARGV);
135                 }
136         } elsif ($arg eq '-H') {
137                 if ($#ARGV < 0) {
138                         print STDERR "ERROR: hostname required\n";
139                         &printUsage();
140                         exit(1);
141                 } else {
142                         $mysqlhost = shift(@ARGV);
143                 }
144         } elsif ($arg eq '-S') {
145                 if ($#ARGV < 0) {
146                         print STDERR "ERROR: socket required\n";
147                         &printUsage();
148                         exit(1);
149                 } else {
150                         $mysqlsock = shift(@ARGV);
151                 }
152         } elsif ($arg eq '-v') {
153                 $verbose++;
154         } elsif ($arg eq '-h') {
155                 &printUsage();
156                 exit(0);
157         } else {
158                 print STDERR "ERROR: unknown argument '$arg'\n";
159                 &printUsage();
160                 exit(1);
161         }       
162 }
163
164 dbg "Verbose: $verbose";
165
166 dbg "Connecting: mysql://$mysqluser\@$mysqlhost/$mysqldb";
167 myexit("Cannot connect database", 2) unless my $dbh = DBI->connect("dbi:mysql:database=$mysqldb".
168         ($mysqlhost?";host=$mysqlhost":'').
169         ($mysqlsock?";mysql_socket=$mysqlsock":'')
170         , $mysqluser, $mysqlpassword);
171
172 dbg "Reading rtpproxy_attrs";
173 my %attrs = ();
174 # copy rtpproxy_attrs to memory, we need snapshot of table
175 $sth = $dbh->prepare("SELECT * FROM rtpproxy_attrs");
176 $sth->execute();
177 my $i = 0;
178 while (my $href = $sth->fetchrow_hashref()) {
179
180         if ($href->{'name'} eq 'dlg_sess_ids') {
181                 $attrs{$href->{'id'}} = $href->{'value'};
182                 $i++;
183         }
184 }
185 $sth->finish();
186 dbg "rtpproxy_attrs records: $i";
187
188 my %cfgSwitchboards = &parseConfigFile($configFile);
189
190 my %switchboards = ();
191 for my $id (keys %cfgSwitchboards) {
192         dbg "Switchboard: $id";
193         $cmd = "iptrtpproxy list --addr-a $cfgSwitchboards{$id}{'addr-a'} --port-a $cfgSwitchboards{$id}{'port-a'} --addr-b $cfgSwitchboards{$id}{'addr-b'} --port-b $cfgSwitchboards{$id}{'port-b'} --force-switchboard-audit --format tab";
194         my @lines = &do_exec($cmd);
195         my @l = split(/\t/, $lines[0]);
196         my $sess_id = -1;
197         my $tick = -1;
198         for my $i (0..$#l) {
199                 if ($l[$i] eq 'sess-id') {
200                         $sess_id = $i;
201                 } elsif ($l[$i] eq 'created/tick') {
202                         $tick = $i;
203                 }
204         }
205         dbg "Lines: $#lines, Columns: sess-id: $sess_id, tick: $tick";
206         for my $i (1..$#lines) {
207                 my @l = split(/\t/, $lines[$i]);
208                 $switchboards{$id}{$l[$sess_id]} = $l[$tick];
209         }
210 }
211
212 dbg "Clean rtpproxy_attrs";
213 # get iptrtpproxy switchboards
214 my $delCnt = 0;
215 $sth = $dbh->prepare("DELETE FROM rtpproxy_attrs WHERE id=?");
216 loop: for my $id (keys %attrs) {
217         # format name:session_id/stamp (, session_id/stamp)*] 
218         my $found = 0;
219         my ($name, $s) = split( /:/, $attrs{$id});
220         if (!defined $s) {
221                 goto del;
222         }
223         my @ss = split( /,/, $s);
224         for $i (0..$#ss) {
225                 my ($sess_id, $tick) = split ( /\//, $ss[$i]);
226                 if ($sess_id eq "" || !defined $tick || $tick eq "") {
227                         next;
228                 }
229                 if ($switchboards{$name}{$sess_id} && $switchboards{$name}{$sess_id} eq $tick) {
230                         dbg "Leave: $id=$attrs{$id}";
231                         next loop;
232                 }
233         }
234 del:
235         dbg "Delete: $id=$attrs{$id}";
236         $sth->execute($id);
237         $delCnt++;
238 }
239 dbg "Deleted: $delCnt records";
240
241 exit(0);
242
243