aboutsummaryrefslogtreecommitdiffstats
path: root/lib/diameter/src/base
AgeCommit message (Collapse)Author
2016-03-07Fix dialyzer warningsAnders Svensson
Whether making record declarations unreadable to compensate for dialyzer's ignorance of match specs is worth it is truly debatable.
2016-03-07Merge branch 'anders/diameter/retransmission/OTP-13342' into maintAnders Svensson
* anders/diameter/retransmission/OTP-13342: Fix handling of shared peer connections in watchdog state SUSPECT Remove unnecessary parentheses Remove dead export
2016-02-19Fix handling of shared peer connections in watchdog state SUSPECTAnders Svensson
A peer connection shared from a remote node was regarded as being available for peer selection (aka up) as long as its peer_fsm process was alive; that is, for the lifetime of the peer connection. In particular, it didn't take note of transitions into watchdog state SUSPECT, when the connection remains. As a result, retransmissions could select the same peer connection whose watchdog transition caused the retransmission. A service process now broadcasts a peer_down event just as it does a peer_up event. The fault predates the table rearrangements of commit 8fd4e5f4.
2016-02-19Remove unnecessary parenthesesAnders Svensson
Not needed as of commit 6c9cbd96.
2016-02-19Remove dead exportAnders Svensson
The export of diameter_traffic:failover/1 happened with the creation of the module in commit e49e7acc, but was never needed since the calling code was also moved into diameter_traffic.
2016-02-09Make peer handling more efficientAnders Svensson
Each service process maintains a dictionary of peers, mapping an application alias to a {pid(), #diameter_caps{}} list of connected peers. These lists are potentially large, peers were appended to the end of the list for no particular reason, and these long lists were constructed/deconstructed when filtering them for pick_peer callbacks. Many simultaneous outgoing request could then slow the VM to a crawl, with many scheduled processes mired in list manipulation. The pseudo-dicts are now replaced by plain ets tables. The reason for them was (once upon a time) to have an interface interchangeable with a plain dict for debugging purposes, but strict swapablity hasn't been the case for some time now, and in practice a swap has never taken place. Additional tables mapping Origin-Host/Realm have also been introduced, to minimize the size of the peers lists when peers are filtered on host/realm. For example, a filter like {any, [{all, [realm, host]}, realm]} is probably a very common case: preferring a Destination-Realm/Host match before falling back on Destination-Realm alone. This is now more efficiently (but not equivalently) expressed as {first, [{all, [realm, host]}, realm]} to stop the search when the best match is made, and extracts peers from host/realm tables instead of searching through the list of all peers supporting the application in question. The code to try and start with a lookup isn't exhaustive, and the 'any' filter is still as inefficient as previously.
2016-02-09Remove unnecessary erlang:monitor/2 qualificationAnders Svensson
See commit 862af31d.
2015-12-22Merge branch 'maint-17' into maintAnders Svensson
2015-12-21Make peer handling more efficientAnders Svensson
Each service process maintains a dictionary of peers, mapping an application alias to a {pid(), #diameter_caps{}} list of connected peers. These lists are potentially large, peers were appended to the end of the list for no particular reason, and these long lists were constructed/deconstructed when filtering them for pick_peer callbacks. Many simultaneous outgoing request could then slow the VM to a crawl, with many scheduled processes mired in list manipulation. The pseudo-dicts are now replaced by plain ets tables. The reason for them was (once upon a time) to have an interface interchangeable with a plain dict for debugging purposes, but strict swapablity hasn't been the case for some time now, and in practice a swap has never taken place. Additional tables mapping Origin-Host/Realm have also been introduced, to minimize the size of the peers lists when peers are filtered on host/realm. For example, a filter like {any, [{all, [realm, host]}, realm]} is probably a very common case: preferring a Destination-Realm/Host match before falling back on Destination-Realm alone. This is now more efficiently (but not equivalently) expressed as {first, [{all, [realm, host]}, realm]} to stop the search when the best match is made, and extracts peers from host/realm tables instead of searching through the list of all peers supporting the application in question. The code to try and start with a lookup isn't exhaustive, and the 'any' filter is still as inefficient as previously.
2015-12-21Remove unnecessary erlang:monitor/2 qualificationAnders Svensson
See commit 862af31d.
2015-12-20Merge branch 'anders/diameter/17.5.6.7/OTP-13211' into maint-17Erlang/OTP
* anders/diameter/17.5.6.7/OTP-13211: vsn -> 1.9.2.2 Update/fix appup for 17.5.6.7 Be resilient to diameter_service state upgrades
2015-12-20Merge branch 'anders/diameter/request_leak/OTP-13137' into maint-17Erlang/OTP
* anders/diameter/request_leak/OTP-13137: Fix request table leak at retransmission Fix request table leak at exit signal
2015-12-20Be resilient to diameter_service state upgradesAnders Svensson
By not failing in code that looks up state: pick_peer and service_info.
2015-12-09Merge branch 'anders/diameter/request_leak/OTP-13137' into maintAnders Svensson
* anders/diameter/request_leak/OTP-13137: Fix request table leak at retransmission Fix request table leak at exit signal
2015-12-09Fix request table leak at retransmissionAnders Svensson
In the case of retranmission, a prepare_retransmit callback could modify End-to-End and/or Hop-by-Hop identifiers so that the resulting diameter_request entry was not removed, since the removal was of entries with the identifiers of the original request. The chances someone doing this in practice are probably minimal.
2015-12-09Fix request table leak at exit signalAnders Svensson
The storing of request records in the ets table diameter_request was wrapped in a try/after so that the latter would unconditionally remove written entries. The problem is that it didn't deal with the process exiting as a result of an exit signal, since this doesn't raise in an exception. Since the process in question applies callbacks to user code, we can potentially be linked to other process and exit as a result. Trapping exits changes the current behaviour of the process, so spawn a monitoring process that cleans up upon reception of 'DOWN'.
2015-09-14Merge branch 'anders/diameter/watchdog/OTP-12969' into maintAnders Svensson
* anders/diameter/watchdog/OTP-12969: Fix watchdog function_clause
2015-09-14Merge branch 'anders/diameter/M-bit/OTP-12947' into maintAnders Svensson
* anders/diameter/M-bit/OTP-12947: Add service_opt() strict_mbit
2015-09-07Fix watchdog function_clauseAnders Svensson
Commit 4f365c07 introduced the error on set_watchdog/2, as a consequence of timeout/1 returning stop, which only happens with accepting transports with {restrict_connections, false}.
2015-09-07Fix watchdog function_clauseAnders Svensson
Commit 4f365c07 introduced the error on set_watchdog/2, as a consequence of timeout/1 returning stop, which only happens with accepting transports with {restrict_connections, false}.
2015-08-25Add service_opt() strict_mbitAnders Svensson
There are differing opinions on whether or not reception of an arbitrary AVP setting the M-bit is an error. 1.3.4 of RFC 6733 says this about how an existing Diameter application may be modified: o The M-bit allows the sender to indicate to the receiver whether or not understanding the semantics of an AVP and its content is mandatory. If the M-bit is set by the sender and the receiver does not understand the AVP or the values carried within that AVP, then a failure is generated (see Section 7). It is the decision of the protocol designer when to develop a new Diameter application rather than extending Diameter in other ways. However, a new Diameter application MUST be created when one or more of the following criteria are met: M-bit Setting An AVP with the M-bit in the MUST column of the AVP flag table is added to an existing Command/Application. An AVP with the M-bit in the MAY column of the AVP flag table is added to an existing Command/Application. The point here is presumably interoperability: that the command grammar should specify explicitly what mandatory AVPs much be understood, and that anything more is an error. On the other hand, 3.2 says thus about command grammars: avp-name = avp-spec / "AVP" ; The string "AVP" stands for *any* arbitrary AVP ; Name, not otherwise listed in that Command Code ; definition. The inclusion of this string ; is recommended for all CCFs to allow for ; extensibility. This renders 1.3.4 pointless unless "*any* AVP" is qualified by "not setting the M-bit", since the sender can effectively violate 1.3.4 without this necessitating an error at the receiver. If clients add arbitrary AVPs setting the M-bit then request handling becomes more implementation-dependent. The current interpretation in diameter is strict: if a command grammar doesn't explicitly allow an AVP setting the M-bit then reception of such an AVP is regarded as an error. The strict_mbit option now allows this behaviour to be changed, false turning all responsibility for the M-bit over to the user.
2015-08-13Merge branch 'maint-17' into maintAnders Svensson
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.
2015-08-13Merge branch 'anders/diameter/17/time/OTP-12926' into maint-17Erlang/OTP
* anders/diameter/17/time/OTP-12926: Simplify time manipulation Remove use of monotonic time in pre-18 code Remove unnecessary redefinition of erlang:max/2
2015-08-13Merge branch 'anders/diameter/grouped_errors/OTP-12930' into maint-17Erlang/OTP
* anders/diameter/grouped_errors/OTP-12930: Fix decode of Grouped AVPs containing errors Simplify logic Simplify logic
2015-08-13Merge branch 'anders/diameter/transport/OTP-12929' into maint-17Erlang/OTP
* anders/diameter/transport/OTP-12929: Fix start order of alternate transports Log discarded answers
2015-08-13Merge branch 'anders/diameter/lcnt/OTP-12912' into maint-17Erlang/OTP
* anders/diameter/lcnt/OTP-12912: Make ets diameter_stats a set Remove unnecessary sorting in stats suite Set ets {write_concurrency, true} on diameter_stats Don't start watchdog timers unnecessarily Remove unnecessary erlang:monitor/2 qualification Add missing watchdog suite clause
2015-08-13Merge branch 'anders/diameter/caseless/OTP-12902' into maint-17Erlang/OTP
* anders/diameter/caseless/OTP-12902: Match allowable peer addresses case insensitively Replace calls to module inet_parse to equivalents in inet
2015-08-13Merge branch 'anders/diameter/grouped_decode/OTP-12879' into maint-17Erlang/OTP
* anders/diameter/grouped_decode/OTP-12879: Fix relay encode of decoded diameter_avp lists
2015-08-07Make ets diameter_stats a setAnders Svensson
There's no need for it to be ordered, and the ordering has been seen to have an unexpectedly negative impact on performance in some cases. Order when retrieving statistics instead, so as not to change the presentation in diameter:service_info/2.
2015-08-05Simplify time manipulationAnders Svensson
By doing away with more wrapping that the parent commit started to remove.
2015-08-05Remove use of monotonic time in pre-18 codeAnders Svensson
This has been seen to be a bottleneck at high load: each undef results in a loop out to the code server. Originally implemented as suggested in the erts user's guide, in commits e6d19a18 and d4386254.
2015-08-05Fix start order of alternate transportsAnders Svensson
A transport configured with diameter:add_transport/2 can be passed multiple transport_module/transport_config tuples in order to specify alternate configuration, modules being attempted in order until one succeeds. This is primarily for the connecting case, to allow a transport to be configured to first attempt connection over SCTP, and then TCP in case SCTP fails, with configuration like that documented: {transport_module, diameter_sctp}, {transport_config, [...], 5000}, {transport_module, diameter_tcp}, {transport_config, [...]} If the options are the same in both cases, another possibility would be configuration like this, which attaches the same transport_config to both modules: {transport_module, diameter_sctp}, {transport_module, diameter_tcp}, {transport_config, [...], 5000}, However, in this case the start order was reversed relative to the documented order: first tcp, then sctp. This commit restores the intended order.
2015-08-05Log discarded answersAnders Svensson
To diameter_lib:log/4, which was last motivated in commit 39acfdb0.
2015-08-04Fix relay encode of decoded diameter_avp listsAnders Svensson
Commit c74b593a fixed the problem that a decoded deep diameter_avp list couldn't be encoded, but did so in the wrong way: there's no need to reencode component AVPs since the Grouped AVP itself already contains the encoded binary. The blunder caused diameter_codec:pack_avp/1 to fail if the first element of the AVP list to be encoded was itself a list. Thanks to Andrzej TrawiƄski for reporting the problem.
2015-08-04Match allowable peer addresses case insensitivelyAnders Svensson
Both diameter_tcp and diameter_sctp can be configured with one or more IP addresses from which connections should be accepted (an 'accept' tuple), specified either as a tuple-valued address or as a regular expression. In the latter case, peer addresses are mapped to string using inet:ntoa/1 and the result matched against the regexp. Since (ipv6) addresses are case insensitive, this should also be the case with the match, but was not.
2015-08-04Replace calls to module inet_parse to equivalents in inetAnders Svensson
Commits b563c796 (R16B) and 0fad6449 (R16B02) added parse_address/1 and ntoa/1 to module inet, providing documented alternatives to address/1 and ntoa/1 in the undocumented (save comments in inet(3)) inet_parse.
2015-08-04Truncate potentially large terms passed to diameter_lib:log/4Anders Svensson
Last visited in commit 00584303.
2015-08-04Set ets {write_concurrency, true} on diameter_statsAnders Svensson
lcnt:inspect/1 recently showed this: lock id #tries collisions [%] time [us] ----- --- ------- --------------- ---------- db_tab diameter_stats 932920 92.9326 330332554
2015-07-19Don't start watchdog timers unnecessarilyAnders Svensson
In particular, restart the timer with each incoming Diameter message, only when the previous timer has expired. Doing so has been seen to result in high lock contention at load, as in the example below: (diameter@test)9> lcnt:conflicts([{print, [name, tries, ratio, time]}]). lock #tries collisions [%] time [us] ----- ------- --------------- ---------- bif_timers 7844528 99.4729 1394434884 db_tab 17240988 1.7947 6286664 timeofday 7358692 5.6729 1399624 proc_link 4814938 2.2736 482985 drv_ev_state 2324012 0.5951 98920 run_queue 21768213 0.2091 63516 pollset 1190174 1.7170 42499 pix_lock 1956 2.5562 39770 make_ref 4697067 0.3669 20211 proc_msgq 9475944 0.0295 5200 timer_wheel 5325966 0.0568 2654 proc_main 10005332 2.8190 1079 pollset_rm_list 59768 1.7752 480
2015-07-19Remove unnecessary erlang:monitor/2 qualificationAnders Svensson
The function has been auto-exported since R14B.
2015-06-22Merge branch 'bruce/change-license'Bruce Yinhe
OTP-12845 * bruce/change-license: fix errors caused by changed line numbers Change license text to APLv2
2015-06-22Merge branch 'anders/diameter/18/OTP-12588'Anders Svensson
* anders/diameter/18/OTP-12588: vsn -> 1.10 Remove dead upgrade-related code Update appup for 18 Fix release note typo Fix comment typo
2015-06-22Merge branch 'anders/diameter/sctp/OTP-12768'Anders Svensson
* anders/diameter/sctp/OTP-12768: Fix connection timeouts in test transports Fix start order of alternate transports Log discarded answers Ensure accepting processes are first in, first out Remove upgrade-related code Be less parallel in traffic suite Increase send/receive buffers for testsuite SCTP listeners Decrease unnecessarily long testsuite timetraps Simplify accepting transport start Simplify peeloff signaling Simplify socket close at terminate Don't monitor listener after peeloff Don't receive initial messages out of order Remove assumption that SCTP association ids will be unique
2015-06-22Merge branch 'anders/diameter/grouped_errors/OTP-12721'Anders Svensson
* anders/diameter/grouped_errors/OTP-12721: Fix decode of Grouped AVPs containing errors Simplify logic Simplify logic
2015-06-21Fix start order of alternate transportsAnders Svensson
A transport configured with diameter:add_transport/2 can be passed multiple transport_module/transport_config tuples in order to specify alternate configuration, modules being attempted in order until one succeeds. This is primarily for the connecting case, to allow a transport to be configured to first attempt connection over SCTP, and then TCP in case SCTP fails, with configuration like that documented: {transport_module, diameter_sctp}, {transport_config, [...], 5000}, {transport_module, diameter_tcp}, {transport_config, [...]} If the options are the same in both cases, another possibility would be configuration like this, which attaches the same transport_config to both modules: {transport_module, diameter_sctp}, {transport_module, diameter_tcp}, {transport_config, [...], 5000}, However, in this case the start order was reversed relative to the documented order: first tcp, then sctp. This commit restores the intended order. OTP-12851
2015-06-20Remove dead upgrade-related codeAnders Svensson
Not needed with the parent commit's restart_application.
2015-06-20Log discarded answersAnders Svensson
To diameter_lib:log/4, which was last motivated in commit 39acfdb0.
2015-06-18Change license text to APLv2Bruce Yinhe
2015-06-18Fix decode of Grouped AVPs containing errorsAnders Svensson
RFC 6733 says this of Failed-AVP in 7.5: In the case where the offending AVP is embedded within a Grouped AVP, the Failed-AVP MAY contain the grouped AVP, which in turn contains the single offending AVP. The same method MAY be employed if the grouped AVP itself is embedded in yet another grouped AVP and so on. In this case, the Failed-AVP MAY contain the grouped AVP hierarchy up to the single offending AVP. This enables the recipient to detect the location of the offending AVP when embedded in a group. It says this of DIAMETER_INVALID_AVP_LENGTH in 7.1.5: The request contained an AVP with an invalid length. A Diameter message indicating this error MUST include the offending AVPs within a Failed-AVP AVP. In cases where the erroneous AVP length value exceeds the message length or is less than the minimum AVP header length, it is sufficient to include the offending AVP header and a zero filled payload of the minimum required length for the payloads data type. If the AVP is a Grouped AVP, the Grouped AVP header with an empty payload would be sufficient to indicate the offending AVP. In the case where the offending AVP header cannot be fully decoded when the AVP length is less than the minimum AVP header length, it is sufficient to include an offending AVP header that is formulated by padding the incomplete AVP header with zero up to the minimum AVP header length. The AVPs placed in the errors field of a diameter_packet record are intended to be appropriate for inclusion in a Failed-AVP, but neither of the above paragraphs has been followed in the Grouped case: the entire faulty AVP (non-faulty components and all) has been included. This made it impossible to identify the actual faulty AVP in all but simple case. This commit adapts the decode to the RFC, and implements the suggested single faulty AVP, nested in as many Grouped containers as required. The best-effort decode of Failed-AVP in answer messages, initially implemented in commit 0f9cdbaf, is also applied.
2015-05-30Merge branch 'maint'Anders Svensson