aboutsummaryrefslogtreecommitdiffstats
path: root/lib/diameter/src/base
AgeCommit message (Collapse)Author
2015-03-24Merge branch 'anders/diameter/route_record/OTP-12551' into maintAnders Svensson
* anders/diameter/route_record/OTP-12551: Fix ordering of AVPs in relayed messages
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-23Fix ordering of AVPs in relayed messagesAnders Svensson
6.1.9 of RFC 6733 states this: A relay or proxy agent MUST append a Route-Record AVP to all requests forwarded. The AVP was inserted as the head of the AVP list, not appended, since the entire AVP list was reversed relative to the received order. Thanks to Andrzej TrawiƄski.
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-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-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-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-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.
2014-08-05Count request retransmissionsAnders Svensson
As mentioned in the parent commit. The {Id, send, retransmission} key is of the same form as the {Id, send|recv, error} key used for encode/decode errors.
2014-08-05Fix counting of outgoing requestsAnders Svensson
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.
2014-07-21Add info item for diameter:service_info/2Anders Svensson
To extract only process info from connections info, which can be useful to reduce the amount of information returned. Choose 'info' for the item since process_info is more than one word: all others are one. Don't choose memory since it's too specific: might want to use it for more.
2014-07-21Add (process) info tuple to diameter:service_info/2Anders Svensson
To show process_info of interest. This is not yet documented since it may well change.
2014-05-28Merge branch 'anders/diameter/hardening/OTP-11721' into maintAnders Svensson
* anders/diameter/hardening/OTP-11721: Change answer_errors default from report to discard
2014-05-27Change answer_errors default from report to discardAnders Svensson
In the same vein as commit 00584303, to avoid logging traffic-related happenings. Not that the value in diameter.hrl is just documentation: the value is set explicitly when diameter:start_service/2 creates diameter_app records.
2014-05-27Merge branch 'anders/diameter/Failed-AVP/OTP-11936' into maintAnders Svensson
* anders/diameter/Failed-AVP/OTP-11936: Do best-effort decode of Failed-AVP Add a testcase that expects a decoded value in Failed-AVP
2014-05-27Merge branch 'anders/diameter/5014/OTP-11946' into maintAnders Svensson
* anders/diameter/5014/OTP-11946: Fix handling of AVP length errors (5014) in unknown AVPs Add testcases that send unknown AVPs with a bad AVP Length
2014-05-27Merge branch 'anders/diameter/hardening/OTP-11721' into maintAnders Svensson
* 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
2014-05-26Do best-effort decode of Failed-AVPAnders Svensson
Commit 4ce2d3a6 (diameter-1.4.2, OTP-11007) disabled the decode of values in Failed-AVP components since any error caused the decode of Failed-AVP itself to fail. This is less than useful since (1) we should be able to decode it given that we've sent it (modulo mangling on the way to the peer and back), and (2) it's not unheard of to examine Failed-AVP to see what the peer objected to. This commits adds a best-effort decode: decode if possible, otherwise not, using the same abuse of the process dictionary as commit bbdb027c.
2014-05-26Fix handling of AVP length errors (5014) in unknown AVPsAnders Svensson
Commit 4ce2d3a6 added the insertion of a single bit into binary AVP data to induce an encode error in the case of a header length that pointed past the available bytes: a 5014 = DIAMETER_INVALID_AVP_LENGTH error. Commit 838856b fixed this for stringish Diameter types, but both commits neglected the case in which the offending AVP isn't known to the dictionary in question. Unless the AVP was regarded as erroneous for other reasons (eg. an M-bit resulting in 5001) it would be happily be packed into an 'AVP' field. If it was regarded as an error, the record could be passed back to diameter_codec:pack_avp/1, and if the record contained header data then there was no clause to deal with the unpleasantry. Deal with it by having the dictionary module strip the extra bit and flag the AVP as 5014, and by having diameter_codec handle any extra bit coming from an dictionary compiled against an old diameter_gen. An old dictionary won't detect 5014 however, so dictionaries should be recompiled. Change most of the guards in diameter_codec from is_bitstring/1 to is_binary/1. What's being passed to the decode functions are binaries received other the network. The only case in which a non-binary bitstring is when we've placed an extra bit there ourselves. (Modulo someone doing something they shouldn't.)