[SR-Dev] [Serdev] AVPs

Daniel-Constantin Mierla miconda at gmail.com
Mon Dec 15 23:36:33 CET 2008


On 12/12/08 17:22, Jan Janak wrote:
> On 12-12 00:25, Daniel-Constantin Mierla wrote:
>> Hello,
>> I think we need to decide about AVPs. Although not deeply investigated,  
>> ser seems to have couple of AVPs lists. In kamailio/openser it is one 
>> list.
>> Can a ser developer describe a bit the AVP implementation as it is now  
>> there?
>   A long time ago we started using AVPs to store all kinds of configuration
>   information. We needed some sort of general configuration mechanism because
>   real-world scripts were getting too complex and at that time the AVPs were
>   readily available.
>   We started by loading attribute names and value from a database table into
>   AVPs. This mechanism was/is same as in k. We would always load a set of
>   attributes this way for a particular user (identified by username and domain
>   from his/her SIP URI). With this mechanism in place, we were able to load a
>   generic set of configuration options for a particular user of the server, I
>   guess you have the same.
>   To make the AVPs easily accessible from the configuration script, we added
>   support for AVP identifiers in the config script, so that you can access AVP
>   with name foo as $foo.
>   As we migrated more and more configuration options to AVPs, it became clear
>   that having just one set of AVPs was not enough. Although we could load all
>   the config options for the caller (From URI) from the database into a set of
>   AVPs, we could not do the same for the callee (Request-URI) at the same
>   time. We could not do it because they would conflict with the AVPs of the 
>   caller as both users could have AVPs with same names but different values.
>   To get around this issue we added another list of AVPs. The new AVP list
>   works the same way, it can contain AVPs with same names as AVPs in the
>   original list and they do not conflict. All functions that work with lists
>   of AVPs now take the list to work on as parameter.
>   To make both AVP lists available in the configuration script, we extended
>   the syntax of AVPs identifiers so the script write can choose the AVP list
>   to work with. SO instead of just $foo you can write either
>   $f.foo or $t.foo
>   $f refers to the original AVP list which is commonly associated with the
>   caller. The address/uid of the caller is taken from From header, hence the
>   'f' in the identifier. $t refers to the AVP list which contains
>   configuration settings of the callee. The address/uid of the calle can be
>   taken either from the Request-URI or To headers, hence the 't' in the
>   identifier.
>   The original syntax without any list identifier is still available, in other
>   words you can still write $foo, this is defined as a shorthand for
>   $f.foo. If you do not specify the AVP list to be used then you are referring
>   to the list containing AVPs of the caller (From).
>   It also turned out that in some cases we would be having too many attributes
>   in the database table storing AVPs. This can happen in bigger setups, having
>   tens or hundreds of thousands users or serving multiple domains. This can
>   slow the database down and makes SER load too much data. Based on my
>   observations it is common that a large number of users have AVPs with same
>   values. If ten thousands of users have attribute named 'foo' with value
>   'bar' then the attribute will be stored in the database ten thousand times.
>   As a remedy for this problem, we introduced the concept of AVP levels. The
>   AVPs described so far and stored in user_attrs table are called user-level
>   attributes and they store configuration specific to particular users. Then
>   we added another two AVP lists to store so called domain-level AVPs.
>   Domain-level AVPs are used to store configuration information that is shared
>   by a group of users. Domain-level AVPs are stored in a separate database
>   table, the name of the table is domain_attrs and its contents is cached in
>   memory by 'domain' SER module. This is an important difference, while
>   user-level AVPs need to be loaded every time a SIP request is processed,
>   domain-level AVPs are only loaded when the contents of domain_attrs table
>   has changed.
>   The domain-level AVPs are called 'domain' because they are tied to a
>   particular domain handled by the SIP server. That could be 'iptel.org',
>   'sip-router.org', and so on. This mainly useful for multi-domain
>   setups. There are two domain-level AVP lists because it is common that SER
>   works with two domains at the same time, the domain from From header
>   (caller's domain) and the domain from Request-URI or To (callee's domain).
>   Again, we extended the syntax of AVP identifiers in the configuration
>   file. So you can write:
>   $fu.foo -- this way you are asking for the value of the user-level foo AVP.
>   $fd.foo -- This will return the value of the domain-level foo AVP.
>   And similarly there is $tu and $td for callee's user-level and domain-level
>   AVPs. If you specify 'u' in the AVP identifiers then SER searches only the
>   list of user-level attributes. If you specify 'd' then SER searches only the
>   list of domain-level attributes.
>   This behavior changes if you do NOT specify the level to be searched. In
>   that case SER searches the user-level list first and if no match is found
>   then the domain-level list will be searched. Thus if you write:
>   $f.foo
>   then you are telling SER to search for the value of 'foo' AVP in the
>   user-level list and continue with the domain-level list if no match is
>   found. In other words, user-level AVPs have higher priority than
>   domain-level AVPs. With this system you can efficiently set a configuration
>   option for all users within a domain by creating a domain-level attribute
>   and yet you can override that option with user-level attributes for
>   particular users within that domain.
>   Then there are the global AVPs. Global AVPs can be used to store settings
>   applicable to the whole SIP server and all domains on that server. Global
>   AVPs are stored in global_attrs table and the contents of that table is
>   cached in memory by gflags module. There is only one list of global
>   AVPs. Global AVPs can be accessed with:
>   $g.foo
>   (note that there is no 'f' or 't' in the identifier). The list of global
>   AVPs is searched after the list of domain-level AVPs. So if you write:
>   $f.foo
>   Then SER searches user-level AVPs first, then domain-level and then the
>   global AVPs.
>   And finally there are also so called URI-level AVPs. They work just
>   like user-level AVPs, but a single user can have multiple sets of
>   uri-level AVPs. They are tied to SIP URIs of that user. Uri-level AVPs are
>   denoted by 'r' in the AVP identifier, for example:
>   $fr.foo

so, if I understood correctly, there are couple of combinations between 
the dot, with one or two letters, right?



where x = f|t|g and y may be missing or u|d|r

Then we can get rid of overlapping in the namespace if we enforce usage 
of $f.foo for $foo . In K there are couple of PV that use dot in 
classname (a PV can be $classname or $classname(innername)), but they 
are proposed to be removed.

In the same idea as in ser, thenK AVPs will map to From list.

>> In openser/kamailio we have more or less same architecture as for ser  
>> 0.9.6 with couple extensions, but I will detail here so we can have full  
>> picture:
>> - avps are kept in shared memory
>   In our case global and domain level AVPs are stored in shared memory.
>> - they are bound to each sip message and moved to transaction if that  
>> message create a transaction
>   This is same.
>> - avp can have two types of names
>>    - integer id, referred as $avp(i:number)
>>    - string id, referred as $avp(s:string)
>> - there can be aliases for avp names, defined as "alias=[is]:id", so the  
>> script writer can use $avp(alias)
>   We've kind of dropped support for integer avps, we've been using string
>   names pretty much everywhere, although the original code still exists.
>> - a value of an avp can be either integer or string
>> - not related to avp core part, but important to mention here -- tm,  
>> controlled by a parameter, can make the avps from transaction (request)  
>> available to onreply_route.
>   In SER tm restores all AVPs stored in a transaction in all route blocks
>   called from tm, such as onreply_route, failure_route. At least I hope I
>   remember it correctly.
>     Jan.
> _______________________________________________
> sr-dev mailing list
> sr-dev at lists.sip-router.org
> http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev

Daniel-Constantin Mierla

More information about the sr-dev mailing list