Age | Commit message (Collapse) | Author |
|
* 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
...
|
|
{record_decode, map} is a bit too quirky.
|
|
To control whether or not messages and grouped AVPs are decoded to
records, in #diameter_packet.msg and #diameter_avp.value respectively.
The decode became unnecessary for diameter's needs in parent commit,
which decoupled it from the checking of AVP arities.
|
|
Commit ca09cf7b caused an incoming CER or DPR to be regarded as
discarded in diameter_watchdog, resulting in a corresponding message
callback (if configured) in diameter_tcp/sctp.
|
|
* anders/diameter/performance/OTP-14343: (50 commits)
Let spawn_opt config replace erlang:spawn_opt/2 for request processes
Move (most of) diameter_gen.hrl to diameter_gen.erl
Change signature associated with dictionary @custom_type/@codecs
Avoid sending answer terms between processes unnecessarily
Refactor handling of incoming requests
Restore diameter_codec:decode/2, update diameter_codec(3)
Add diameter_codec option ordered_encode
Restore undocumented Failed-AVP setting convenience
Fix/simplify setting of one Failed-AVP
Avoid recreating records
Avoid recreating records
Avoid recreating records
Avoid recreating records
Adapt test suites to modified encode/decode
Simplify diameter_caps construction
Don't compute URI defaults unnecessarily
Don't deconstruct {TPid, Caps} unnecessarily
Remove use of process dictionary in decode
Remove minor diameter_config bloat
Fix maximum AVP arity check
...
|
|
* anders/diameter/transport/ERL-332: (35 commits)
Capitulate on SCTP vs sparc-sun-solaris2.10
Remove obsolete traffic testcase
Fix dialyzer warnings
Remove client/server string decode from traffic suite
Add diameter_sctp option packet
Add diameter_sctp send/recv callbacks
Let diameter_tcp send/recv callbacks deal in diameter_packet
Randomly select traffic testcases
Exercise diameter_tcp message callbacks in traffic suite
Exercise diameter_{tcp,sctp} sender in traffic suite
Remove upgrade from diameter_traffic
Add diameter_tcp send/recv callbacks
Make diameter_{tcp,sctp} sender configurable
Remove upgrade from diameter_sctp; tweak diameter_tcp to match
Fix incomprehensible dialyzer warning
Simplify acks to transport processes
Strip throttling callbacks from diameter_tcp
Deal with (another) SCTP association id quirk on Solaris
Use binary:copy/2 when generating largish data in test suites
Deal with SCTP association id quirk on Solaris
...
|
|
To allow list-valued messaged to be encoded in the specified order,
instead of in the dictionary order by first converting the list to a
record. This is not yet exposed in configuration.
|
|
By passing additional arguments through it.
|
|
|
|
What's interesting when implementing some form of load regulation is
when an incoming request has been answered or discarded. Acknowledge
exactly this, not the identity of handler processes as previously. A
transport process can request acks of nonforthcoming answers by sending
{diameter, ack} to the parent peer_fsm, a handler processes identifies
itself with a {handler, pid()} message, and the peer_fsm monitors on
this to be able to send a notification to the transport if the handler
dies before sending an answer.
|
|
Message length errors in incoming messages were misinterpreted with
transport_opt() {length_errors, exit} due to the throw introduced in
commit 2ffb288: the corresponding catch in incoming/2 caught errors
thrown by close/1, leading to failure when the error reason was
interpreted as a diameter_packet record. Do away with the throw, that
also caused woe in the parent commit.
|
|
|
|
* anders/diameter/capx_strictness/OTP-14257:
Add transport_opt() capx_strictness
|
|
|
|
To allow the Peer State Machine requirement that only the expected
capabilities exchange message be received in the relevant state to be
relaxed. If {capx_strictness, false} is configured then anything bu the
expected CER/CEA is ignored.
This is non-standard behaviour, and thusfar undocumented. Use at your
own risk.
|
|
When relaying outgoing requests through transport on a remote node,
terms that were stripped when sending to the transport process weren't
stripped when spawning a process on the remote node.
Also, don't save the request to the process dictionary in a process that
just relays an answer.
|
|
The table has existed forever, to route incoming answers to a waiting
request process: each outgoing request writes to the table, and each
incoming answer reads. This has been seen to suffer from lock contention
at high load however, so this commit moves the routing into the
diameter_peer_fsm processes that are diameter's conduit to transport
processes. The request table is still used for failover detection, but
entries are only written when a watchdog state transitions leaves or
enters state OKAY.
|
|
|
|
* anders/diameter/info/OTP-13508:
Add diameter:peer_find/1
Add diameter:peer_info/1
|
|
* anders/diameter/overload/OTP-13330:
Suppress dialyzer warning
Remove dead case clause
Let throttling callback send a throttle message
Acknowledge answers to notification pids when throttling
Throttle properly with TLS
Don't ask throttling callback to receive more unless needed
Let a throttling callback answer a received message
Let a throttling callback discard a received message
Let throttling callback return a notification pid
Make throttling callbacks on message reception
Add diameter_tcp option throttle_cb
|
|
To return a peer_fsm/transport pair given one of them.
|
|
In addition to returning ok or {timeout, Tmo}, let a throttling callback
for message reception return a pid(), which is then notified if the
message in question is either discarded or results in a request process.
Notification is by way of messages of the form
{diameter, discard | {request, pid()}}
where the pid is that of a request process resulting from the received
message. This allows the notification process to keep track of the
maximum number of request processes a peer connection can have given
rise to.
|
|
Record field types have been modified due to commit 8ce35b2:
"Take out automatic insertion of 'undefined' from typed record fields".
|
|
The diffs are all about adapting to the OTP 18 time interface. The code
was previously backwards compatible, falling back on the erlang:now/0 if
erlang:monotonic_time/0 is unavailable, but this was seen to be a bad
thing in commit 9c0f2f2c. Use of erlang:now/0 is now removed.
|
|
Last visited in commit 00584303.
|
|
OTP-12845
* bruce/change-license:
fix errors caused by changed line numbers
Change license text to APLv2
|
|
Not needed with the parent commit's restart_application.
|
|
|
|
To bound the length of incoming messages that will be decoded. A message
longer than the specified number of bytes is discarded. An
incoming_maxlen_exceeded counter is incremented to make note of the
occurrence.
The motivation is to prevent a sufficiently malicious peer from
generating significant load by sending long messages with many AVPs for
diameter to decode. The 24-bit message length header accomodates
(16#FFFFFF - 20) div 12 = 1398099
Unsigned32 AVPs for example, which the current record-valued decode is
too slow with in practice. A bound of 16#FFFF bytes allows for 5461
small AVPs, which is probably more than enough for the majority of
applications, but the default is the full 16#FFFFFF.
|
|
* anders/diameter/dpr/OTP-12609:
Discard incoming/outgoing requests after incoming DPR
Add transport_opt() dpr_timeout
Be lenient with errors in incoming DPR
|
|
Despite claims of full backwards compatibility, the text of RFC 6733
changes the interpretation of unspecified values in a DiameterURI. In
particular, 3588 says that the default port and transport are 3868 and
sctp respectively, while 6733 says it's either 3868/tcp (aaa) or
5658/tcp (aaas). The 3588 defaults were used regardless, but now use
them only if the common dictionary is diameter_gen_base_rfc3588. The
6733 defaults are used otherwise.
This kind of change in the standard can lead to interop problems, since
a node has to know which RFC its peer is following to know that it will
properly interpret missing URI components. Encode of a URI includes all
components to avoid such confusion.
That said, note that the defaults in the diameter_uri record have *not*
been changed. This avoids breaking code that depends on them, but the
risk is that such code sends inappropriate values. The record defaults
may be changed in a future release, to force values to be explicitly
specified.
|
|
* anders/diameter/string_decode/OTP-11952:
Let examples override default service options
Set {restrict_connections, false} in example server
Set {string_decode, false} in examples
Test {string_decode, false} in traffic suite
Add service_opt() string_decode
Strip potentially large terms when sending outgoing Diameter messages
Improve language consistency in diameter(1)
|
|
To control whether stringish Diameter types are decoded to string or
left as binary. The motivation is the same as in the parent commit: to
avoid large strings being copied when incoming Diameter messages are
passed between processes; or *if* in the case of messages destined for
handle_request and handle_answer callbacks, since these are decoded in
the dedicated processes that the callbacks take place in. It would be
possible to do something about other messages without requiring an
option, but disabling the decode is the most effective.
The value is a boolean(), true being the default for backwards
compatibility. Setting false causes both diameter_caps records and
decoded messages to contain binary() in relevant places that previously
had string(): diameter_app(3) callbacks need to be prepared for the
change.
The Diameter types affected are OctetString and the derived types that
can contain arbitrarily large values: OctetString, UTF8String,
DiameterIdentity, DiameterURI, IPFilterRule, and QoSFilterRule. Time and
Address are unaffected.
The DiameterURI decode has been redone using re(3), which both
simplifies and does away with a vulnerability resulting from the
conversion of arbitrary strings to atom.
The solution continues the use and abuse of the process dictionary for
encode/decode purposes, last seen in commit 0f9cdba.
|
|
With the same motivation as in commits 5bd2d72 and b1fd629.
As in the latter, incoming DPR is the only exception.
|
|
To cause a peer connection to be closed following an outgoing DPA, in
case the peer fails to do so. It is the recipient of DPA that should
close the connection according to RFC 6733.
|
|
To avoid having the peer interpret the error as meaning the connection
shouldn't be closed, which probably does more harm than ignoring
syntactic errors in the DPR.
Note that RFC 6733 says this about incoming DPR, in 5.4 Disconnecting
Peer Connections:
Upon receipt of the message, the Disconnect-Peer-Answer message is
returned, which SHOULD contain an error if messages have recently been
forwarded, and are likely in flight, which would otherwise cause a race
condition.
The race here is presumably between answers to forwarded requests and
the outgoing DPA, but we have no handling for this: whether or not there
are pending answers is irrelevant to how DPR is answered. It's
questionable that a peer should be able to prevent disconnection in any
case: it has to be the node sending DPR that decides if it's approriate,
and the peer should take it as an indication of what's coming.
Incoming DPA is already treated leniently: the only error that's not
ignored is mismatching End-to-End and Hop-by-Hop Identifiers, since
there's no distinguishing an erroneous value from an unsolicited DPA.
This mismatch could also be ignored, which is the case for DWA for
example, but this problem is already dealt with by dpa_timeout, which
causes a connection to be closed even when the expected DPA isn't
received.
|
|
These are requests that diameter itself sends. It's previously been
possible to send them, but answers timed out at the caller since they
were discarded in diameter_watchdog. Answers will still timeout, but now
the requests are discarded before being sent.
|
|
DPR is sent by diameter at application shutdown, service stop, or
transport removal. It has been possible to send the request with
diameter:call/4, but the answer was discarded, instead of the transport
process being terminated. This commit causes DPR to be handled in the
same way regardless of whether it's sent by diameter or by
diameter:call/4.
Note that the behaviour subsequent to DPA is unchanged. In particular,
in the connecting case, the closed connection will be reestablished
after a connect_timer expiry unless the transport is removed. The more
probable use case is the listening case, to disconnect a single peer
associated with a listening transport.
|
|
To make the default DPA timeout configurable. The timeout say how many
milliseconds to wait for DPA in response to an outgoing DPR before
terminating the transport process regardless.
|
|
Since there's a race between an answer being sent and the connection
being closed upon the reception of DPA that's likely to be lost, and
because of the questionability of sending messages after DPR, as
discussed in the parent commit. An exception is made for DPR so that
simultaneous DPR in both directions doesn't result in it being discarded
on both ends.
|
|
RFC 6733 isn't terribly clear about what should happen to incoming or
outgoing messages once DPR is sent and the Peer State Machine
transitions into state Closing. There's no event for this in section
5.6, Peer State Machine, and no clarification in section 5.4,
Disconnecting Peer Connections. There is a little bit of discussion in
2.1.1, SCTP Guidelines, in relation to unordered message delivery, but
the tone there is that messages might be received after DPR because of
unordered delivery, not because they were actually sent after DPR.
Discarding outgoing answers may do more harm than good, but requests are
more likely to be unexpected, as has been seen to be the case with DWR
following DPR. DPR indicates a desire to close the connection: discard
any subsequent outgoing requests.
|
|
From {error, Reason} to {no_connection, Reason} when a connection can't
be established. The exit reason of a diameter_peer_fsm process is turned
into a message from the corresponding diameter_watchdog process to the
relevant diameter_service process, the latter sending a 'closed' event
including the reason to any subscribers. Reason = [] when none of the
configured transport modules succeeds in establishing a connection,
which admittedly isn't terribly descriptive. (The lists is of error
reasons from transport start functions, which is empty as long as
transport processes start successfully.)
Note that this form of the closed event is undocumented, aside from the
documentation saying that one should expect undocumented events. The
explicitly documented forms are currently specific to CER/CEA failures.
|
|
Commit df19c272 broke this in avoiding counting on arbitrary keys.
It didn't break it sufficiently for the only counters usage in the test
suites to fail however: watchdog counters worked as intended, but no
others, not even CER and DPR. More testcases are needed.
This commit does change/fix the previous semantics somewhat:
- Retransmissions are no longer counted. This previously made it
impossible to distinguish between these and unanswered requests, since
both counted as an outgoing request. There should probably be a
retransmission counter but it should be distinct from the sent request
counter.
- The counting is always on the node from which diameter:call/4 is
invoked, not the node on which the transport resides, as was previously
the case. (Although they're typically one and the same.)
Note that none of these semantics are documented as yet, so we're not
changing a documented interface.
|
|
* anders/diameter/hardening/OTP-11721:
Simplify example server
Make example server answer unsupported requests with 3001
Make example code quiet
Don't count messages on arbitrary keys
Replace traffic-related log reports with no-op function calls
|
|
That is, don't use a key constructed from an incoming Diameter header
unless the message is known to the dictionary in question. Otherwise
there are 2^32 application ids, 2^24 command codes, and 2 R-bits for an
ill-willed peer to choose from, each resulting in new keys in the
counter table (diameter_stats).
The usual {ApplicationId, CommandCode, Rbit} in a key is replaced by the
atom 'unknown' if the message in question is unknown to the decoding
dictionary.
Counters for messages sent and received by a relay are (still) not
implemented.
|
|
The former were a little over-enthusiastic and could cause a node to be
logged to death if a peer Diameter node was sufficiently ill-willed.
The function calls are to diameter_lib:log/4, the arguments of which
identify the happening in question, and which does nothing but provide a
function to trace on. Many existing log calls have been shrunk.
The only remaining traffic-related report (hopefully) is that resulting
from {answer_errors, report} config, and this has been slimmed.
|
|
* anders/diameter/dpr/OTP-11938:
Ensure watchdog dies with transport if DPA was sent
|
|
* anders/diameter/rc_counters/OTP-11937:
Count encode errors in outgoing messages
Count decode errors in incoming requests
Count decode errors independently of result codes
|
|
* anders/diameter/rc_counters/OTP-11891:
Count result codes in CEA/DWA/DPA
|
|
A DPR/DPA exchange should always cause the watchdog process in question
to die with the transport, so that a subsequent connection with the same
peer doesn't result in a 3 x DWR/DWA exchange. Commit 5903d6db saw to
this for the sending of DPR but neglected the corresponding problem for
DPA.
In the case of sending DPR (the aforementioned commit), note that
there's no distinction between receiving DPA as expected and not: the
watchdog dies with the transport regardless.
diameter_watchdog must be loaded first at upgrade.
|