Age | Commit message (Collapse) | Author |
|
* anders/diameter/one_failed_avp/OTP-11127:
Adapt CEA/DPA Failed-AVP to RFC 6733
|
|
* anders/diameter/5xxx_failed_avp/OTP-11092:
Fix setting of Failed-AVP on {answer_message, 5xxx} from handle_request
|
|
RFC 6733 says that certain 5xxx result codes must be accompanied by
Failed-AVP, and decode populates #diameter_packet.errors with
Result-Code/AVP pairs for errors it detects. However, Failed-AVP was not
set in the outgoing answer if the handle_request callback returned
{answer_message, 5xxx}. It is now set with the AVP from the first pair
with the specified Result-Code, if found.
Note that {answer_message, 5xxx} doesn't handle all cases in which a
5xxx answer is required, only that in which the setting above is
appropriate. If it isn't then handle_request should construct its answer
and return {reply, Ans}.
|
|
* anders/diameter/host_ip_address/OTP-11045:
Respect Host-IP-Address configuration
|
|
Addresses returned from a transport module were always used to populate
Host-IP-Address AVP's in an outgoing CER/CEA, which precluded the
sending of a VIP address. Transport addresses are now only used if
Host-IP-Address is unspecified.
In other words, respect any configured Host-IP-Address, regardless of
the physical addresses returned by the transport. To use the physical
addresses, don't configure Host-IP-Address.
|
|
By setting only one, not many. The handling for other messages (except
DWA, which is forgiving of errors) was dealt with in commit f7ec93e3.
|
|
RFC 6733 recommends against the use of Inband-Security-Id, so only send
a value that differs from the default.
|
|
* anders/diameter/watchdog_function_clause/OTP-11115:
Fix watchdog function_clause
|
|
Commit 0b7c87dc caused diameter_watchdog:restart/2 to start returning
'stop', so that a watchdog process for a listening transport that
allowed multiple connections to the same peer would die one watchdog
timeout after losing a connection. The new return value was supposed to
be passed up to transition/2, but was instead passed to set_watchdog/1,
resulting in a function_clause error. The resulting crash was harmless
but unseemly.
Not detected by dialyzer.
Thanks to Aleksander Nycz.
|
|
When setting these from an #diameter_packet.errors list, select one
Result-Code or {Result-Code, Failed-AVP}, instead of accumulating all
AVP's from the 2-tuples in the list. This is more in keeping with RFC
6733:
7.5. Failed-AVP AVP
The Failed-AVP AVP (AVP Code 279) is of type Grouped and provides
debugging information in cases where a request is rejected or not
fully processed due to erroneous information in a specific AVP. The
value of the Result-Code AVP will provide information on the reason
for the Failed-AVP AVP. A Diameter answer message SHOULD contain an
instance of the Failed-AVP AVP that corresponds to the error
indicated by the Result-Code AVP. For practical purposes, this
Failed-AVP would typically refer to the first AVP processing error
that a Diameter node encounters.
The text of RFC 3588 was less specific, not including the last two
sentences.
Note that an improper AVP Length will result in both 5014 and 5005 being
detected for the same AVP. Without this commit, Failed-AVP would be
populated with two AVP's for the same error.
|
|
|
|
Invalid lengths come in two flavours: ones that correctly point at the
end of an AVP's payload but don't agree with its type, and ones that
point elsewhere. The former are relatively harmless but the latter leave
no way to recover AVP boundaries, which typically results in failure to
decode subsequent AVP's in the message in question.
In the case that AVP Length points past the end of the message, diameter
incorrectly regarded the error as 5009, INVALID_AVP_BITS: not right
since the error has nothing to do with AVP Flags. Ditto if the length
was less than 8, a minimal header length. Only in the remaining case was
the detected error 5014, INVALID_AVP_LENGTH. However, in this case it
slavishly followed RFC 3588 in suggesting the undecodable AVP as
Failed-AVP, thereby passing the woeful payload back to the sender to
have equal difficulty decoding. Now follow RFC 6733 and suggest an AVP
with a zero-filled payload.
|
|
When setting Failed-AVP in a message record, it was never tested that
the field was actually present. RFC 6733 says it should be, 3588 says
MAY.
|
|
Such a length caused decode of a message with valid (24-bit) length to
fail. Note that the error detected is wrong: it should be 5014
(INVALID_AVP_LENGTH), not 3009 (INVALID_AVP_BITS). This will be dealt
with by OTP-11007.
|
|
* anders/diameter/watchdog_leak/OTP-11019:
Minor doc fix
Add testcase to exercise reconnect behaviour
Fix watchdog table leak
|
|
A transport module can return a local address list from its start/3
function in order to specify addresses to be used as Host-IP-Address
during capabilities exchange. Now allow addresses to be communicated in
a 'connected' message in the case of a connecting transport, so that
diameter_tcp (in particular) can make local address configuration
optional, communicating the gen_tcp default after connection
establishment instead.
|
|
A service process maintains a table keyed on watchdog process pids. When
a watchdog process dies the corresponding entry should be removed but
this was broken in commit f115a9f7, causing entries with watchdog state
DOWN to accumulate.
Watchdog processes die as a result of diameter:remove_transport/2, or
when a peer reestablishes a connection in the listening case. Neither is
typically a frequent occurrence.
The fault manifests itself in the return value of
diameter:service_info(SvcName, transport), which displays entries for
watchdog processes that are no longer alive.
|
|
{error, Reason} is now returned, instead of the options being ignored.
Note that diameter:add_transport/2 purposely ignores unknown options and
that the behaviour is documented. This is historic: some users depend on
it in order to store their own options for identifying transport config,
instead of using the reference returned by add_transport.
|
|
The validation of {sequence, {H,N}} incorrectly checked that H was an
N-bit integer, instead of the intended 32-N.
|
|
Crashing watchdog and peer_fsm processes was somewhat unseemly. Emit an
error report and die silently instead.
|
|
Faulty configuration was previously passed directly on to watchdog and
peer_fsm processes, diameter:add_transport/2 happily returning ok and
the error resulting on failure of watchdog and/or peer_fsm processes.
Now check for errors before getting this far, returning {error, Reason}
from diameter:add_transport/2 when one is detected. There are still
some errors that can only be detected after transport start (eg. a
misbehaving callback) but most will be caught early.
|
|
'infinity' is a valid transport_config timeout.
|
|
Remove unused functions, add dialyzer specs, make wait/1 less fallible.
|
|
|
|
|
|
RFC 6733 has changed the arity of Vendor-Id in this Grouped AVP, from 1*
in RFC 3588 to 1 in RFC 6773. This impacts the generated dictionary
modules: Vendor-Id is expected to be list-valued in the 3588 dictionary,
integer-valued in the 6733 dictionary. This, in turn, breaks the
independence of capabilities configuration on a service or transport
from the dictionary that will be used to encode an outgoing CER or CEA.
This commit fixes this by massaging any Vendor-Specific-Application-Id
config as appropriate when constructing CER or CEA for a given
dictionary.
|
|
|
|
Allow both share_peers and use_shared_peers to be a list of nodes, or a
function that returns a list of nodes.
|
|
This is the functionality that allows transports to be shared between
identically-named services on different nodes, which has been neither
documented nor tested (until now).
|
|
Make it just a number of timeouts, without a new DWR being sent.
|
|
Counters read by diameter:service_info(SvcName, transport) can be
selected at the same time as the diameter_stats server is folding them
into another key, possibly resulting in inaccurate values. Have
diameter_stats select from the server process to avoid this and add
diameter_stats:sum/1 to sum values from all contributors on a given
term.
|
|
|
|
To make the number of watchdogs sent before the transitions REOPEN ->
OKAY and OKAY -> SUSPECT configurable. Using anything other then the
default config is non-standard and should only be used for test.
|
|
Also add comments to identify the corresponding OTP releases.
Purposely don't use regexp version numbers to be explicit about
previously released versions. (Could use them in one direction but then
app suite needs to be adapted.)
|
|
RFC 3588 allowed only 3xxx result codes in an answer-message (that is,
an answer that sets the E-bit) while RFC 6733 also allows 5xxx result
codes. Setting request_errors = answer tells diameter to answer 5xxx
errors itself. Returning {answer_message, integer()} from a
handle_request callback allows both 3xxx and 5xxx result codes to be
set. {protocol_error, integer()} is retained for 3xxx result codes.
|
|
In particular, don't put an error tuple in the errors field of
a #diameter_packet{} when Result-Code and the E-bit are in conflict, put
{integer(), #diameter_avp{}}.
|
|
When receiving a request for which errors have been detected during
decode, diameter previously used the errors list in the decoded
diameter_packet record to unconditionally set Result-Code and Failed-AVP
in the outgoing answer. It wasn't particularly delicate in doing so
however and would happily set a 5xxx Result-Code even if a
handle_request callback returned an answer-message, leading to an encode
error. This behaviour became even less endearing as of commit ac452e28,
which made it possible to handle_request to take place even for protocol
errors. (ie. When a callback typically should return an answer-message.)
This commit fixes the behaviour by only setting a value that's
appropriate for the answer in question, either a 3xxx or a 5xxx,
depending on if the answer's an answer-message or not. It also allows
handle_request to prevent diameter from setting anything by setting
errors = false in a returned diameter_packet. Ideally it should have
been errors = [] but the empty list is the default value for the errors
field and changing the default (ideally there shouldn't have been one)
would require recompilation of all modules including diameter.hrl:
choose the less attractive 'false' to avoid such backwards
incompatibility.
The request reception is also refactored somewhat to shorten some call
chains.
|
|
Configuring the value 'callback' all errors detected in incoming
requests to result in a handle_request callback. The default value
'answer_3xxx' is the previous behaviour in which diameter answers
protocol errors without a callback.
|
|
The value determines whether or not an unexpected message length in the
header of an incoming messages causes the peer process to exit, the
message to be discarded or handled as usual. The latter may only be
appropriate for message-oriented transport (eg. SCTP) since
stream-oriented transport (eg. TCP) may not be able to recover the
message boundary once a length error has occurred.
|
|
|
|
|
|
Traffic handling is connected to the service implementation through the
pick_peer callback and failover but diameter_service was getting
unwieldy as home to both the service process and traffic handling.
|
|
In particular, remove fields containing values that are known (as of the
preceding commit) to the request process.
|
|
In order to be able to remove fields from the request process that don't
need to be there and do less in the service process. The pick_peer
callback now takes place in the request process in the case of immutable
state, just as in the case of the initial send.
|
|
The generated '#get-'/1 has one clause for each exported record r, whose
definition is equivalent to the following.
'#get-'(#r{} = Rec) ->
[r | lists:zip(record_info(r, fields), tl(tuple_to_list(Rec)))];
The record name at the head of the list is the same format that diameter
accepts for outgoing message.
|
|
Instead, use whatever dictionary a transport has configured as
supporting application id 0. This is to support the updated RFC 6733
dictionaries (which bring with them updated records) and also to be able
to transparently support any changed semantics (eg. 5xxx in
answer-message).
|
|
There is no such transition in RFC 3539, the state remains in INITIAL.
|
|
This was the result of the watchdog process exiting as a consequence of
peer death in some casesi, causing a restarted transport to enter
INITIAL when it should enter REOPEN. The watchdog now remains alive as
long as peer shutdown isn't requested and a 'close' message to the
service process (instead of watchdog death) generates 'closed' events
from the service.
|
|
|
|
That is, make the naming match that of the corresponding modules.
This has long been fairly confusing.
|