Age | Commit message (Collapse) | Author |
|
* anders/diameter/DOIC/OTP-14588:
Exercise avp_dictionaries in traffic suite
Let generic AVPs be encoded/decoded in alternate dictionaries
Rename field in codec map: dictionary -> app_dictionary
Add RFC 7683 Diameter Overload Indicator Conveyance text and dictionary
Fix decode undef
Fix dictionary compilation error message
|
|
To support specifications like RFC 7683 DOIC, that only define AVPs, not
applications. AVPs that aren't known to the application dictionary in
question could previously not be decoded. Configuring alternate
dictionaries with the new transport/service option avp_dictionaries
changes this, so that AVPs like DOIC's Grouped OC-OLR can presented in
their fully decoded glory. Encode is also extended, allowing things like
the following to be encoded in an outgoing message:
'AVP' => [{'OC-OLR', #{'OC-Sequence-Number' => 1,
'OC-Report-Type' => 0,
'OC-Reduction-Percentage' => [25]}}]
A diameter_gen_doic_rfc7683 dictionary is installed, but
avp_dictionaries isn't specific to DOIC.
This commit also solves the problem demonstrated a few commits back,
that application AVPs aren't decoded in answers setting the E-bit. Test
coverage will come in a subsequent commit.
|
|
To better reflect what the field is: field 'module' is the dictionary
module that's calling diameter_gen to decode a list of AVP, while field
'app_dictionary' is the dictionary module defining the message being
decoded.
|
|
Which motivates the avp_dictionaries config that will be added in
a subsequent commit.
|
|
Function avp/5 isn't exported from dictionary modules. Not necessarily
intentional, but don't just export it since that requires recompilation
of all dictionary modules, since the function is in diameter_gen.hrl.
Not having to recompile was the main motivation for moving most of the
included code to module diameter_gen in commit 205521d3.
This reveals a weakness in the decode of answers setting the E-bit: any
AVP that isn't defined by the common application won't be decoded; the
diameter_avp records that these are packed into (in the 'AVP' field of a
message record, or equivalent) will have value = undefined. This is
nothing new (same in OTP 19), but the values should be decoded. Fix it
(and the lack of test coverage) in a subsequent commit that will add
avp_dictionaries config.
|
|
Adding a second {Vendor-Id} to the common CER definition results in
this error:
** AVP CER at line 85 already referenced at line 84
That is, the error incorrectly refers to the message name (CER) where the
AVP name (Vendor-Id) is expected.
|
|
* anders/diameter/decode_format/OTP-14511:
Map less in traffic suite
Fix decode_format doc oversights
Rename decode_format false to none
Tweak {decode_format, false} semantics
Fix dialyzer spec
|
|
* anders/diameter/config_consistency/OTP-14555:
Fix strict_arities blunder
Fix minor error-handling blunder
|
|
* anders/diameter/Proxy-Info/OTP-9869:
Fix handling of Proxy-Info in answers formulated by diameter
|
|
* anders/diameter/Experimental-Result/OTP-14511:
Fix extraction of Experimental-Result for counter keys
|
|
* anders/diameter/performance/OTP-14521:
Rename variable
Fix decode of too many generic AVPs
Enumerate AVPs in diameter_avp.index (again)
|
|
* anders/diameter/sctp/OTP-10889:
Send unordered on all outbound diameter_sctp streams
Delay rotation of diameter_sctp outbound streams
Exercise unordered delivery in traffic suite
Use unordered delivery on a lone outbound stream in diameter_sctp
|
|
Which reads better and makes it easier to distinguish this false from
others.
|
|
Represent the decoded message by its atom-valued name in
diameter_packet.msg, which makes trace much more readable. A
diameter_avp.value is untouched (ie. undefined): the AVP name is already
in the name field.
|
|
Which dialyzer hasn't noticed.
|
|
anders/diameter/decode_format/OTP-14511
* anders/diameter/config_consistency/OTP-14555:
Fix strict_arities blunder
Fix minor error-handling blunder
Let strict_mbit and incoming_maxlen be configured per transport
Let a service configure default transport options
Rename type evaluable -> eval
Document transport_opt() strict_capx
Rename transport_opt() capx_strictness to strict_capx
|
|
Remove value from the merged map, not from the maps being merged.
Bundled in commit 5f3becad.
|
|
Leading to this admonition from dialyzer:
diameter_config.erl:670: The variable No can never match since previous
clauses completely covered the type 'ok'
The throw was caught, but resulted in an error return without the
intended information.
|
|
RFC 6733 says this:
6.2. Diameter Answer Processing
When a request is locally processed, the following procedures MUST be
applied to create the associated answer, in addition to any
additional procedures that MAY be discussed in the Diameter
application defining the command:
...
o Any Proxy-Info AVPs in the request MUST be added to the answer
message, in the same order they were present in the request.
This wasn't done when a handle_request callback returned a Result-Code
in an 'answer-message' or protocol_error tuple, causing diameter itself
to construct the answer message. This form of answer is just a
convenience, since the callback can always return an answer that it
constructs itself.
|
|
The introduction of decode_format in commit 722fa415 (and then 55e65b26)
meant the value was not necessarily the intended tuple.
|
|
It's no longer the AVP name as of the parent commit, but the name of
the field/member the value will be stored in. Typically the AVP name,
but possibly 'AVP'.
|
|
That is, when the arity of an 'AVP' field has an upper bound. This
shouldn't happen in practice, but if an AVP is known but its name not
explicit in the message grammar then its count was confused with that
of AVPs packed into the 'AVP' field.
|
|
Commit 96cd627a changed the way the index field was used, but the
enumeration is used in at least one known application (as a pointer from
elements of diameter_packet.errors to elements of diameter_packet.avps)
and the motivation for the change is questionable: the lookup that was
avoided was unnecessary given that it was already performed in
incrementing a counter. Revert to enumerating as before in the non-relay
case, but not in the relay case since there's no corresponding usecase.
|
|
There's no reason for sending ordered since request handling is
concurrent: different processes handling incoming requests can't know in
which order they were received on the transport, and different processes
sending requests can't know the order in which they're sent.
|
|
For the same reason as unordered delivery is delayed in the grandparent
commit. Delivery is ordered only within a stream, so until a second
message is received from the peer, there's no guarantee that a second
outgoing request won't be received before the initial capablities
exchange message. Rotation begins upon reception of a second message
from the peer, messages being sent on stream 0 until then.
|
|
* anders/diameter/config_consistency/OTP-14555:
Let strict_mbit and incoming_maxlen be configured per transport
Let a service configure default transport options
Rename type evaluable -> eval
|
|
* anders/diameter/upgrade/OTP-14552:
Fix compatibility of remote send
|
|
* anders/diameter/strict_capx/OTP-14546:
Document transport_opt() strict_capx
Rename transport_opt() capx_strictness to strict_capx
|
|
* anders/diameter/performance/OTP-14521:
Fix influence of decode_format on service events
Work around more common_test woe
|
|
* anders/diameter/loopback_any/OTP-14544:
Use loopback/any config in examples suite
Handle loopback/any as local address in diameter_tcp/sctp
|
|
* anders/diameter/caseless/OTP-14535:
Replace calls to inet_parse(3)
Fix regexp match of accept tuple in diameter_tcp/sctp
|
|
RFC 6733 say the below about head-of-line blocking and SCTP, the
suggestion of unordered sending being new compared to the RFC 3588.
Until now, all delivery in diameter_sctp has been ordered, and
roundrobin over available streams unless the user passes a stream
identifier in an outgoing diameter_packet record. This commit changes
this to use unordered delivery when there's only a single outbound
stream to choose from.
The special case at capabilities exchange is handled by only starting to
send unordered after the second message from the peer has been received.
(First message after capabilities exchange, as the RFC probably means.)
The special case at DPR isn't handled, since there's no knowing the
order in which a peer will answer: a node that sends DPR while it has
other requests outstanding can't expect that the latter will be answered
before DPR, even if delivery is ordered since incoming requests are
handled concurrently. If it wants a guarantee then it simply has to wait
for answers before sending DPR.
A user can force all delivery to be unordered by specifying
{sctp_default_send_params, #sctp_sndrcvinfo{flags = [unordered]}}
as a config option to diameter_sctp, but in this case there's no
handling of a request being sent directly after CEA since there's no
ordered flag to override the default.
RFC 6733:
2.1.1. SCTP Guidelines
Diameter messages SHOULD be mapped into SCTP streams in a way that
avoids head-of-the-line (HOL) blocking. Among different ways of
performing the mapping that fulfill this requirement it is
RECOMMENDED that a Diameter node send every Diameter message (request
or response) over stream zero with the unordered flag set. However,
Diameter nodes MAY select and implement other design alternatives for
avoiding HOL blocking such as using multiple streams with the
unordered flag cleared (as originally instructed in RFC 3588). On
the receiving side, a Diameter entity MUST be ready to receive
Diameter messages over any stream, and it is free to return responses
over a different stream. This way, both sides manage the available
streams in the sending direction, independently of the streams chosen
by the other side to send a particular Diameter message. These
messages can be out-of-order and belong to different Diameter
sessions.
Out-of-order delivery has special concerns during a connection
establishment and termination. When a connection is established, the
responder side sends a CEA message and moves to R-Open state as
specified in Section 5.6. If an application message is sent shortly
after the CEA and delivered out-of-order, the initiator side, still
in Wait-I-CEA state, will discard the application message and close
the connection. In order to avoid this race condition, the receiver
side SHOULD NOT use out-of-order delivery methods until the first
message has been received from the initiator, proving that it has
moved to I-Open state. To trigger such a message, the receiver side
could send a DWR immediately after sending a CEA. Upon reception of
the corresponding DWA, the receiver side should start using out-of-
order delivery methods to counter the HOL blocking.
Another race condition may occur when DPR and DPA messages are used.
Both DPR and DPA are small in size; thus, they may be delivered to
the peer faster than application messages when an out-of-order
delivery mechanism is used. Therefore, it is possible that a DPR/DPA
exchange completes while application messages are still in transit,
resulting in a loss of these messages. An implementation could
mitigate this race condition, for example, using timers, and wait for
a short period of time for pending application level messages to
arrive before proceeding to disconnect the transport connection.
Eventually, lost messages are handled by the retransmission mechanism
described in Section 5.5.4.
|
|
Decoded CER/CEA messages are passed in events messages that can be
subscribed to using diameter:subscribe/1. A configured decode_format was
not reflected in these, messages always being passed as records.
Clarify that strict_arities only applies to message callbacks.
|
|
Since these can make sense per peer. The remaining service-only options
either belong there or make little sense being configured per transport.
|
|
Only a default spawn_opt has been possible to configure, but there's
no reason why most others should need to be configured per transport.
Those options that still only make sense on a transport are
transport_module/config (because of the semantics of multiple values),
applications/capabilities (since these override service options), and
private (since it's only to allow user-specific options in a backwards
compatible way).
|
|
Export the old type as a synonym for backwards compatability. The name
evaluable is a bit too awkward.
|
|
To follow the naming of options like strict_mbit and more. Still accept
capx_strictness since this is known to be used.
Introduced in commit e4f28f3b.
|
|
By changing the definition of the request record, commit f489c0d5 broke
sending an outgoing request over a peer connection terminated on a
remote node running an older version of diameter. The modified fields
aren't even used on the remote node, so simply reintroduce one of the
fields so that the size of the tuple is unchanged.
|
|
The support is implied by documentation, but wasn't handled in code. Be
consistent in retrieving the address from the sock rather than the
configuration, and in accepting both ip and ifaddr for a local address.
|
|
* anders/diameter/performance/OTP-14521:
Work around unexpected common_test behaviour
Randomly skip groups in traffic suite
Randomly disable traffic counters in traffic suite
Add service_opt() traffic_counters
Fix type spec
Split AVPs at decode
Avoid unnecessary copying of binaries in diameter_tcp
Don't update diameter_tcp state unnecessarily
Don't update diameter_tcp state unnecessarily
Simplify extraction of incoming Diameter messages in diameter_tcp
Restructure/simplify message reception in diameter_peer_fsm
Sleep randomly at the start of (parallel) traffic testcases
Fix ct return value in traffic suite
Fix type spec
Optimize sub-binaries
Optimize sub-binaries
Count AVPs in #diameter_avp.index
Don't extract options unnecessarily at encode
Redo message decode as a single pass
|
|
* anders/diameter/5009/OTP-14512:
Use relaxed arity checks in traffic suite
Be forgiving of non-list values at encode
Add service_opt() strict_arities
Fix detection of 5009 errors
Test Result-Code 5009 in traffic suite
|
|
* anders/diameter/codec/OTP-14511: (26 commits)
Limit SCTP testing in traffic suite
Increase init_per_group timetrap in traffic suite
Add diameter_util:eprof/1 for test
Don't search forms unnecessarily in diameter_exprecs parse transform
Increase init_per_suite timetrap in traffic suite
Don't count AVPs unnecessarily at encode
Test decode_format record_from_map in traffic suite
Tweak limiting of testcases in traffic suite
Don't take length of AVP lists unnecessarily at encode
Tweak map-valued decode
Rearrange group names in traffic suite
Randomly wrap answers in diameter_packet in transport suite
Don't exercise client/server encoding independently in traffic suite
Add decode_format record_from_map
Rename record_decode -> decode_format
Create fewer client connections in traffic suite
Test record_decode in traffic suite
Map answers to maps in traffic suite
Test map encoding in traffic suite
Let messages and grouped AVPs be decoded to lists
...
|
|
With the documented calls to inet(3).
|
|
Matching of remote addresses when accepting connections in a listening
transport was case-sensitive, causing the semantics to change as a
consequence of 95ebfa0b, which made inet:ntoa/1 return lowercase.
|
|
The forms being extracted are in the head of the split.
|
|
To be able to disable the counting of messages for which application
callbacks take place. Messages sent/handled by diameter itself are
always counted.
|
|
That dialyzer hasn't noticed is broken.
|
|
Despite what the Efficiency Guide says about match being more efficient,
split_binary appears to be slightly faster. (Although this one
extraction is a drop in the bucket.) Binary optimizations aren't an
issue during decode.
|
|
Since messages are accumulated by appending binaries as of three
commits back, the accumulated binary is prone to being copied, as
discussed in the Efficiency Guide. Matching the Message Length header
as bytes are being accumulated is one cause of this, so work around it
by splitting the binary and extracting the length without a match.
This doesn't feel like something that should be necessary: that matching
a binary would cause an append to copy isn't obvious. The first attempt
at simplifying the accumulation was simply to append an incoming binary
to the current fragment, match against <<_, Len:24, _/binary>> to
extract the length, and then test if there are enough bytes for a
message. This lead to horrible performance (response times for 2 MB
messages approximately 100 times worse than previously), and it wasn't
at all obvious that the reason was the accumulated binary being copied
with each append as a result of the match. Using split_binary avoids the
match context that forces the copying.
|
|
Not with each setopts to re-activate the socket.
|