Commit 42c729c1 authored by Robert Anderson's avatar Robert Anderson

Fixed accounting start, update and stop records handling sessions spanning over multiple periods

Added UPGRADING file for upgrading information from previous revision
parent 8b94b634
r509:
# Database
ALTER TABLE accounting ADD PeriodKey VARCHAR(7);
ALTER TABLE accounting_summary DROP COLUMN AcctInputPackets;
# smradiusd.conf
Modified:
accounting_start_query=<<EOT
INSERT INTO
@TP@accounting
(
Username,
ServiceType,
FramedProtocol,
NASPort,
NASPortType,
CallingStationID,
CalledStationID,
NASPortID,
AcctSessionID,
FramedIPAddress,
AcctAuthentic,
EventTimestamp,
AcctStatusType,
NASIdentifier,
NASIPAddress,
AcctDelayTime,
PeriodKey
)
VALUES
(
%{request.User-Name},
%{request.Service-Type},
%{request.Framed-Protocol},
%{request.NAS-Port},
%{request.NAS-Port-Type},
%{request.Calling-Station-Id},
%{request.Called-Station-Id},
%{request.NAS-Port-Id},
%{request.Acct-Session-Id},
%{request.Framed-IP-Address},
%{request.Acct-Authentic},
%{request.Timestamp},
%{request.Acct-Status-Type},
%{request.NAS-Identifier},
%{request.NAS-IP-Address},
%{request.Acct-Delay-Time},
%{query.PeriodKey}
)
EOT
accounting_update_query=<<EOT
UPDATE
@TP@accounting
SET
AcctSessionTime = %{query.AcctSessionTime},
AcctInputOctets = %{query.AcctInputOctets},
AcctInputGigawords = %{query.AcctInputGigawords},
AcctInputPackets = %{query.AcctInputPackets},
AcctOutputOctets = %{query.AcctOutputOctets},
AcctOutputGigawords = %{query.AcctOutputGigawords},
AcctOutputPackets = %{query.AcctOutputPackets},
AcctStatusType = %{request.Acct-Status-Type}
WHERE
Username = %{request.User-Name}
AND AcctSessionID = %{request.Acct-Session-Id}
AND NASIPAddress = %{request.NAS-IP-Address}
AND PeriodKey = %{query.PeriodKey}
EOT
accounting_stop_query=<<EOT
UPDATE
@TP@accounting
SET
AcctSessionTime = %{query.Acct-Session-Time},
AcctInputOctets = %{query.Acct-Input-Octets},
AcctInputGigawords = %{query.Acct-Input-Gigawords},
AcctInputPackets = %{query.Acct-Input-Packets},
AcctOutputOctets = %{query.Acct-Output-Octets},
AcctOutputGigawords = %{query.Acct-Output-Gigawords},
AcctOutputPackets = %{query.Acct-Output-Packets}
WHERE
Username = %{request.User-Name}
AND AcctSessionID = %{request.Acct-Session-Id}
AND NASIPAddress = %{request.NAS-IP-Address}
AND PeriodKey = %{query.PeriodKey}
EOT
Added:
accounting_update_get_records_query=<<EOT
SELECT
SUM(AcctInputOctets) AS InputOctets,
SUM(AcctInputPackets) AS InputPackets,
SUM(AcctOutputOctets) AS OutputOctets,
SUM(AcctOutputPackets) AS OutputPackets,
SUM(AcctInputGigawords) AS InputGigawords,
SUM(AcctOutputGigawords) AS OutputGigawords,
SUM(AcctSessionTime) AS SessionTime,
PeriodKey
FROM
@TP@accounting
WHERE
Username = %{request.User-Name}
AND AcctSessionID = %{request.Acct-Session-Id}
AND NASIPAddress = %{request.NAS-IP-Address}
GROUP BY
PeriodKey
ORDER BY
ID ASC
EOT
accounting_stop_status_query=<<EOT
UPDATE
@TP@accounting
SET
AcctStatusType = %{request.Acct-Status-Type},
AcctTerminateCause = %{request.Acct-Terminate-Cause}
WHERE
Username = %{request.User-Name}
AND AcctSessionID = %{request.Acct-Session-Id}
AND NASIPAddress = %{request.NAS-IP-Address}
EOT
......@@ -34,17 +34,21 @@ our (@ISA,@EXPORT,@EXPORT_OK);
MOD_RES_ACK
MOD_RES_NACK
MOD_RES_SKIP
UINT_MAX
);
@EXPORT_OK = ();
use constant {
RES_OK => 0,
RES_ERROR => -1,
RES_OK => 0,
RES_ERROR => -1,
MOD_RES_SKIP => 0,
MOD_RES_ACK => 1,
MOD_RES_NACK => 2,
MOD_RES_SKIP => 0,
MOD_RES_ACK => 1,
MOD_RES_NACK => 2,
UINT_MAX => 2**32
};
......
......@@ -118,14 +118,13 @@ sub post_auth_hook
# Get the users' usage
my $accountingUsage;
my $month = DateTime->from_epoch( epoch => $user->{'_Internal'}->{'Timestamp-Unix'} )->strftime('%Y-%m');
# Loop with plugins to find anyting supporting getting of usage
foreach my $module (@{$server->{'module_list'}}) {
# Do we have the correct plugin?
if ($module->{'Accounting_getUsage'}) {
$server->log(LOG_INFO,"[MOD_FEATURE_CAPPING] Found plugin: '".$module->{'Name'}."'");
# Fetch users session uptime & bandwidth used
my $res = $module->{'Accounting_getUsage'}($server,$user,$packet,$month);
my $res = $module->{'Accounting_getUsage'}($server,$user,$packet);
if (!defined($res)) {
$server->log(LOG_ERR,"[MOD_FEATURE_CAPPING] No usage data found for user '".$packet->attr('User-Name')."'");
return MOD_RES_SKIP;
......@@ -318,7 +317,7 @@ sub post_acct_hook
if ($module->{'Accounting_getUsage'}) {
$server->log(LOG_INFO,"[MOD_FEATURE_CAPPING] Found plugin: '".$module->{'Name'}."'");
# Fetch users session uptime & bandwidth used
my $res = $module->{'Accounting_getUsage'}($server,$user,$packet,$month);
my $res = $module->{'Accounting_getUsage'}($server,$user,$packet);
if (!defined($res)) {
$server->log(LOG_ERR,"[MOD_FEATURE_CAPPING] No usage data found for user '".$packet->attr('User-Name')."'");
return MOD_RES_SKIP;
......
......@@ -301,6 +301,7 @@ sub cleanup
$prevMonth = $now->month - 1;
}
my $lastMonth = DateTime->new( year => $prevYear, month => $prevMonth, day => 1 );
my $prevPeriodKey = $lastMonth->strftime("%Y-%m");
# Get begin date of next month
my ($folYear,$folMonth);
......@@ -335,12 +336,12 @@ sub cleanup
FROM
@TP@accounting
WHERE
EventTimestamp > ?
PeriodKey = ?
AND Username = ?
GROUP BY
Username
',
$lastMonth,$userName
$prevPeriodKey,$userName
);
if (!$sth) {
......@@ -428,7 +429,6 @@ sub cleanup
# Get users topups that are still valid from topups_summary, must not be depleted
my $prevPeriodKey = $lastMonth->strftime("%Y-%m");
$sth = DBSelect('
SELECT
@TP@topups_summary.TopupID,
......@@ -783,7 +783,24 @@ sub cleanup
# Loop through summary topups
foreach my $summaryTopup (@summaryTopups) {
# Set users depleted topups
# Delete any previous record of this summary
$sth = DBDo('
DELETE FROM
@TP@topups_summary
WHERE
TopupID = ?
AND PeriodKey = ?',
$summaryTopup->{'ID'}, $periodKey
);
if (!$sth) {
$server->log(LOG_ERR,"[MOD_CONFIG_SQL_TOPUPS] Cleanup => Failed to delete previous record: ".
awitpt::db::dblayer::Error());
goto FAIL_ROLLBACK;
}
# Insert topup summary
$sth = DBDo('
INSERT INTO
@TP@topups_summary (TopupID,PeriodKey,Balance)
......
......@@ -235,7 +235,8 @@ accounting_start_query=<<EOT
AcctStatusType,
NASIdentifier,
NASIPAddress,
AcctDelayTime
AcctDelayTime,
PeriodKey
)
VALUES
(
......@@ -254,39 +255,74 @@ accounting_start_query=<<EOT
%{request.Acct-Status-Type},
%{request.NAS-Identifier},
%{request.NAS-IP-Address},
%{request.Acct-Delay-Time}
%{request.Acct-Delay-Time},
%{query.PeriodKey}
)
EOT
accounting_update_get_records_query=<<EOT
SELECT
SUM(AcctInputOctets) AS InputOctets,
SUM(AcctInputPackets) AS InputPackets,
SUM(AcctOutputOctets) AS OutputOctets,
SUM(AcctOutputPackets) AS OutputPackets,
SUM(AcctInputGigawords) AS InputGigawords,
SUM(AcctOutputGigawords) AS OutputGigawords,
SUM(AcctSessionTime) AS SessionTime,
PeriodKey
FROM
@TP@accounting
WHERE
Username = %{request.User-Name}
AND AcctSessionID = %{request.Acct-Session-Id}
AND NASIPAddress = %{request.NAS-IP-Address}
GROUP BY
PeriodKey
ORDER BY
ID ASC
EOT
accounting_update_query=<<EOT
UPDATE
@TP@accounting
SET
AcctSessionTime = %{request.Acct-Session-Time},
AcctInputOctets = %{request.Acct-Input-Octets},
AcctInputGigawords = %{request.Acct-Input-Gigawords},
AcctInputPackets = %{request.Acct-Input-Packets},
AcctOutputOctets = %{request.Acct-Output-Octets},
AcctOutputGigawords = %{request.Acct-Output-Gigawords},
AcctOutputPackets = %{request.Acct-Output-Packets},
AcctSessionTime = %{query.SessionTime},
AcctInputOctets = %{query.InputOctets},
AcctInputGigawords = %{query.InputGigawords},
AcctInputPackets = %{query.InputPackets},
AcctOutputOctets = %{query.OutputOctets},
AcctOutputGigawords = %{query.OutputGigawords},
AcctOutputPackets = %{query.OutputPackets},
AcctStatusType = %{request.Acct-Status-Type}
WHERE
Username = %{request.User-Name}
AND AcctSessionID = %{request.Acct-Session-Id}
AND NASIPAddress = %{request.NAS-IP-Address}
AND PeriodKey = %{query.PeriodKey}
EOT
accounting_stop_query=<<EOT
UPDATE
@TP@accounting
SET
AcctSessionTime = %{request.Acct-Session-Time},
AcctInputOctets = %{request.Acct-Input-Octets},
AcctInputGigawords = %{request.Acct-Input-Gigawords},
AcctInputPackets = %{request.Acct-Input-Packets},
AcctOutputOctets = %{request.Acct-Output-Octets},
AcctOutputGigawords = %{request.Acct-Output-Gigawords},
AcctOutputPackets = %{request.Acct-Output-Packets},
AcctSessionTime = %{query.SessionTime},
AcctInputOctets = %{query.InputOctets},
AcctInputGigawords = %{query.InputGigawords},
AcctInputPackets = %{query.InputPackets},
AcctOutputOctets = %{query.OutputOctets},
AcctOutputGigawords = %{query.OutputGigawords},
AcctOutputPackets = %{query.OutputPackets}
WHERE
Username = %{request.User-Name}
AND AcctSessionID = %{request.Acct-Session-Id}
AND NASIPAddress = %{request.NAS-IP-Address}
AND PeriodKey = %{query.PeriodKey}
EOT
accounting_stop_status_query=<<EOT
UPDATE
@TP@accounting
SET
AcctStatusType = %{request.Acct-Status-Type},
AcctTerminateCause = %{request.Acct-Terminate-Cause}
WHERE
......@@ -306,7 +342,7 @@ accounting_usage_query=<<EOT
@TP@accounting
WHERE
Username = %{request.User-Name}
AND EventTimestamp >= %{query.From}
AND PeriodKey = %{query.PeriodKey}
EOT
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment