aboutsummaryrefslogtreecommitdiffstats
path: root/lib/diameter/src/base/diameter_traffic.erl
AgeCommit message (Collapse)Author
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-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-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-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/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-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-08-31Fix handling of Proxy-Info in answers formulated by diameterAnders Svensson
RFC 6733 says this: 6.2. Diameter Answer Processing When a request is locally processed, the following procedures MUST be applied to create the associated answer, in addition to any additional procedures that MAY be discussed in the Diameter application defining the command: ... o Any Proxy-Info AVPs in the request MUST be added to the answer message, in the same order they were present in the request. This wasn't done when a handle_request callback returned a Result-Code in an 'answer-message' or protocol_error tuple, causing diameter itself to construct the answer message. This form of answer is just a convenience, since the callback can always return an answer that it constructs itself.
2017-08-31Fix extraction of Experimental-Result for counter keysAnders Svensson
The introduction of decode_format in commit 722fa415 (and then 55e65b26) meant the value was not necessarily the intended tuple.
2017-08-29Merge branch 'anders/diameter/upgrade/OTP-14552' into maintAnders Svensson
* anders/diameter/upgrade/OTP-14552: Fix compatibility of remote send
2017-08-23Fix compatibility of remote sendAnders Svensson
By changing the definition of the request record, commit f489c0d5 broke sending an outgoing request over a peer connection terminated on a remote node running an older version of diameter. The modified fields aren't even used on the remote node, so simply reintroduce one of the fields so that the size of the tuple is unchanged.
2017-08-10Add service_opt() traffic_countersAnders Svensson
To be able to disable the counting of messages for which application callbacks take place. Messages sent/handled by diameter itself are always counted.
2017-08-10Fix type specAnders Svensson
That dialyzer hasn't noticed is broken.
2017-08-10Fix type specAnders Svensson
That dialyzer hasn't noticed is broken.
2017-08-03Redo message decode as a single passAnders Svensson
Decode has previously been two passes: first chunk the message into a reversed list of toplevel diameter_avp records, then fold through the reversed list to build the full result. Various workarounds have made it a bit more convoluted than it should be however. Rework it completely, turning the previous 2-pass tail-recursive implementation into a 1-pass body recursive one. The relay decode still exists in diameter_codec, as a stripped down version of the full decode in diameter_gen.
2017-08-03Add service_opt() strict_aritiesAnders Svensson
To be able to disable the relatively expensive check that the number of AVPs received in a message or grouped AVP agrees with the dictionary in question. The may well be easier for the user in handle_request/answer callbacks, when digesting the received message, and in some cases may not be important. The check at encode can also be disabled, allowing messages that don't agree with the dictionary in question to be sent, which can be useful in test (at least).
2017-08-03Tweak map-valued decodeAnders Svensson
Use the same [MsgName | Avps] representation as for the list decode, but with Avps a map instead of a AVP name/values list. As a result, don't set the message/AVP name on an additional key in the map, which felt a bit odd. Messages are [MsgName :: atom() | map()], Grouped AVPs are just map(). Fix at least one problem in the traffic suite along the way: with decode_format false, the own decode in to_map/2 didn't know whether or not to decode strings, resulting on some failures.
2017-08-03Rename record_decode -> decode_formatAnders Svensson
{record_decode, map} is a bit too quirky.
2017-08-03Let messages and grouped AVPs be decoded to listsAnders Svensson
That is, decode to the same format that encode already accepts. Only a message has its name at the head of the list since AVPs are already name/value pairs.
2017-08-03Let messages and grouped AVPs be encoded/decoded from/to mapsAnders Svensson
With {record_decode, map}. The option name is arguably a bit misleading now, but not too objectionable given that the encode/decode in question has historically only been of records. One advantage of the map decode is that the map only contains values for those AVPs existing in the message or grouped AVP in question. The name of the message or grouped AVP is stored in with key ':name', the leading colon ensuring that the key isn't a diameter-name. Decoding to maps makes the hrl files generated from dictionary files largely irrelevant. There are value defines generated into these, but they're typically so long as to be unusable.
2017-08-03Add service_opt() record_decodeAnders Svensson
To control whether or not messages and grouped AVPs are decoded to records, in #diameter_packet.msg and #diameter_avp.value respectively. The decode became unnecessary for diameter's needs in parent commit, which decoupled it from the checking of AVP arities.
2017-06-14Merge branch 'anders/diameter/capx_vs_dpr/OTP-14338'Anders Svensson
* anders/diameter/capx_vs_dpr/OTP-14338: Let candidate peers be passed to diameter:call/4 Comment on RFC ambiguity regarding application identifiers Remove trailing whitespace
2017-06-13Let spawn_opt config replace erlang:spawn_opt/2 for request processesAnders Svensson
By accepting an MFA that is applied to the fun that is otherwise spawned for each incoming request, to allow handler processes to be reused. This is not yet documented and may change, but the motivation is to let spawn be replaced by process pool, from which the MFA selects. A list-valued spawn_opt is equivalent to {erlang, spawn_opt, [Opts]}.
2017-06-13Let candidate peers be passed to diameter:call/4Anders Svensson
To solve the problem of being able to send messages to a peer that hasn't advertised support for the application in question, as discussed in the parent commit. diameter:call/4 can be passed 'peer' options to identify candidates, and the only requirement is that an appropriate dictionary be configured for encode. Filters are applied as if candidates had been selected by advertised application.
2017-06-13Avoid sending answer terms between processes unnecessarilyAnders Svensson
As in commit fb14eac9, but for outgoing answers.
2017-06-13Refactor handling of incoming requestsAnders Svensson
To simplify the call chains and intermediate terms, that had become a little convoluted over time.
2017-06-13Add diameter_codec option ordered_encodeAnders Svensson
To allow list-valued messaged to be encoded in the specified order, instead of in the dictionary order by first converting the list to a record. This is not yet exposed in configuration.
2017-06-13Restore undocumented Failed-AVP setting convenienceAnders Svensson
The parent commit removed the convenience of setting something like the following in the errors field of the diameter_packet of an answer message. [#diameter_avp{} = A2, {5001, #diameter_avp{} = A1}] This results in Result-Code = 5001 and Failed-AVP = [A1,A2], but is currently undocumented. Probably useful, so restore it. Also accept {RC, [#diameter_avp{}]} at encode, which is probably more useful; eg. [{5001, [A || {5001, A} <- Errors]}] Anyone who wants full control can set errors = false and formulate Result-Code/Failed-AVP themselves. (As opposed to not setting a value explicitly, which results in setting from the decoded errors list. A bit quirky, but documented and historical.)
2017-06-13Fix/simplify setting of one Failed-AVPAnders Svensson
When setting the Result-Code/Failed-AVP of an outgoing answer from an errors list either returned from or not discarded by a handle_request callback, more than the AVP paired with the Result-Code in question could be set in Failed-AVP. RFC 6733: 7.5. Failed-AVP AVP The Failed-AVP AVP (AVP Code 279) is of type Grouped and provides debugging information in cases where a request is rejected or not fully processed due to erroneous information in a specific AVP. The value of the Result-Code AVP will provide information on the reason for the Failed-AVP AVP. A Diameter answer message SHOULD contain an instance of the Failed-AVP AVP that corresponds to the error indicated by the Result-Code AVP. For practical purposes, this Failed-AVP would typically refer to the first AVP processing error that a Diameter node encounters.
2017-06-13Avoid recreating recordsAnders Svensson
In this case the diameter_packet of an answer message for encode. The record itself could be avoided, but that requires a new interface in diameter_codec, probably for little gain.
2017-06-13Avoid recreating recordsAnders Svensson
In the theme of the previous two commits, creating the required diameter_header of diameter_packet record only once.
2017-06-13Avoid recreating recordsAnders Svensson
As in the parent commit, recreating the options record is relatively costly.
2017-06-13Avoid recreating recordsAnders Svensson
This old construction is approximately two to four times slower from best (no elements modified) to worst (all modified) case, with the new construction having constant speed.
2017-06-13Don't deconstruct {TPid, Caps} unnecessarilyAnders Svensson
The tuple is returned from and passed to callbacks, so retain the tuple instead of its elements.
2017-06-13Remove use of process dictionary in decodeAnders Svensson
By passing additional arguments through it.
2017-06-12Remove unnecessary value mappingAnders Svensson
Since value is ignored.
2017-06-12Remove upgrade from diameter_trafficAnders Svensson
2017-06-11Simplify acks to transport processesAnders Svensson
What's interesting when implementing some form of load regulation is when an incoming request has been answered or discarded. Acknowledge exactly this, not the identity of handler processes as previously. A transport process can request acks of nonforthcoming answers by sending {diameter, ack} to the parent peer_fsm, a handler processes identifies itself with a {handler, pid()} message, and the peer_fsm monitors on this to be able to send a notification to the transport if the handler dies before sending an answer.
2017-03-07Avoid sending large terms between nodes unnecessarilyAnders Svensson
When relaying outgoing requests through transport on a remote node, terms that were stripped when sending to the transport process weren't stripped when spawning a process on the remote node. Also, don't save the request to the process dictionary in a process that just relays an answer.
2017-03-07Don't use request table for answer routingAnders Svensson
The table has existed forever, to route incoming answers to a waiting request process: each outgoing request writes to the table, and each incoming answer reads. This has been seen to suffer from lock contention at high load however, so this commit moves the routing into the diameter_peer_fsm processes that are diameter's conduit to transport processes. The request table is still used for failover detection, but entries are only written when a watchdog state transitions leaves or enters state OKAY.
2017-02-24Fix/redo failover optimizationAnders Svensson
Commit 9a878743 addressed inefficiency at failover, but introduced inefficiency in the sending of outgoing requests in so doing: each outgoing request added an request table entry keyed on a transport pid, then looked for a specific element with this key, and then (later) removed the inserted element. Since the request table is a bag, this results in linear searches over a potentially long list of element keyed on the same pid. The higher the rate of outgoing calls, the more costly it becomes. Instead of writing entries to the request table, the peer_up/down calls to diameter_traffic that mirror transitions to and from the OKAY state in the RFC 3539 watchdog state machine now result in a process for request processes to monitor in order to detect failover.
2016-09-12Merge branch 'anders/diameter/19.1/OTP-13838' into maintAnders Svensson
* anders/diameter/19.1/OTP-13838: vsn -> 1.12.1 Update appup for 19.1 Fix xmllint errors in documentation Remove documentation overkill Don't run traffic tests in parallel when {string_decode, true} Remove copyright from generated dictionary modules Fix dictionary function typo Fix dictionary typo in relay example
2016-09-12Merge branch 'anders/diameter/failover/OTP-13412' into maintAnders Svensson
* anders/diameter/failover/OTP-13412: Make peer failover more efficient
2016-08-26Fix dictionary function typoAnders Svensson
It's '#get-'/2, not 'get-'/2. Only failed if the dictionary in question defined no Failed-AVP, which is rarely the case in practice. Thanks to Ferenc Holzhauser.
2016-05-09Merge branch 'anders/diameter/overload/OTP-13330'Anders Svensson
* anders/diameter/overload/OTP-13330: Suppress dialyzer warning Remove dead case clause Let throttling callback send a throttle message Acknowledge answers to notification pids when throttling Throttle properly with TLS Don't ask throttling callback to receive more unless needed Let a throttling callback answer a received message Let a throttling callback discard a received message Let throttling callback return a notification pid Make throttling callbacks on message reception Add diameter_tcp option throttle_cb
2016-03-16Make peer failover more efficientAnders Svensson
Failover caused the entire request table to be scanned in search of entries with the transport process in question. With many entries (possibly as a result of the leak fixed in commit 6c9cbd96), this can lead to the service process hanging in ets:select_trap/1, with memory growth when many request processes write concurrently. Now write entries keyed on the transport pid, so that finding request processes at failover is a lookup rather than a select scanning the entire table. There is no upgrade handling in that new code doesn't consider that old code didn't write entries on the transport pid. Thus, a request whose table entries were written in old code will timeout rather than failover in new code. That is, there is a small window for failover to be missed (since request processes are short-lived), but it requires that it take place during the upgrade. As a minor aside, don't ignore failovers when sending binaries (which isn't officially supported), let prepare_retransmit callbacks deal with modifying the binary as required.
2016-03-14Acknowledge answers to notification pids when throttlingAnders Svensson
By sending {diameter, {answer, pid()}} when an incoming answer is sent to the specified pid, instead of a discard message as previously. The latter now literally means that the message has been discarded.
2016-03-13Let throttling callback return a notification pidAnders Svensson
In addition to returning ok or {timeout, Tmo}, let a throttling callback for message reception return a pid(), which is then notified if the message in question is either discarded or results in a request process. Notification is by way of messages of the form {diameter, discard | {request, pid()}} where the pid is that of a request process resulting from the received message. This allows the notification process to keep track of the maximum number of request processes a peer connection can have given rise to.