aboutsummaryrefslogtreecommitdiffstats
path: root/lib/diameter/src
AgeCommit message (Collapse)Author
2017-08-10Fix type specAnders Svensson
That dialyzer hasn't noticed is broken.
2017-08-10Split AVPs at decodeAnders Svensson
Despite what the Efficiency Guide says about match being more efficient, split_binary appears to be slightly faster. (Although this one extraction is a drop in the bucket.) Binary optimizations aren't an issue during decode.
2017-08-10Avoid unnecessary copying of binaries in diameter_tcpAnders Svensson
Since messages are accumulated by appending binaries as of three commits back, the accumulated binary is prone to being copied, as discussed in the Efficiency Guide. Matching the Message Length header as bytes are being accumulated is one cause of this, so work around it by splitting the binary and extracting the length without a match. This doesn't feel like something that should be necessary: that matching a binary would cause an append to copy isn't obvious. The first attempt at simplifying the accumulation was simply to append an incoming binary to the current fragment, match against <<_, Len:24, _/binary>> to extract the length, and then test if there are enough bytes for a message. This lead to horrible performance (response times for 2 MB messages approximately 100 times worse than previously), and it wasn't at all obvious that the reason was the accumulated binary being copied with each append as a result of the match. Using split_binary avoids the match context that forces the copying.
2017-08-10Don't update diameter_tcp state unnecessarilyAnders Svensson
Not with each setopts to re-activate the socket.
2017-08-10Don't update diameter_tcp state unnecessarilyAnders Svensson
Only reset the fragment after all messages have been extracted.
2017-08-10Simplify extraction of incoming Diameter messages in diameter_tcpAnders Svensson
Appending to a binary is efficient, so just append message fragments Only match out the length once per message since doing so for every packet from TCP causes the binary to be copied.
2017-08-10Restructure/simplify message reception in diameter_peer_fsmAnders Svensson
Create less garbage.
2017-08-10Fix type specAnders Svensson
That dialyzer hasn't noticed is broken.
2017-08-03Optimize sub-binariesAnders Svensson
Also inline incr/8 and associated functions that were needed for the compiler to accept the optimization, since this does make for a measuable improvement.
2017-08-03Optimize sub-binariesAnders Svensson
With ERL_COMPILER_OPTIONS=bin_opt_info, before: base/diameter_codec.erl:508: Warning: NOT OPTIMIZED: the binary matching instruction that follows in the same function have problems that prevent delayed sub binary optimization (probably indicated by INFO warnings) And after: base/diameter_codec.erl:508: Warning: OPTIMIZED: creation of sub binary delayed This has a surprisingly large impact on the performance of diameter_codec:collect_avps/2: about 15% faster in one testcase on a RAR with 7 AVPs.
2017-08-03Count AVPs in #diameter_avp.indexAnders Svensson
The index field in record diameter_avp was previously used to enumerate AVPs so that the list could be returned in some cases, since diameter_codec:collect_avps/2 (now /1) reversed the order. That's no longer the case as of the grandparent commit, so use the field to enumerate instances of the same AVP instead, and only when arities are being checked, to save having to look them up in the map when checking for 5009 errors, or counting AVPs at all in diameter_codec:collect_avps/1.
2017-08-03Don't extract options unnecessarily at encodeAnders Svensson
Extract strict_arities once and pass it through as an argument.
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-03Be forgiving of non-list values at encodeAnders Svensson
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-03Fix detection of 5009 errorsAnders Svensson
As noted in the parent commit, the wrong AVPs were reported, being counted from the back of the message instead of the front. Both 5005 and 5009 errors are now detected after the message is decoded.
2017-08-03Don't count AVPs unnecessarily at encodeAnders Svensson
Stop counting when there can be no arity errors.
2017-08-03Don't take length of AVP lists unnecessarily at encodeAnders Svensson
Count as AVPs are encoded instead.
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-03Add decode_format record_from_mapAnders Svensson
Undocumented, for transforming a map decode to record. The record decode becomes more expensive the larger the number of AVPs in the message definition in question, since the record is recreated each time an AVP value is set in it. The map decode can potentially do better.
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-08-03Count AVP arities during decodeAnders Svensson
Instead of after, during the check that AVPs have sufficient arity. This makes the arity checks independent of the record decode, which will allow the latter to be made optional.
2017-08-03Fix obsolete diameter_gen.hrl commentsAnders Svensson
Most of the contents were moved to module diameter_gen in commit 205521d3.
2017-06-14Update copyright yearHans Nilsson
2017-06-14Merge branch 'anders/diameter/20.0/OTP-14398'Anders Svensson
* anders/diameter/20.0/OTP-14398: vsn -> 2.0 Update appup for 20.0
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-14Merge branch 'anders/diameter/performance/OTP-14343'Anders Svensson
* anders/diameter/performance/OTP-14343: (50 commits) Let spawn_opt config replace erlang:spawn_opt/2 for request processes Move (most of) diameter_gen.hrl to diameter_gen.erl Change signature associated with dictionary @custom_type/@codecs Avoid sending answer terms between processes unnecessarily Refactor handling of incoming requests Restore diameter_codec:decode/2, update diameter_codec(3) Add diameter_codec option ordered_encode Restore undocumented Failed-AVP setting convenience Fix/simplify setting of one Failed-AVP Avoid recreating records Avoid recreating records Avoid recreating records Avoid recreating records Adapt test suites to modified encode/decode Simplify diameter_caps construction Don't compute URI defaults unnecessarily Don't deconstruct {TPid, Caps} unnecessarily Remove use of process dictionary in decode Remove minor diameter_config bloat Fix maximum AVP arity check ...
2017-06-14Merge branch 'anders/diameter/transport/ERL-332'Anders Svensson
* anders/diameter/transport/ERL-332: (35 commits) Capitulate on SCTP vs sparc-sun-solaris2.10 Remove obsolete traffic testcase Fix dialyzer warnings Remove client/server string decode from traffic suite Add diameter_sctp option packet Add diameter_sctp send/recv callbacks Let diameter_tcp send/recv callbacks deal in diameter_packet Randomly select traffic testcases Exercise diameter_tcp message callbacks in traffic suite Exercise diameter_{tcp,sctp} sender in traffic suite Remove upgrade from diameter_traffic Add diameter_tcp send/recv callbacks Make diameter_{tcp,sctp} sender configurable Remove upgrade from diameter_sctp; tweak diameter_tcp to match Fix incomprehensible dialyzer warning Simplify acks to transport processes Strip throttling callbacks from diameter_tcp Deal with (another) SCTP association id quirk on Solaris Use binary:copy/2 when generating largish data in test suites Deal with SCTP association id quirk on Solaris ...
2017-06-13Update appup for 20.0Anders Svensson
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-13Comment on RFC ambiguity regarding application identifiersAnders Svensson
It is tempting to regard remote support for the common application as implicit, but that leads to the problems noted, and a node could never then expect non-intersecting application support to result in 5010. It probably can't anyway given the different ways the RFC's intent can be interpreted, but it's not unreasonable that a node should be able to advertise a single Diameter application and get 5010 if the peer doesn't support it. The problem we have currently is that peer selection is based on the support advertised by the peer. The application id of an outgoing request is used to lookup peers that have advertised support, so if the peer hasn't advertised support for Diameter common messages then the user won't be able to send DPR and more: diameter:call/4 will just return {error, no_connection}. This commit doesn't solve the problem.
2017-06-13Move (most of) diameter_gen.hrl to diameter_gen.erlAnders Svensson
To remove the requirement that dictionary modules be recompiled whenever the encode/decode implementation changes. The included diameter_gen.hrl now only contains trivial functions that call info diameter_gen.erl.
2017-06-13Change signature associated with dictionary @custom_type/@codecsAnders Svensson
To pass the options map through the encode. This is not backwards compatible, and dictionaries supporting @custom_types or @codecs will need to be updated.
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-13Restore diameter_codec:decode/2, update diameter_codec(3)Anders Svensson
The documentation has been out of date since the string_decode option was added in commit 1590920c. The optionless decode/2 was removed in the commit that removed the use of the process dictionary in decode.
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-13Simplify diameter_caps constructionAnders Svensson
Replace old macro-based implementation with something more readable.
2017-06-13Don't compute URI defaults unnecessarilyAnders Svensson
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.