(RADIATOR) Forking for accounting

Matthew Trout MatthewTrout at businessserve.co.uk
Wed Apr 30 10:22:26 CDT 2003


Radiator as provided does not honour the Fork clause in AuthBySQL when
dealing with accounting packets; in order to achieve this without producing
unexpected effects on configs that expect this (mis?)-behaviour, I added a
ForkOnAccounting configuration directive with a patch to AuthSQL.pm.

Running radiator with this patch (and a minor one to Util.pm to add a
%{ZeroUnless:} syntax to ensure my accounting queries are valid SQL) I got a
marked performance increase (LDAP auth, MySQL logging with slightly tweaked
versions of the provided examples to do a single INSERT on Stop packets for
speed); however when the server came under heavy load I noticed a number of
odd behaviours.

1) Radiator repeatedly reported the error 'Lost connection to MySQL server'
when running queries, although these queries all seemed to have run
successfully - this got steadily worse as the load increased
2) When the load reached a certain point, I started getting
LDAP_OPERATIONS_ERROR occasionally, which I traced (with the aid of google)
to being a result of an error calling asn_read in Convert::ASN1::IO - i.e.
the connection had been lost here also
3) Radiator would occasionally lock entirely and cease replying (the
frequency of this also increases with server load); it appears that the
master and one of its child processes were locked waiting for each other -
i.e.
# ps -ef | grep radius
    root 21305 15003  0 12:51:14 ?        0:00 /usr/local/bin/perl
/usr/local/bin/radiusd
    root 15003     1  0 10:49:06 ?        9:41 /usr/local/bin/perl
/usr/local/bin/radiusd
    root 21325 14940  0 13:17:13 pts/2    0:00 grep radius
# truss -p 15003
read(4, 0x00A03758, 4)          (sleeping...)
signotifywait()                 (sleeping...)
lwp_cond_wait(0xFF0F5548, 0xFF0F5558, 0xFF0EEDB0) (sleeping...)
# truss -p 21305
read(4, 0x00A03758, 8192)       (sleeping...)
signotifywait()                 (sleeping...)
lwp_sema_wait(0xFE30DE30)       (sleeping...)
# truss -p 15003
read(4, 0x00A03758, 4)          (sleeping...)
signotifywait()                 (sleeping...)
lwp_cond_wait(0xFF0F5548, 0xFF0F5558, 0xFF0EEDB0) (sleeping...)

Has anybody experienced similar issues with the normal Fork directive?

Hugh, Mike, can you enlighten me as to whether this is an issue with the way
my patch calls the Radiator forking code (I've attempted to keep it as close
to the way the handlerFork method is normally called as possible) or an
issue with the forking code itself? I've had -ahem- fun (FSVO) with Solaris'
parent/child process handling and Perl before, so this may be
platform-specific.

My Radiator config (sans secrets) is -

<SessionDatabase SQL>
        Identifier      DSL-SessDB
        DBSource        DBI:mysql:database=radius_session_dsl;host=10.7.6.15
        DBUsername      automan
        DBAuth          6o1ahadoto
        AddQuery        insert into RADONLINE\
                        (USERNAME, NASIDENTIFIER, NASPORT, ACCTSESSIONID,\
                        TIME_STAMP, FRAMEDIPADDRESS, NASPORTTYPE,
SERVICETYPE,\
                        CALLFROM, CALLTO)\
                        values ('%u', '%1', %2, %3, %{Timestamp},\
                        '%{Framed-IP-Address}', '%{NAS-Port-Type}',
'%{Service-Type}',\
                        '%{Calling-Station-Id}', '%{Called-Station-Id}')
</SessionDatabase SQL>

<SessionDatabase SQL>
        Identifier      FRIACO-SessDB
        DBSource
DBI:mysql:database=radius_session_friaco;host=10.7.6.15
        DBUsername      automan
        DBAuth          6o1ahadoto
        AddQuery        insert into RADONLINE\
                        (USERNAME, NASIDENTIFIER, NASPORT, ACCTSESSIONID,\
                        TIME_STAMP, FRAMEDIPADDRESS, NASPORTTYPE,
SERVICETYPE,\
                        CALLFROM, CALLTO)\
                        values ('%u', '%1', %2, %3, %{Timestamp},\
                        '%{Framed-IP-Address}', '%{NAS-Port-Type}',
'%{Service-Type}',\
                        '%{Calling-Station-Id}', '%{Called-Station-Id}')
</SessionDatabase SQL>

<SessionDatabase SQL>
        Identifier      Dial-SessDB
        DBSource
DBI:mysql:database=radius_session_dial;host=10.7.6.15
        DBUsername      automan
        DBAuth          6o1ahadoto
        AddQuery        insert into RADONLINE\
                        (USERNAME, NASIDENTIFIER, NASPORT, ACCTSESSIONID,\
                        TIME_STAMP, FRAMEDIPADDRESS, NASPORTTYPE,
SERVICETYPE,\
                        CALLFROM, CALLTO)\
                        values ('%u', '%1', %2, %3, %{Timestamp},\
                        '%{Framed-IP-Address}', '%{NAS-Port-Type}',
'%{Service-Type}',\
                        '%{Calling-Station-Id}', '%{Called-Station-Id}')
</SessionDatabase SQL>

<AddressAllocator SQL>
        Identifier      DialAllocator
        DBSource
DBI:mysql:database=radius_session_dial;host=10.7.6.15
        DBUsername      automan
        DBAuth          6o1ahadoto
        DefaultLeasePeriod      86400
        LeaseReclaimInterval    3600
        AllocateQuery   update RADPOOL set STATE=1,TIME_STAMP=%0,
NASIP='%N', NASPORT=%{NAS-Port}, \
                        EXPIRY=%1, USERNAME=%2 where YIADDR='%3' and
TIME_STAMP %4
        DeallocateQuery update RADPOOL set STATE=0,TIME_STAMP=%t where
NASIP='%N' and NASPORT=%{NAS-Port}
        <AddressPool YC-Radius>
                Subnetmask 255.255.255.255
                Range 212.248.147.1 212.248.147.255
                Range 212.248.148.1 212.248.148.255
                Range 212.248.149.1 212.248.149.255
        </AddressPool>
</AddressAllocator>

<AddressAllocator SQL>
        Identifier      ADSLAllocator
        DBSource        DBI:mysql:database=radius_session_dsl;host=10.7.6.15
        DBUsername      automan
        DBAuth          6o1ahadoto
        DefaultLeasePeriod      7776000
        LeaseReclaimInterval    3600
        AllocateQuery   update RADPOOL set STATE=1,TIME_STAMP=%0,
NASIP='%N', NASPORT=%{NAS-Port}, \
                        EXPIRY=%1, USERNAME=%2 where YIADDR='%3' and
TIME_STAMP %4
        DeallocateQuery update RADPOOL set STATE=0,TIME_STAMP=%t where
NASIP='%N' and NASPORT=%{NAS-Port}
        <AddressPool BT-ADSL-Radius>
                Subnetmask 255.255.255.255
                Range 62.69.97.0 62.69.97.255
                Range 62.69.98.0 62.69.98.255
        </AddressPool>
</AddressAllocator>

#<Handler Client-Identifier = BT-ADSL-Radius,Acct-Status-Type=/.+/>
#       SessionDatabase DSL-SessDB
#       AcctLogFileName %L/adsl-acct-detail
#       <AuthBy TEST>
#               # Return a Packet
#       </AuthBy>
#</Handler>

<Handler Client-Identifier = BT-ADSL-Radius,Acct-Status-Type=/.+/>
        SessionDatabase DSL-SessDB
#       AcctLogFileName %L/adsl-acct-detail
        AuthByPolicy DoAllAuths
        <AuthBy SQL>
                ForkOnAccounting
                Identifier      AcctSTOP
                AuthSelect
                DBSource
DBI:mysql:database=radius_session_dsl;host=10.7.6.15
                DBUsername      automan
                DBAuth          6o1ahadoto
                HandleAcctStatusTypes Stop
                AcctSQLStatement insert into usertime \
                ( \
                server,id,name,\
                time_on,port,port_type,service_type,protocol,\
                ip,call_to,call_from,InBytes,OutBytes,\
                term_cause,auth,\
                start_time,stop_time,\
                connect_info\
                ) \
                values \
                (\
                inet_aton('%{NAS-IP-Address}'),\
                '%{ZeroUnless:Acct-Session-Id}',\
                '%{User-Name}',\
                \
                %{ZeroUnless:Acct-Session-Time},\
                %{ZeroUnless:NAS-Port},\
                '%{NAS-Port-Type}',\
                '%{Service-Type}',\
                '%{Framed-Protocol}',\
                \
                '%{Framed-IP-Address}',\
                '%{Called-Station-Id}',\
                '%{Calling-Station-Id}',\
                %{ZeroUnless:Acct-Input-Octets},\
                %{ZeroUnless:Acct-Output-Octets},\
                \
                '%{Acct-Terminate-Cause}',\
                %{ZeroUnless:Auth-Type},\
                From_unixtime(%{ZeroUnless:Timestamp} -
%{ZeroUnless:Acct-Session-Time}),\
                From_unixtime(%{ZeroUnless:Timestamp}),\
                '%{Connect-Info}'\
                )
        </AuthBy>
        <AuthBy DYNADDRESS>
                AddressAllocator        ADSLAllocator
                PoolHint                %{Client:Identifier}
        </AuthBy>
        <AuthBy TEST>
                # Return a Packet
        </AuthBy>
</Handler>

<Handler Client-Identifier = BT-FRIACO-Radius,Acct-Status-Type=/.+/>
        SessionDatabase FRIACO-SessDB
#       AcctLogFileName %L/friaco-acct-detail
        AuthByPolicy DoAllAuths
        <AuthBy SQL>
                ForkOnAccounting
                Identifier      AcctSTOP
                AuthSelect
                DBSource
DBI:mysql:database=radius_session_friaco;host=10.7.6.15
                DBUsername      automan
                DBAuth          6o1ahadoto
                HandleAcctStatusTypes Stop
                AcctSQLStatement insert into usertime \
                ( \
                server,id,name,\
                time_on,port,port_type,service_type,protocol,\
                ip,call_to,call_from,InBytes,OutBytes,\
                term_cause,auth,\
                start_time,stop_time,\
                connect_info\
                ) \
                values \
                (\
                inet_aton('%{NAS-IP-Address}'),\
                '%{ZeroUnless:Acct-Session-Id}',\
                '%{User-Name}',\
                \
                %{ZeroUnless:Acct-Session-Time},\
                %{ZeroUnless:NAS-Port},\
                '%{NAS-Port-Type}',\
                '%{Service-Type}',\
                '%{Framed-Protocol}',\
                \
                '%{Framed-IP-Address}',\
                '%{Called-Station-Id}',\
                '%{Calling-Station-Id}',\
                %{ZeroUnless:Acct-Input-Octets},\
                %{ZeroUnless:Acct-Output-Octets},\
                \
                '%{Acct-Terminate-Cause}',\
                %{ZeroUnless:Auth-Type},\
                From_unixtime(%{ZeroUnless:Timestamp} -
%{ZeroUnless:Acct-Session-Time}),\
                From_unixtime(%{ZeroUnless:Timestamp}),\
                '%{Connect-Info}'\
                )
        </AuthBy>
        <AuthBy TEST>
                # Return a Packet
        </AuthBy>
</Handler>

<Handler Client-Identifier = /CVX1/,Acct-Status-Type=/.+/>
        SessionDatabase Dial-SessDB
#       AcctLogFileName %L/dial-acct-detail
        AuthByPolicy DoAllAuths
        <AuthBy SQL>
                ForkOnAccounting
                Identifier      AcctSTOP
                AuthSelect
                DBSource
DBI:mysql:database=radius_session_dial;host=10.7.6.15
                DBUsername      automan
                DBAuth          6o1ahadoto
                HandleAcctStatusTypes Stop
                AcctSQLStatement insert into usertime \
                ( \
                server,id,name,\
                time_on,port,port_type,service_type,protocol,\
                ip,call_to,call_from,InBytes,OutBytes,\
                term_cause,auth,\
                start_time,stop_time,\
                connect_info\
                ) \
                values \
                (\
                inet_aton('%{NAS-IP-Address}'),\
                '%{ZeroUnless:Acct-Session-Id}',\
                '%{User-Name}',\
                \
                %{ZeroUnless:Acct-Session-Time},\
                %{ZeroUnless:NAS-Port},\
                '%{NAS-Port-Type}',\
                '%{Service-Type}',\
                '%{Framed-Protocol}',\
                \
                '%{Framed-IP-Address}',\
                '%{Called-Station-Id}',\
                '%{Calling-Station-Id}',\
                %{ZeroUnless:Acct-Input-Octets},\
                %{ZeroUnless:Acct-Output-Octets},\
                \
                '%{Acct-Terminate-Cause}',\
                %{ZeroUnless:Auth-Type},\
                From_unixtime(%{ZeroUnless:Timestamp} -
%{ZeroUnless:Acct-Session-Time}),\
                From_unixtime(%{ZeroUnless:Timestamp}),\
                '%{Connect-Info}'\
                )
        </AuthBy>
        <AuthBy TEST>
                # Return a Packet
        </AuthBy>
</Handler>

<Handler Client-Identifier = /YC-Radius/,Acct-Status-Type=/.+/>
        SessionDatabase Dial-SessDB
#       AcctLogFileName %L/dial-acct-detail
        AuthByPolicy DoAllAuths
        <AuthBy SQL>
                ForkOnAccounting
                Identifier      AcctSTOP
                AuthSelect
                DBSource
DBI:mysql:database=radius_session_dial;host=10.7.6.15
                DBUsername      automan
                DBAuth          6o1ahadoto
                HandleAcctStatusTypes Stop
                AcctSQLStatement insert into usertime \
                ( \
                server,id,name,\
                time_on,port,port_type,service_type,protocol,\
                ip,call_to,call_from,InBytes,OutBytes,\
                term_cause,auth,\
                start_time,stop_time,\
                connect_info\
                ) \
                values \
                (\
                inet_aton('%{NAS-IP-Address}'),\
                '%{ZeroUnless:Acct-Session-Id}',\
                '%{User-Name}',\
                \
                %{ZeroUnless:Acct-Session-Time},\
                %{ZeroUnless:NAS-Port},\
                '%{NAS-Port-Type}',\
                '%{Service-Type}',\
                '%{Framed-Protocol}',\
                \
                '%{Framed-IP-Address}',\
                '%{Called-Station-Id}',\
                '%{Calling-Station-Id}',\
                %{ZeroUnless:Acct-Input-Octets},\
                %{ZeroUnless:Acct-Output-Octets},\
                \
                '%{Acct-Terminate-Cause}',\
                %{ZeroUnless:Auth-Type},\
                From_unixtime(%{ZeroUnless:Timestamp} -
%{ZeroUnless:Acct-Session-Time}),\
                From_unixtime(%{ZeroUnless:Timestamp}),\
                '%{Connect-Info}'\
                )
        </AuthBy>
        <AuthBy DYNADDRESS>
                AddressAllocator        DialAllocator
                PoolHint                %{Client:Identifier}
        </AuthBy>
        <AuthBy TEST>
                # Return a Packet
        </AuthBy>
</Handler>

<Handler Client-Identifier = BT-FRIACO-Radius>
#<Handler DEFAULT>
#       PreAuthHook sub {
${$_[0]}->addAttrByNum($Radius::Radius::EAP_MESSAGE,1); }

SessionDatabase FRIACO-SessDB

<AuthBy GROUP>
        AuthByPolicy ContinueUntilAccept

        <AuthBy LDAP2>
                Debug           255
                NoDefault
                HoldServerConnection
                Host            10.7.9.13
                AuthDN          cn=directory manager
                AuthPassword    dir-ad1rmas
                BaseDN          ou=customers, ou=people, dc=bsve.net,
o=internet
                #UsernameAttr    uid
                #PasswordAttr    friacopassword
                AuthAttrDef     FRIACO-todr, Time, check
                SearchFilter
(&(objectclass=friacouser)(csid=0%{Calling-Station-Id})(!(suspended=yes)))
                AddToReply Service-Type = Framed-User, \
                        Framed-Protocol = PPP, \
                        Framed-IP-Address = 255.255.255.254, \
                        Framed-IP-Netmask = 255.255.255.255, \
                        Framed-Routing = None, \
                        Framed-Compression = Van-Jacobsen-TCP-IP, \
                        Framed-MTU = 1500, \
                        Session-Timeout = "until Time"
        </AuthBy>

        <AuthBy LDAP2>
#                Debug           255
                NoDefault
                HoldServerConnection
                Host            10.7.9.13
                AuthDN          cn=directory manager
                AuthPassword    dir-ad1rmas
                BaseDN          ou=customers, ou=people, dc=bsve.net,
o=internet
                AuthAttrDef     FRIACO-todr, Time, check
                UsernameAttr    friacousername
                PasswordAttr    friacopassword
                SearchFilter
(&(%0=%1)(objectClass=FRIACOuser)(!(suspended=yes)))
                AddToReply Service-Type = Framed-User, \
                        Framed-Protocol = PPP, \
                        Framed-IP-Address = 255.255.255.254, \
                        Framed-IP-Netmask = 255.255.255.255, \
                        Framed-Routing = None, \
                        Framed-Compression = Van-Jacobsen-TCP-IP, \
                        Framed-MTU = 1500, \
                        Session-Timeout = "until Time"
        </AuthBy>

</AuthBy>
PostAuthHook sub { (${$_[1]}->get_attr('Session-Timeout') > 7200) &&
${$_[1]}->change_attr('Session-Timeout',7200); }
</Handler>

<Handler Client-Identifier = BT-ADSL-Radius>
        AuthByPolicy    ContinueWhileAccept
       <AuthBy LDAP2>
#               Debug           255
               NoDefault
               HoldServerConnection
               Host            10.7.9.13
               AuthDN          cn=directory manager
               AuthPassword    dir-ad1rmas
               BaseDN          ou=customers, ou=people, dc=bsve.net,
o=internet
               UsernameAttr    uid
               PasswordAttr    userpassword
               SearchFilter
(&(%0=%1)(objectClass=adsluser)(!(adslsuspended=1)))
               AuthAttrDef     framed-ip-address, Framed-IP-Address, reply
               AuthAttrDef     routed-network-address, _ipbase, request
               AuthAttrDef     routed-network-netmask, _netmask, request
               AuthAttrDef     explicitnexthopaddress, _nexthop, request
               PostSearchHook sub { if ($_[2]->get_attr('_ipbase')) { \
 
$_[3]->get_reply->add_attr('cisco-avpair', \
 
'ip:route='.$_[2]->get_attr('_ipbase'). \
                                          ' '.$_[2]->get_attr('_netmask'). \
                                          ( $_[2]->get_attr('_nexthop') \
                                          ? '
'.$_[3]->get_reply->get_attr('Framed-IP-Address') \
                                          : '')); \
                                    } }
               AddToReply Service-Type = Framed-User, \
                       Framed-Protocol = PPP, \
                       cisco-avpair = "ip:dns-servers=62.69.64.134
62.69.64.135"
       </AuthBy>
        <AuthBy DYNADDRESS>
                AddressAllocator        ADSLAllocator
                PoolHint                %{Client:Identifier}
        </AuthBy>
</Handler>

<Handler Client-Identifier = /CVX1/>
RewriteUsername s/^([^\@]+).*/$1\@bsdial.net/
       <AuthBy LDAP2>
#               Debug           255
               NoDefault
               HoldServerConnection
               Host            10.7.9.13
               AuthDN          cn=directory manager
               AuthPassword    dir-ad1rmas
               BaseDN          ou=customers, ou=people, dc=bsve.net,
o=internet
               UsernameAttr    uid
               PasswordAttr    userpassword
               SearchFilter
(&(%0=%1)(dialup-nasclass=%{Client:Identifier})(objectClass=dialuser)(!(susp
ended=1)))
               AuthAttrDef     dialup-ip-address, Framed-IP-Address, reply
               AuthAttrDef     dialup-netmask, Framed-IP-Netmask, reply
               AuthAttrDef     dialup-maximum-bundled-channels,
CVX-Maximum-Channels, reply
               AuthAttrDef     dialup-routing-metric, Ascend-Metric, reply
               PostSearchHook sub {
$_[3]->get_reply->get_attr('CVX-Maximum-Channels') \
                                     ||
$_[3]->get_reply->add_attr('CVX-Maximum-Channels', 2); }
               AddToReply Service-Type = Framed-User, \
                          Framed-Protocol = PPP, \
                          Framed-Routing = None, \
                          CVX-Idle-Limit = 1800
        </AuthBy>
</Handler>

<Handler Client-Identifier = YC-Radius, Called-Station-Id =
/0?8450591005|0?8450591010/>
        RewriteUsername s/^([^\@]+).*/$1\@bsdial.net/
        <AuthBy DYNADDRESS>
                AddressAllocator        DialAllocator
                PoolHint                %{Client:Identifier}
                AcceptIfMissing
                AddToReply Service-Type = Framed-User, \
                   Framed-Protocol = PPP, \
                   Framed-Routing = None, \
                   CVX-Idle-Limit = 1800, \
                   CVX-Maximum-Channels = 2, \
                   cisco-avpair = "ip:dns-servers=62.69.64.134 62.69.64.135"
        </AuthBy>
</Handler>

<Handler Client-Identifier = YC-Radius>
        RewriteUsername s/^([^\@]+).*/$1\@bsdial.net/
        AuthByPolicy    ContinueWhileAccept
        <AuthBy LDAP2>
#               Debug           255
               NoDefault
               HoldServerConnection
               Host            10.7.9.13
               AuthDN          cn=directory manager
               AuthPassword    dir-ad1rmas
               BaseDN          ou=customers, ou=people, dc=bsve.net,
o=internet
               UsernameAttr    uid
               PasswordAttr    userpassword
               SearchFilter
(&(%0=%1)(dialup-nasclass=YC-Radius)(objectClass=dialuser)(!(suspended=1)))
               AuthAttrDef     dialup-ip-address, Framed-IP-Address, reply
               AuthAttrDef     dialup-netmask, Framed-IP-Netmask, reply
               AuthAttrDef     dialup-maximum-bundled-channels,
CVX-Maximum-Channels, reply
               PostSearchHook sub {
$_[3]->get_reply->get_attr('CVX-Maximum-Channels') \
                                     ||
$_[3]->get_reply->add_attr('CVX-Maximum-Channels', 2); }
               AddToReply Service-Type = Framed-User, \
                          Framed-Protocol = PPP, \
                          Framed-Routing = None, \
                          CVX-Idle-Limit = 1800, \
                          cisco-avpair = "ip:dns-servers=62.69.64.134
62.69.64.135"
        </AuthBy>
        <AuthBy DYNADDRESS>
                AddressAllocator        DialAllocator
                PoolHint                %{Client:Identifier}
        </AuthBy>
</Handler>

Logs look like the following (have included a fragment with both errors)

Mon Apr 28 18:36:45 2003: ERR: ldap search failed with error
LDAP_OPERATIONS_ERROR.
Mon Apr 28 18:36:45 2003: ERR: Disconnecting from LDAP server (server
10.7.9.13:389).
Mon Apr 28 18:37:08 2003: ERR: do failed for 'update RADPOOL set
STATE=0,TIME_STAMP=1051551428 where NASIP='212.248.254.18' and NASP
ORT=266': Lost connection to MySQL server during query
Mon Apr 28 18:37:08 2003: ERR: do failed for 'insert into usertime (
server,id,name,time_on,port,port_type,service_type,protocol,ip,
call_to,call_from,InBytes,OutBytes,term_cause,auth,start_time,stop_time,conn
ect_info) values (inet_aton('212.248.254.18'),'0000DF28'
,'gas370840 at bsdial.net',83,266,'ISDN','Framed-User','PPP','212.248.147.115',
'08450591000','1314400032',4289,2229,'User-Request',0,Fr
om_unixtime(1051551428 - 83),From_unixtime(1051551428),'')': Lost connection
to MySQL server during query

The patches used follow; they were both taken against Radiator 3.5, but
apply cleanly against 3.6 (which is what we're currently running, on Solaris
2.8)

*** /usr/local/src/Radiator-3.5/Radius/AuthSQL.pm       Fri Nov 29 06:10:07
2002
--- AuthSQL.pm  Thu Apr 10 11:34:18 2003
***************
*** 23,28 ****
--- 23,29 ----
       'AcctColumnDef'         => 'stringarray',
       'HandleAcctStatusTypes' => 'counthash',
       'AcctInsertQuery'       => 'string',
+      'ForkOnAccounting'      => 'flag',
       );
  
  #####################################################################
***************
*** 113,118 ****
--- 114,138 ----
            if $self->{AccountingAlivesOnly}
               && $status_type ne 'Alive';
  
+         # Now we might fork before running the accounting query/ies
+         # Should only do this if the database response is "slow"
+         return ($main::IGNORE, 'forked')
+              if $self->{ForkOnAccounting} && !$self->handlerFork();
+ 
+       # (Re)-connect to the database if necessary, so we can use
+       # the quote function.
+       # No reply will be sent to the original requester if we 
+       # fail to connect
+       if (!$self->reconnect)
+       {
+           &Radius::Util::logAccounting
+               ($p, undef, 
+                $self->{AcctFailedLogFileName}, 
+                $self->{AcctLogFileFormat})
+                   if $self->{AcctFailedLogFileName};
+           return ($main::IGNORE, 'Database failure');
+       }
+ 
        # If AcctSQLStatement is set, parse the strings and execute them
        # Contributed by Nicholas Barrington <nbarrington at smart.net.au>
        map {$self->do(&Radius::Util::format_special($_, $p))}
***************
*** 122,141 ****
        # If AcctColumnDef is set, build an insert statment
        if (defined $self->{AcctColumnDef})
        {
-           # (Re)-connect to the database if necessary, so we can use
-           # the quote function.
-           # No reply will be sent to the original requester if we 
-           # fail to connect
-           if (!$self->reconnect)
-           {
-               &Radius::Util::logAccounting
-                   ($p, undef, 
-                    $self->{AcctFailedLogFileName}, 
-                    $self->{AcctLogFileFormat})
-                       if $self->{AcctFailedLogFileName};
-               return ($main::IGNORE, 'Database failure');
-           }
- 
            # Add each column defined by AcctColumnDef
            # Courtesy Phil Freed ptf at cybertours.com
            my ($cols, $vals) = $self->getExtraCols($p);
--- 142,147 ----

*** /usr/local/src/Radiator-3.5/Radius/Util.pm  Tue Dec 17 05:07:31 2002
--- Util.pm     Wed Apr  9 18:01:53 2003
***************
*** 334,339 ****
--- 334,340 ----
      $s =~ s/%\{Reply:([^{]+)\}/{$rpacket ? $rpacket->get_attr($1) :
''}/egs;
      $s =~ s/%\{Client:([^{]+)\}/{$p ? $p->{Client}{$1} : ''}/egs;
      $s =~ s/%\{Handler:([^{]+)\}/{$p ? $p->{Handler}{$1} : ''}/egs;
+     $s =~ s/%\{ZeroUnless:([^{]+)\}/{($p && $p->get_attr($1)) ?
$p->get_attr($1) : '0'}/egs;
  #    $s =~ s/%\{Eval:([^{]+)\}/{eval($1)}/egs;
      $s =~ s/%\{([^{]+)\}/{$p ? $p->get_attr($1) : ''}/egs;
===
Archive at http://www.open.com.au/archives/radiator/
Announcements on radiator-announce at open.com.au
To unsubscribe, email 'majordomo at open.com.au' with
'unsubscribe radiator' in the body of the message.


More information about the radiator mailing list