aboutsummaryrefslogtreecommitdiffstats
path: root/lib/diameter/src
AgeCommit message (Collapse)Author
2015-03-23Add transport_opt() dpr_timeoutAnders Svensson
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.
2015-03-23Be lenient with errors in incoming DPRAnders Svensson
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.
2015-03-23Merge branch 'anders/diameter/dpr/OTP-12542' into maintAnders Svensson
* anders/diameter/dpr/OTP-12542: Discard CER or DWR sent with diameter:call/4 Allow DPR to be sent with diameter:call/4 Add transport_opt() dpa_timeout Add testcase for sending DPR with diameter:call/4
2015-03-23Merge branch 'anders/diameter/dpr/OTP-12543' into maintAnders Svensson
* anders/diameter/dpr/OTP-12543: Discard incoming requests after outgoing DPR Discard outgoing requests after outgoing DPR
2015-03-22Discard CER or DWR sent with diameter:call/4Anders Svensson
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.
2015-03-22Allow DPR to be sent with diameter:call/4Anders Svensson
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.
2015-03-22Add transport_opt() dpa_timeoutAnders Svensson
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.
2015-03-22Discard incoming requests after outgoing DPRAnders Svensson
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.
2015-03-22Discard outgoing requests after outgoing DPRAnders Svensson
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.
2015-03-22Merge branch 'anders/diameter/time/OTP-12439' into maintAnders Svensson
* anders/diameter/time/OTP-12439: Adapt to changes in time api
2015-03-19Adapt to changes in time apiAnders Svensson
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.
2015-03-05Merge branch 'anders/diameter/grouped_decode/OTP-12475' into maintAnders Svensson
* 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
2015-03-05Merge branch 'anders/diameter/time/OTP-12439' into maintAnders Svensson
* anders/diameter/time/OTP-12439: Use new time api in test suites Use new time api in implementation
2015-03-05Merge branch 'anders/diameter/pool/OTP-12428' into maintAnders Svensson
* 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
2015-03-05Merge branch 'anders/diameter/shutdown/OTP-12412' into maintAnders Svensson
* anders/diameter/shutdown/OTP-12412: Increase service shutdown timeout Set shutdown = infinity for supervisor children Monitor more efficiently at shutdown
2015-03-05Merge branch 'anders/diameter/retransmission/OTP-12415' into maintAnders Svensson
* anders/diameter/retransmission/OTP-12415: Fix retransmission of messages sent as header/avps list
2015-03-04Allow encode of decoded diameter_avp listAnders Svensson
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.
2015-03-04Fix handling of length errors on Grouped AVPsAnders Svensson
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.
2015-02-25Don't discard outgoing answers with Result-Code/E-bit errorsAnders Svensson
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.
2015-02-20Use new time api in implementationAnders Svensson
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.
2015-02-20Be backwards compatible with diameter_sctp listener stateAnders Svensson
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.
2015-02-20Remove (ancient) dead codeAnders Svensson
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.
2015-02-20Refresh example codeAnders Svensson
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.
2015-02-20Adapt tcp/sctp transport modules for pool_size > 1Anders Svensson
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.
2015-02-20Add transport_opt() pool_sizeAnders Svensson
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.
2015-01-19Fix retransmission of messages sent as header/avps listAnders Svensson
Extracting the End-to-End and Hop-by-Hop identifiers resulted in a function clause error, causing the send to fail.
2015-01-19Increase service shutdown timeoutAnders Svensson
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.
2015-01-19Set shutdown = infinity for supervisor childrenAnders Svensson
As suggested in supervisor(3). The leaves of the supervision tree should determine the timeouts.
2015-01-19Monitor more efficiently at shutdownAnders Svensson
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.
2014-12-01Update appup for 17.4Anders Svensson
OTP-12196 remote request table leak OTP-12233 3xxx result code without E-bit OTP-12281 ignored connect_timer OTP-12308 filter ordering
2014-12-01Merge branch 'anders/diameter/filters/OTP-12308' into maintAnders Svensson
* anders/diameter/filters/OTP-12308: Order peers in pick_peer callbacks
2014-12-01Merge branch 'anders/diameter/connect_timer/OTP-12281' into maintAnders Svensson
* 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
2014-12-01Merge branch 'anders/diameter/3xxx/OTP-12233' into maintAnders Svensson
* anders/diameter/3xxx/OTP-12233: Fix handling of 3xxx Result-Code without E-bit
2014-11-27Order peers in pick_peer callbacksAnders Svensson
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.
2014-11-03Tweak reason in closed eventAnders Svensson
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.
2014-11-03Fix ignored connect timerAnders Svensson
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.
2014-10-10Fix handling of 3xxx Result-Code without E-bitAnders Svensson
Commit 00584303 broke the population of the errors field of the diameter_packet record when an incoming request with an E-bit/Result-Code mismatch was decoded. Instead of the intended {5004, #diameter_avp{value = integer()}}, the value was a 4-tuple containing the integer Result-Code.
2014-09-25Fix remote diameter_request table leakAnders Svensson
An outgoing request whose pick_peer callback selected a transport on another node resulted in an orphaned diameter_request entry on that node.
2014-09-14Merge branch 'anders/diameter/Failed-AVP/OTP-12094' into maintAnders Svensson
* anders/diameter/Failed-AVP/OTP-12094: Fix ?MODULE in preprocessed dictionary forms
2014-09-12Fix ?MODULE in preprocessed dictionary formsAnders Svensson
By replacing literal diameter_gen_relay atoms in forms extracted from that module by the name of the module in question. This has been wrong for some time, but only became noticable when the parent commit started using ?MODULE as more than a process dictionary key or tag to match on. In particular, the function dict/1 in diameter_gen.hrl (included by every dictionary module) can now return ?MODULE, which is (not surprisingly) expected to be the name of the dictionary module in question. It wasn't in the case of a module compiled from forms: it was diameter_gen_relay, since that's the module the forms were extracted from. The fix only affects dictionaries compiled from forms, as returned by diameter_make:codec/2. In particular, dictionaries compiled from Erlang source returned by this function, or by diameterc(1), are unaffected.
2014-09-09Merge branch 'anders/diameter/17.3_release/OTP-12093' into maintAnders Svensson
* anders/diameter/17.3_release/OTP-12093: vsn -> 1.7.1 Update appup for OTP-12094 Update appup for OTP-12080 Update appup for OTP-12069
2014-09-09Merge branch 'anders/diameter/Failed-AVP/OTP-12094' into maintAnders Svensson
* anders/diameter/Failed-AVP/OTP-12094: Fix best effort decode of Failed-AVP Fix decode of Failed-AVP in RFC 3588 answer-message
2014-09-09Merge branch 'anders/diameter/counters/OTP-12080' into maintAnders Svensson
* anders/diameter/counters/OTP-12080: Fix counters for answer-message Count relayed messages on {relay, Rbit} Count request retransmissions Fix counting of outgoing requests
2014-09-08Update appup for OTP-12094Anders Svensson
diameter_codec must be loaded before diameter_traffic.
2014-09-08Update appup for OTP-12080Anders Svensson
2014-09-08Update appup for OTP-12069Anders Svensson
2014-09-08Fix best effort decode of Failed-AVPAnders Svensson
Commit c2c00fdd didn't get it quite right: it only decoded failed AVPs in the common dictionary since it's this dictionary an answer-message is decoded in. An extra dictionary isn't something that's easily passed through the decode without rewriting dictionary compilation however, and that's no small job, so continue with the use/abuse of the process dictionary by storing the dictionary module for the decode to retrieve. This is one step worse than previous uses since the dictionary is put in one module (diameter_codec) and got in another (the dictionary module), but it's the lesser of two evils.
2014-09-08Fix counters for answer-messageAnders Svensson
An answer message that sets the E-bit is encoded/decoded with Diameter common dictionary, using the answer-message grammar specified in the RFC. However, the dictionary of the application in question is the one that knows the command code of the message. Commit df19c272 didn't make this distinction when incrementing counters for an answer-message, using the common dictionary for both purposes, causing the message to be counted as unknown. This commit remedies that.
2014-08-05Map binary process info to a reference/byte countAnders Svensson
That is, instead of including the list in a diameter:service_info/2 info tuple, only include the number of references and the number of bytes referenced. The list itself can be quite large and typically isn't that interesting, at least not to a diameter user.
2014-08-05Count relayed messages on {relay, Rbit}Anders Svensson
Instead of grouping them with 'unknown'. These messages were keyed on {ApplicationId, CommandCode, Rbit} prior to commit df19c272, but distinguishing between the relay application and others is probably more useful. The only reason for not including the R-bit in the unknown key is that the key is also used elsewhere, and relay is an expected case while unknown isn't.