Age | Commit message (Collapse) | Author |
|
* anders/diameter/dpr/OTP-12543:
Discard incoming requests after outgoing DPR
Discard outgoing requests after outgoing DPR
|
|
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.
|
|
* anders/diameter/17/time/OTP-12439:
Adapt app suite to changes in time api
|
|
* anders/diameter/time/OTP-12439:
Adapt to changes in time api
|
|
* anders/diameter/pool/OTP-12428:
Add pool_size test to config suite
|
|
Overlooked in commit 4b691d8d.
|
|
erlang:convert_time_resolution/3 has been renamed to convert_time_unit.
erlang:time_resolution/0 has been removed: use new time resolution
values instead.
|
|
erlang:time_resolution/0 has been removed,
erlang:convert_time_resolution/3 has been renamed convert_time_unit, and
{os,erlang}:system_time/0,1 have been added. Modify the list of ignored
undefined function calls accordingly.
|
|
* anders/diameter/grouped_decode/OTP-12475:
Allow encode of decoded diameter_avp list
Add testcases for diameter_avp decode
Fix handling of length errors on Grouped AVPs
Don't discard component diameter_avp list on Grouped AVP decode error
Fix process dictionary manipulation during message decode
|
|
* anders/diameter/17/time/OTP-12439:
Ignore undefined calls to OTP 18 time api in app suite
|
|
* anders/diameter/time/OTP-12439:
Use new time api in test suites
Use new time api in implementation
|
|
* anders/diameter/pool/OTP-12428:
Fix SCTP match blunder in suites
Be backwards compatible with diameter_sctp listener state
Add gen_tcp testcase that fails sporadically
Simplify transport suite
Remove (ancient) dead code
Don't orphan slave nodes in example suite
Refresh example code
Improve language consistency in diameter(1)
Add pool suite to test transport_opt() pool_size
Adapt tcp/sctp transport modules for pool_size > 1
Add transport_opt() pool_size
|
|
* anders/diameter/shutdown/OTP-12412:
Increase service shutdown timeout
Set shutdown = infinity for supervisor children
Monitor more efficiently at shutdown
|
|
* anders/diameter/retransmission/OTP-12415:
Fix retransmission of messages sent as header/avps list
|
|
The decode of an incoming request in a non-relay application results in
a deep list of diameter_avp records. Encoding such a list resulted in a
function_clause error in diameter_codec:pack_avp/1, which expected a
flat list. The list is only flat in the relay case, or in the absence of
AVPs of type Grouped.
This is also related to code that exists but isn't documented. It's
documented that a diameter_app(3) handle_request callback can return
{relay, Opts} to relay a request received in the relay application.
What's not documented is that it can also return {proxy|resend, Opts} in
a non-relay application, but this leads to encode failure when there are
Grouped AVPs. This shouldn't be interpreted as meaning that proxy|resend
are now supported: they aren't. The two extra terms are a historical
relic that should probably be removed. Neither are generally usable
since, for example, a proxy agent may want to modify a request before
resending it. A specific handle_request return is not needed to
implement a proxy agent. Even {relay, Opts} isn't strictly necessary.
|
|
|
|
The decode of a Grouped AVP ignored the case that extracting component
AVPs with diameter_codec:collect_avps/1 returned a tuple, in the case of
a truncated AVP header.
|
|
So that the xref testcase is independent of the release it's run on. The
code uses the new time api if available, so as to be forward compatible.
|
|
Clause matching error for specific test cases was harmless since the
subsequent clause also matched. Errors detected by the server result in
Failed-AVP being sent, which should not lead to a decode error in the
client.
|
|
Outgoing answers missing a Result-Code AVP or setting an E-bit
inappropriately were discarded, but there's no particular reason for
doing so if the answer can be encoded, and the sender has no way of
knowing that their answer has been discarded. It's also inappropriate
that the message be discarded in the relay case. Answers are now sent,
and an error counter incremented.
|
|
More than an incoming message can contain ancillary data, which the
gen_sctp and transport suites did not expect. On FreeBSD 10, an
sctp_assoc_change event appears always to contain ancillary data.
|
|
Where it's less important to do so, but it has to be done at some point
since erlang:now/0 is deprecated. As in the parent commit, continue to
use the old api if the new one is unavailable.
|
|
In particular, deal with the deprecation of erlang:now/0 in OTP 18. Be
backwards compatible with older releases: the new api is only used when
available.
The test suites have not been modified.
|
|
Commit 24993fc2 modified the state even in the case that the new
pool_size option the change was introduced to support was not used.
Doing so made downgrade impossible since old code would not be prepared
for the modified state. Retain a compatible state, so that simple code
replacement is enough.
|
|
On OS X at least. The testcase opens a listening socket, spawns 8
processes that call gen_tcp:accept/1, waits a couple of seconds, and
then spawns 8 processes that call gen_tcp:connect/3. Some of these
occasionally return {error, econnreset}.
|
|
Using the fact that transport processes can now be started concurrently.
The suite serialized starts itself when pretending to be diameter
starting a transport process.
|
|
Commit 9a671bf0 removed the need for diameter_sctp to send outgoing
messages through the listening process. That was prior to R5B02, so the
clause isn't need for any upgrade case.
|
|
Stops were aborted at the first failure.
|
|
Which hasn't received any attention for some time. Clean it up, rename
the poorly named peer.erl (it's Diameter *nodes* that are implemented),
and make the it possible to specify arbitrary transport configuration.
|
|
In particular, do away with unnecessary articles in the first sentence
of item lists.
|
|
With testcases that uses restrict_connections and pool_size config to
establish multiple connections between two Diameter nodes, checking for
the expected number of transport processes using
diameter:service_info/2.
|
|
In particular, that starts for the same transport reference can now be
concurrent. Looking up a listener process and starting a new one if not
found did handle this (more than one process could find no listener),
and diameter_sctp assumed there could only be one transport process
waiting for an association.
|
|
Transport processes are started by diameter one at a time. In the
listening case, a transport process accepts a connection, tells the
peer_fsm process, which tells its watchdog process, which tells its
service process, which then starts a new watchdog, which starts a new
peer_fsm, which starts a new transport process, which (finally) goes
about accepting another connection. In other words, not particularly
aggressive in accepting new connections. This behaviour doesn't do
particularly well with a large number of concurrent connections: with
TCP and 250 connecting peers we see connections being refused.
This commit adds the possibilty of configuring a pool of accepting
processes, by way of a new transport option, pool_size. Instead of
diameter:add_transport/2 starting just a single process, it now starts
the configured number, so that instead of a single process waiting for a
connection there's now a pool.
The option is even available for connecting processes, which provides an
alternate to adding multiple transports when multiple connections to the
same peer are required. In practice this also means configuring
{restrict_connections, false}: this is not implicit.
For backwards compatibility, the form of
diameter:service_info(_,transport) differs in the connecting case,
depending on whether or not pool_size is configured.
Note that transport processes for the same transport_ref() can be
started concurrently when pool_size > 1. This places additional
requirements on diameter_{tcp,sctp}, that will be dealt with in a
subsequent commit.
|
|
The AVPs of an incoming Diameter message diameter_codec:decode/2,3 are
decoded into a diameter_packet record in two ways: as a message-specific
record in the 'msg' field and as a deep list of diameter_avp records in
the 'avps' field. The record decode came first; the diameter_avp decode
came later to support the Diameter relay application, but can also be
convenient for non-relay applications. The diameter_avp representation
can be used with outgoing messages, but what exactly is supported for
isn't clearly documented.
In the diameter_avp list representation, it's AVPs of type Grouped that
lead to nesting: instead of a diameter_avp record, a Grouped AVP is
represented by a diameter_avp list whose head is the Grouped AVP itself,
and whose tail is the list of component AVPs.
The diameter_avp decode was broken in the case of decode errors: the
Grouped AVP was represented as a bare diameter_avp, and the component
records were lost. The decode now produces the intended list. Note that
component AVPs that could not be decoded will have 'undefined' in their
data field.
|
|
Decode can span multiple codec modules, so written entries cannot be
tagged on ?MODULE.
|
|
Extracting the End-to-End and Hop-by-Hop identifiers resulted in a
function clause error, causing the send to fail.
|
|
Shutting down the service causes DPR to be sent on all open transports
under the service. These in turn have a timeout for the reception of
DPA, but the timeout is bounded by the supervisor's in practice. Both
timeouts were 1 second. Increase the supervisor timeout to 5 seconds.
Note that the service supervisor is furthest to the right in the
supervision tree in diameter_sup. Thus is significant, so that the
transport-related processes aren't shutdown first.
|
|
As suggested in supervisor(3). The leaves of the supervision tree should
determine the timeouts.
|
|
There's no need for building a pid list only to map it to a list of
monitor references. Also, monitoring before banging the shutdown
message makes for better trace, avoiding unnecessary noproc reasons when
the process dies before the monitor is created.
|
|
|
|
|
|
OTP-12196 remote request table leak
OTP-12233 3xxx result code without E-bit
OTP-12281 ignored connect_timer
OTP-12308 filter ordering
|
|
* anders/diameter/filters/OTP-12308:
Order peers in pick_peer callbacks
|
|
* anders/diameter/connect_timer/OTP-12281:
Tweak reason in closed event
Fix ignored connect timer
Check {connect,watchdog}_timer distinction in event testcases
Rename reconnect_timer to connect_timer in examples and suites
|
|
* anders/diameter/3xxx/OTP-12233:
Fix handling of 3xxx Result-Code without E-bit
|
|
The order of peers presented to a diameter_app(3) pick_peer callback has
previously not been documented, but there are use cases that are
simplified by an ordering. For example, consider preferring a direct
connection to a specified Destination-Host/Realm to any host in the
realm. The implementation previously treated this as a special case by
placing matching hosts at the head of the peers list, but the
documentation made no guarantees. Now present peers in match-order, so
that the desired sorting is the result of the following filter.
{any, [{all, [host, realm]}, realm]}
The implementation is not backwards compatible in the sense that a realm
filter alone is no longer equivalent in this case. However, as stated,
the documentation never made any guarantees regarding the sorting.
|
|
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.
|
|
There are two timers governing the establishment of peer connections:
connect_timer and watchdog_timer. The former is the RFC 6733 Tc timer
and is used by diameter_service to establish an initial connection. The
latter is RFC 3539 TwInit and is used by diameter_watchdog for
connection reestablishment after the watchdog leaves state INITIAL. A
connecting transport ignored the connect timer since the watchdog
process never died, regardless of the watchdog state, causing the
watchdog timer to handle reconnection.
This seems to have been broken for some time.
|
|
The connect timer is currently ignored by a connecting transport,
so the check causes one testcase to fail.
|