Standardised JSON VP list format

Brian Candler B.Candler at pobox.com
Wed Nov 9 13:44:00 CET 2011


On Tue, Nov 08, 2011 at 03:04:23PM +0100, Arran Cudbard-Bell wrote:
> What about:
> 
> "<attribute>":{
> 	"value":[[<value>,<tag>],<value>,[<value>,<tag>]]
> }
> 
> I don't see that there's any other possible use for nested arrays in the value key?

Possibly the update operator (=, +=, :=, !* etc).

As for tags, the first option which springs to mind is to put them in the
attribute label, as they are in FreeRadius today.

However with tags, the update operators don't behave how I'd expect.  If I
write

    Tunnel-Server-Endpoint:0 := 1.2.3.4
    Tunnel-Server-Endpoint:1 := 5.6.7.8

then the second := erases all previous instances of Tunnel-Server-Endpoint. 
The tag behaves not as part of the attribute, but as part of the value
(which in fact it is).

This isn't a problem with standard FreeRadius where the AV pairs are always
returned in some order - apart from the limitation that there's no facility
to replace just Tunnel-Server-Endpoint:1.  But it would be a problem for
this JSON:

{
  "Tunnel-Server-Endpoint:0": [["1.2.3.4",":="]],
  "Tunnel-Server-Endpoint:1": [["5.6.7.8",":="]]
}

because many JSON consumers don't guarantee the order in which object
members are returned.

A more convenient way to handle tags would be as object keys:

{
  "Tunnel-Server-Endpoint": {"0"=>"1.2.3.4", "1"=>"5.6.7.8"}
}

But this still has the problem of element ordering given the same example as
above:

{
  "Tunnel-Server-Endpoint": {"0"=>["1.2.3.4",":="], "1"=>["5.6.7.8",":="]}
}

Semantically, having repeated := is not very useful. Normally you'd have :=
on the first value and += on the others.  Can we rely on this?  That is,
apply := to the whole attribute and have it expand to := on the first value
and += on the rest? Then += would apply as += to all values.

But when you start to consider other update operators, it would prohibit
cases like this:

   Reply-Message += "foo"
   Reply-Message -= "bar"

and the only way I can see to support that is that firstly every value needs
to be tagged with an operator, and secondly the values must be in an array
so that they are processed in a deterministic sequence. If not, you get
non-deterministic behaviour in this sort of edge case (admittedly useless):

   Reply-Message += "foo"
   Reply-Message -= "foo"

Final point: if you are returning a bundle of attributes, currently these
are always *merged* into the reply packet.  You can delete individual
attributes using -= or !* operators, but there is no way to say "replace the
entire reply list built so far" without invoking something like attr_filter
in unlang. This is no worse for rlm_rest than we have today, but I'd really
like some way to return maybe a magic attribute which either deletes all
attributes, or all attributes apart from those listed in the reply, or
triggers a specific entry in rlm_attr_filter.

But this is going outside the realm of JSON formatting.

Regards,

Brian.



More information about the Freeradius-Devel mailing list