aboutsummaryrefslogtreecommitdiffstats
path: root/lib/diameter/src/base
AgeCommit message (Collapse)Author
2019-04-14Add appup and code_changeAnders Svensson
For the parent commit as a diameter 2.2 patch.
2019-04-14Fix inadvertently broad monitorAnders Svensson
Commit d9d918b2 added a gen_server whose purpose is to keep track of visible nodes on which diameter_dist:attach/1 has been called to register a node as a handler of incoming Diameter requests when diameter_dist:route_session/2 is configured as spawn_opt MFA. The server contacts visible nodes at init in order to request information, but instead of monitoring visible to also be able to request information at nodeup, it monitored on all nodes, resulting in gen_server casts even to hidden nodes. Monitor only on visible nodes since a hidden node may not be able to deal with the new message.
2019-03-08Merge branch 'anders/diameter/distribution/OTP-15398' into maintAnders Svensson
* anders/diameter/distribution/OTP-15398: Add diameter_dist_SUITE to exercise diameter_dist:route_session/2 Add consistent hashing to diameter_dist:route_session/2 Add options to diameter_dist:route_session/2 node selection Add diameter_dist for ready spawn_opt callbacks Tweak/document request handler callback Document acknowledgements in transport interface Fix comment typo
2019-03-06Add consistent hashing to diameter_dist:route_session/2Anders Svensson
If the Session-Id optional value to node() mapping fails then hash Session-Id to a node by default, instead of selecting the local node as in the parent commit. The previous behaviour is configurable by setting default = local in an options map. Nodes make themselves part of the pool from which nodes are selected by calling diameter_dist:attach/1 with the list of service names they are willing to handle requests for, the local node being selected in the absence of any attached nodes. The original idea was to base the node pool on share_peers and/or use_shared_peers configuration, but that configuration determines where outgoing requests can be sent, while route_session/2 deals with incoming requests, so it's not obvious that conflating the two is a good thing. (Also because share_peers/use_shared_peers can be used in different ways; the former could have been skipped entirely.) The hashing effectively places nodes on a circle, a hashed Session-Id being mapped to the nearest predecessor node (clockwise). Nodes are rehashed with each Session-Id (with the id as salt) for a more even distribution, at the cost of performance, although how high the cost or how even the distribution has yet to be tested. Obviously, the larger the number of attached nodes, the higher the cost. Adding/removing an attached node only affects session ids that hash in the interval between the added/removed node and its successor (hence consistent hashing). Options are tweaked slightly compared to the parent commit, and it is now possible to restrict the optional value mapping to specific Diameter identities, to avoid mapping an id that was generated at the peer when the peer is also implemented with the diameter application. Note that diameter_dist is not yet an officially documented interface, so could change. Documentation is in the module itself.
2019-03-06Add options to diameter_dist:route_session/2 node selectionAnders Svensson
To be able to restrict how many AVPs will be examined (from the front of a message) when looking for Session-Id, and to decide what to do with if the AVP isn't found. Options are specified as a map of the following form. #{search => non_neg_integer(), default => discard | mfa(), dispatch => list() | mfa()} The search member says how many AVPs to examine at most, from the front of the message. If the optional value of a Session-Id is not the name of a connected node then the default member determines what to do with the request, handle it locally (the default), discard it, or invoke an MFA on the Session-Id | false (if none was found) and diameter_packet record to return a node() | false; if the latter then the request is discarded. If a node is identified then the dispatch MFA is invoked on the node and the request MFA (as three arguments), a list Opts being equivalent to the MFA {erlang, spawn_opt, [Opts]}, and the default being the empty list. Integer- or list-valued options are equivalent to the corresponding map with a single value. Limiting the search is to avoid searching messages containing many AVPs for a Session-Id that is known to occur near the header, since section 8.8 of RFC 6733 says this: When present, the Session-Id SHOULD appear immediately following the Diameter header (see Section 3). There's no guarantee, but in practice it may well be known that peers are respecting the RFC, and in that case limiting the search is a defense against searching messages from a malicious peer unnecessarily. The search is unlimited by default. A default is only used when a search fails to locate a Session-Id, and can be to discard the message, or have a node() or false be returned from an MFA applied to the diameter_packet in question. The local node is chosen by default.
2019-03-06Add diameter_dist for ready spawn_opt callbacksAnders Svensson
That is, of functions that can be configured as spawn_opt MFAs in transport configuration. This commits adds the spawn_local described in the parent commit, and a route_session that assumes that the local node initiates all sessions with Session-Id returned by diameter:session_id/1, and handles incoming requests on the node on which the id in question was returned, diameter:session_id/1 using node() as optional value in the Session-Id format.
2019-03-06Tweak/document request handler callbackAnders Svensson
The possibility of configuring an MFA as spawn_opt was added in commit fd285079, the callback being passed an arity-0 fun to be applied in an appropriate handler process. Replace the fun by a tuple to be passed to diameter_traffic:request/1, to avoid passing funs between nodes when handler processes are remote. A list-valued spawn_opt is now equivalent to the following configured as {spawn_opt, {Mod, spawn_local, [Opts]}}. spawn_local(ReqT, Opts) -> spawn_opt(diameter_traffic, request, [ReqT], Opts). ReqT is passed by diameter and contains information that the callback may want to decide where to handle the request in question (which wasn't accessible with a fun), but this information isn't exposed in a documented way. The intention is instead to add an own callback implementation to make use of the information. Note that application lookup now takes place in the watchdog process in both the list-valued (or no configuration) and mfa-valued cases. Whether this is good, bad, or (probably) inconsequential remains to be seen.
2019-03-06Fix comment typoAnders Svensson
2019-02-13Merge branch 'anders/diameter/nocatch/OTP-15569' into maintAnders Svensson
* anders/diameter/nocatch/OTP-15569: Update appup Fix nocatch on incoming answer with faulty Experimental-Result-Code
2019-02-08Fix nocatch on incoming answer with faulty Experimental-Result-CodeAnders Svensson
Failure to decode the Grouped AVP results in a throw from module diameter_gen, which is caught in the normal message decode, but wasn't when only the AVP is decoded from diameter_traffic (for error checking and counter increment). The result was no handle_answer/error callback, and an error return from diameter:call/4 when the detach option was not specified.
2018-07-18Fix function_clause when sending a request after an outgoing DPAAnders Svensson
After DPR, the intention is that outgoing answers are sent and outgoing requests are discarded. This was the case when the DPR was outgoing, but if it was incoming then a subsequent outgoing request resulted in a function_clause, bringing down the diameter_peer_fsm gen_server associated with the transport connection in question. With diameter_tcp/sctp, the failure can result in the connection being reset before the peer closes it in response to DPA, but is otherwise harmless since DPR means that the connection is already on its way down.
2018-06-18Update copyright yearHenrik Nord
2018-06-07Don't use deprecated erlang:get_stacktrace/0Anders Svensson
2018-03-06Merge branch 'anders/diameter/20.3/OTP-14946' into maintAnders Svensson
* anders/diameter/20.3/OTP-14946: vsn -> 2.1.4 Update appup for 20.3 Update service_info examples in doc Fix inaccurate comment
2018-03-05Merge branch 'anders/diameter/terminate/ERIERL-124' into maintAnders Svensson
* anders/diameter/terminate/ERIERL-124: Fix handling of SUSPECT connections at service termination
2018-03-05Fix inaccurate commentAnders Svensson
A peer_fsm process can be started long before a connection is established in the listening case. The time reported in a 'peer' tuple in service_info is of connection establishment.
2018-02-01Fix handling of SUSPECT connections at service terminationAnders Svensson
A peer connection in watchdog state SUSPECT is represented by a peer table entry in diameter_service, but not by a request table entry in diameter_peer, so diameter_service:terminate/2 could result in failures like this: exception error: no match of right hand side value [] in function diameter_traffic:peer_down/1 (base/diameter_traffic.erl, line 141) in call from lists:foldl/3 (lists.erl, line 1263) in call from ets:do_foldl/4 (ets.erl, line 611) in call from ets:foldl/3 (ets.erl, line 600) in call from diameter_service:terminate/2 (base/diameter_service.erl, line 557) in call from gen_server:try_terminate/3 (gen_server.erl, line 648) in call from gen_server:terminate/10 (gen_server.erl, line 833) in call from gen_server:handle_msg/6 (gen_server.erl, line 679)
2017-12-15Fix diameter_reg:subscribe/2 remove notificationAnders Svensson
Commit fae8ca0c broke notification by removing table elements before matching for them, causing diameter_tcp/sctp listening processes to live on after diameter:remove_transport/2. Commit 58091992 added diameter_reg:subscribe/2, and commit 5ca5fb71 started using it for listener exit.
2017-10-14Fix error handling when decoding an AVP with an alternate dictionaryAnders Svensson
The options map wasn't updated after the AVP was identified, with the resulting consequences for M-bit interpretation.
2017-10-13Remove unused function argumentsAnders Svensson
Which may have been used in the past, but aren't now.
2017-10-13Fix faulty recursionAnders Svensson
The wrong variable was passed into the decode recursion, causing the options map to be contaminated by strict_mbit and failed_avp modifications that should only apply to component AVPs in the Grouped case. Decode errors and M-bits could be ignored as a result.
2017-10-05Update appup and code_change for ERIERL-83Anders Svensson
2017-10-05Fix missing monitor in diameter_regAnders Svensson
Commit fae8ca0c inadvertently removed the monitor at add/1 and add_new/1. As a result, process death did not remove associations, causing table diameter_reg to leak entries and stop/start of a service to fail. Add a testcase to detect the problem, which existing testcases miss.
2017-09-18Merge branch 'anders/diameter/performance/OTP-14521' into maintAnders Svensson
* anders/diameter/performance/OTP-14521: Fix append of Route-Record AVPs
2017-09-15Fix append of Route-Record AVPsAnders Svensson
Commit b3d9e0c0 did away with the reordering of diameter_avp lists, so prepending the AVP to the list means prepending it in the message, which is not what the RFC requires. Appending to a list isn't ideal, but right now there's no better way.
2017-09-13Merge branch 'anders/diameter/grouped_decode/OTP-14607' into maintAnders Svensson
* anders/diameter/grouped_decode/OTP-14607: Fix diameter_packet.avps decode of Grouped AVP errors in Failed-AVP
2017-09-13Merge branch 'anders/diameter/DOIC/OTP-14588' into maintAnders Svensson
* anders/diameter/DOIC/OTP-14588: Fix avp_dictionaries decode with {decode_format, none}
2017-09-11Fix diameter_packet.avps decode of Grouped AVP errors in Failed-AVPAnders Svensson
The decode didn't respect the format as a list of diameter_avp records, so information about faulty component AVPs was lost.
2017-09-11Fix avp_dictionaries decode with {decode_format, none}Anders Svensson
Decode is only a no-op when the AVP is Grouped, and then only on the Grouped AVP itself, not its components.
2017-09-09Merge branch 'anders/diameter/config_consistency/OTP-14555' into maintAnders Svensson
* anders/diameter/config_consistency/OTP-14555: Fix type spec Fix strict_arities blunder
2017-09-09Merge branch 'anders/diameter/performance/OTP-14521' into maintAnders Svensson
* anders/diameter/performance/OTP-14521: Simplify implementation in diameter_reg (take 2)
2017-09-08Fix type specAnders Svensson
Map key was not retained when the spec was added in commit 66bb5251.
2017-09-08Fix strict_arities blunderAnders Svensson
The watchdog process retained the configuration, causing DWR/DWA encode to fail on a string-valued Origin-Host/Realm if the encode arity was relaxed. Bungled in commit 5f3becad.
2017-09-07Simplify implementation in diameter_reg (take 2)Anders Svensson
Simplify the simplification. The order of sending is changed, but the order isn't significant.
2017-09-07Merge branch 'anders/diameter/performance/OTP-14521' into maintAnders Svensson
* anders/diameter/performance/OTP-14521: Simplify implementation in diameter_reg Fix type spec Fix minor monitor blunder in diameter_reg
2017-09-06Simplify implementation in diameter_regAnders Svensson
Use maps instead of dict for traceability more than performance.
2017-09-06Fix type specAnders Svensson
That dialyzer hasn't noticed is wrong.
2017-09-05Merge branch 'anders/diameter/DOIC/OTP-14588' into maintAnders Svensson
* anders/diameter/DOIC/OTP-14588: Exercise avp_dictionaries in traffic suite Let generic AVPs be encoded/decoded in alternate dictionaries Rename field in codec map: dictionary -> app_dictionary Add RFC 7683 Diameter Overload Indicator Conveyance text and dictionary Fix decode undef Fix dictionary compilation error message
2017-09-05Fix minor monitor blunder in diameter_regAnders Svensson
Commit 58091992 discarded a new monitor reference, so didn't avoid multiple monitors as was the intention. The blunder was harmless since all but the first DOWN message resulted in notifications.
2017-09-04Let generic AVPs be encoded/decoded in alternate dictionariesAnders Svensson
To support specifications like RFC 7683 DOIC, that only define AVPs, not applications. AVPs that aren't known to the application dictionary in question could previously not be decoded. Configuring alternate dictionaries with the new transport/service option avp_dictionaries changes this, so that AVPs like DOIC's Grouped OC-OLR can presented in their fully decoded glory. Encode is also extended, allowing things like the following to be encoded in an outgoing message: 'AVP' => [{'OC-OLR', #{'OC-Sequence-Number' => 1, 'OC-Report-Type' => 0, 'OC-Reduction-Percentage' => [25]}}] A diameter_gen_doic_rfc7683 dictionary is installed, but avp_dictionaries isn't specific to DOIC. This commit also solves the problem demonstrated a few commits back, that application AVPs aren't decoded in answers setting the E-bit. Test coverage will come in a subsequent commit.
2017-09-04Rename field in codec map: dictionary -> app_dictionaryAnders Svensson
To better reflect what the field is: field 'module' is the dictionary module that's calling diameter_gen to decode a list of AVP, while field 'app_dictionary' is the dictionary module defining the message being decoded.
2017-09-04Fix decode undefAnders Svensson
Function avp/5 isn't exported from dictionary modules. Not necessarily intentional, but don't just export it since that requires recompilation of all dictionary modules, since the function is in diameter_gen.hrl. Not having to recompile was the main motivation for moving most of the included code to module diameter_gen in commit 205521d3. This reveals a weakness in the decode of answers setting the E-bit: any AVP that isn't defined by the common application won't be decoded; the diameter_avp records that these are packed into (in the 'AVP' field of a message record, or equivalent) will have value = undefined. This is nothing new (same in OTP 19), but the values should be decoded. Fix it (and the lack of test coverage) in a subsequent commit that will add avp_dictionaries config.
2017-09-03Merge branch 'anders/diameter/decode_format/OTP-14511' into maintAnders Svensson
* anders/diameter/decode_format/OTP-14511: Map less in traffic suite Fix decode_format doc oversights Rename decode_format false to none Tweak {decode_format, false} semantics Fix dialyzer spec
2017-09-03Merge branch 'anders/diameter/config_consistency/OTP-14555' into maintAnders Svensson
* anders/diameter/config_consistency/OTP-14555: Fix strict_arities blunder Fix minor error-handling blunder
2017-09-03Merge branch 'anders/diameter/Proxy-Info/OTP-9869' into maintAnders Svensson
* anders/diameter/Proxy-Info/OTP-9869: Fix handling of Proxy-Info in answers formulated by diameter
2017-09-03Merge branch 'anders/diameter/Experimental-Result/OTP-14511' into maintAnders Svensson
* anders/diameter/Experimental-Result/OTP-14511: Fix extraction of Experimental-Result for counter keys
2017-09-03Merge branch 'anders/diameter/performance/OTP-14521' into maintAnders Svensson
* anders/diameter/performance/OTP-14521: Rename variable Fix decode of too many generic AVPs Enumerate AVPs in diameter_avp.index (again)
2017-09-01Rename decode_format false to noneAnders Svensson
Which reads better and makes it easier to distinguish this false from others.
2017-09-01Tweak {decode_format, false} semanticsAnders Svensson
Represent the decoded message by its atom-valued name in diameter_packet.msg, which makes trace much more readable. A diameter_avp.value is untouched (ie. undefined): the AVP name is already in the name field.
2017-09-01Fix dialyzer specAnders Svensson
Which dialyzer hasn't noticed.