aboutsummaryrefslogtreecommitdiffstats
path: root/lib/diameter/src/transport/diameter_tcp.erl
AgeCommit message (Collapse)Author
2017-08-29Merge branch 'anders/diameter/config_consistency/OTP-14555' into maintAnders Svensson
* anders/diameter/config_consistency/OTP-14555: Let strict_mbit and incoming_maxlen be configured per transport Let a service configure default transport options Rename type evaluable -> eval
2017-08-29Merge branch 'anders/diameter/loopback_any/OTP-14544' into maintAnders Svensson
* anders/diameter/loopback_any/OTP-14544: Use loopback/any config in examples suite Handle loopback/any as local address in diameter_tcp/sctp
2017-08-24Rename type evaluable -> evalAnders Svensson
Export the old type as a synonym for backwards compatability. The name evaluable is a bit too awkward.
2017-08-19Handle loopback/any as local address in diameter_tcp/sctpAnders Svensson
The support is implied by documentation, but wasn't handled in code. Be consistent in retrieving the address from the sock rather than the configuration, and in accepting both ip and ifaddr for a local address.
2017-08-18Merge branch 'anders/diameter/performance/OTP-14521' into maintAnders Svensson
* anders/diameter/performance/OTP-14521: Work around unexpected common_test behaviour Randomly skip groups in traffic suite Randomly disable traffic counters in traffic suite Add service_opt() traffic_counters Fix type spec Split AVPs at decode Avoid unnecessary copying of binaries in diameter_tcp Don't update diameter_tcp state unnecessarily Don't update diameter_tcp state unnecessarily Simplify extraction of incoming Diameter messages in diameter_tcp Restructure/simplify message reception in diameter_peer_fsm Sleep randomly at the start of (parallel) traffic testcases Fix ct return value in traffic suite Fix type spec Optimize sub-binaries Optimize sub-binaries Count AVPs in #diameter_avp.index Don't extract options unnecessarily at encode Redo message decode as a single pass
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-06-21Add missing setopts after deferred diameter_{tcp,sctp} actionsAnders Svensson
Since the actions can request that a previously passive socket be made active. Missed in commits 636a7199 and 373cd07c.
2017-06-12Let diameter_tcp send/recv callbacks deal in diameter_packetAnders Svensson
To let a recv callback for an incoming request set transport_data and have it returned in a send callback.
2017-06-12Add diameter_tcp send/recv callbacksAnders Svensson
From the receiver process, that can return binaries to send/receive and stop the transport process from reading on the socket. This is still undocumented, and may change.
2017-06-11Make diameter_{tcp,sctp} sender configurableAnders Svensson
With sends still from the receiving process by default, since changing the default behaviour may well have negative effects. A separate sender probably implies a greater need for some form of load regulation for one, since a blocking send would no longer imply that incoming messages are no longer recevied. Dealing with this could result in the same deadlock that the sending process intends to avoid, but the user should be in control over how/when incoming traffic is regulated.
2017-06-11Remove upgrade from diameter_sctp; tweak diameter_tcp to matchAnders Svensson
Added in commit 2afd1fe5. Only rename variables in diameter_tcp, no functional change.
2017-06-11Fix incomprehensible dialyzer warningAnders Svensson
This: diameter_tcp.erl:241: Record construction #transport{parent::'false',ssl::boolean() | maybe_improper_list(),frag::<<>>,tref::'false',flush::'false',pending::0,reset::{1 | 4,0 | 2},throttled::boolean(),q::{0,queue:queue(_)},monitor::'undefined' | pid()} violates the declared type of field parent::pid() The problem isn't #transport.pid at all, it's #monitor.pid, and the only relation is that the pid that's assigned to the latter is also (later) assigned to the former. There is no record construction that assigns false to #transport.parent. Introduced in commit 33a535e4.
2017-06-11Strip throttling callbacks from diameter_tcpAnders Svensson
Commits starting at 472a080c added a throttle_cb option to diameter_tcp to let a callback apply backpressure when it decides that additional requests should not be read. It didn't provide a hook for knowing that an answer was sent however, which is needed when sends no longer take place in the receiver process, and is more complicated than it should be. Strip it all away, in preparation for a simpler incarnation.
2017-06-11Add missing dialyzer typesAnders Svensson
Which dialyzer itself has never complained about.
2017-06-11Don't send from receiving transport processesAnders Svensson
Both diameter_tcp and diameter_sctp are susceptible to deadlock since a peer that blocks send also prevents additional messages from being received. Send from a process that's paired with the transport process to avoid this. Use the existing monitor process in the TCP case, add one in the SCTP case. This has been the reason for many sporadic testcase failures, mostly in diameter_traffic_SUITE.
2017-06-11Fix gen_tcp close of ssl socketAnders Svensson
Should be ssl:close/1.
2017-06-11Remove clauses supporting old codeAnders Svensson
Since smooth upgrade won't be supported in this branch.
2016-08-26Close listening sockets at service deathAnders Svensson
Commit 5ca5fb71 ensured that they were closed immediately at transport removal, but in so doing broke their closing at stop service completely, by removing the timer that caused sockets to be closed even belatedly. Monitor on the service process to make it happen. This could still be improved, since stop_service listening ports aren't closed until after the service process has died. They could be closed earlier in the case of stop_service.
2016-05-30Close listening sockets at transport removalAnders Svensson
The transport interface documented in diameter_transport(3) is used to start/stop accepting/connecting transport processes: they're started with a function call, and told to die with their parent process. In the accepting case, both diameter_tcp and diameter_sctp start a listening process when the first accepting transport is started. However, there's no way for a listening process to find out that that it should stop listening when transport configuration is removed. Both diameter_tcp and diameter_sctp have used a timer to terminate the listening process after all existing accepting processes have died as a consequence of transport removal. The problem with this is that nothing stops a new client from connecting before this, and also that no new transport can succeed in opening the same listening port (eg. reconfiguration) until the old listener dies. This commit solves the problem by adding diameter_reg:subscribe/2, to allow callers to subscribe to messages about added/removed associations. A call to diameter:add_transport/2 results in a new child process that registers a term that a listening process subscribes to. Transport removal results in the death of the child, and the resulting notification to the listener causes the latter to close its socket and terminate. This is still an internal interface, but the subscription mechanism should probably be made external (eg. a diameter:subscribe/1 that can be used to subscribe to specified messages), so that transport modules other than diameter's own can make use of it. There is no support for soft upgrade.
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-05-04Suppress dialyzer warningAnders Svensson
This one: diameter_tcp.erl:928: (call) The call diameter_tcp:throttle({'timeout',_},#transport{socket::port() | {'sslsocket',_,_},parent::pid(),module::atom(),frag::binary() | {non_neg_integer(),non_neg_integer(),binary(),[binary()]},ssl::boolean() | [any()],timeout::'infinity' | non_neg_integer(),tref::'false' | reference(),flush::boolean(),throttle_cb::'false' | fun() | maybe_improper_list(fun() | maybe_improper_list(any(),[any()]) | {atom(),atom(),[any()]},[any()]) | {atom(),atom(),[any()]},throttled::'true' | binary()}) will never return since it differs in the 1st argument from the success typing arguments: ('discard' | 'ok' | binary() | pid() | {'discard' | 'ok' | binary() | pid(),'false' | fun() | [fun() | [any()] | {atom(),atom(),[any()]}] | {atom(),atom(),[any()]}},#transport{socket::port() | {'sslsocket',_,_},parent::pid(),module::atom(),frag::binary() | {non_neg_integer(),non_neg_integer(),binary(),[binary()]},ssl::boolean() | [any()],timeout::'infinity' | non_neg_integer(),tref::'false' | reference(),flush::boolean(),throttle_cb::'false' | fun() | [fun() | [any()] | {atom(),atom(),[any()]}] | {atom(),atom(),[any()]},throttled::binary()}) It's true that the clause doesn't return, because of the throw, and that's the intention.
2016-05-03Remove dead case clauseAnders Svensson
Orphaned in commit 9298872b.
2016-03-18Let throttling callback send a throttle messageAnders Svensson
That is, don't assume that it's only diameter_tcp doing so: allow it to be received when not throttling. This lets a callback module trigger a new throttling callback itself, but it's not clear if this will be useful in practice.
2016-03-13Throttle properly with TLSAnders Svensson
In particular, let a callback decide when to receive the initial message.
2016-03-13Don't ask throttling callback to receive more unless neededAnders Svensson
TCP packets can contain more than one message, so only ask to receive another message if it hasn't already been received.
2016-03-13Let a throttling callback answer a received messageAnders Svensson
As discussed in the parent commit. This is easier said than done in practice, but there's no harm in allowing it.
2016-03-13Let a throttling callback discard a received messageAnders Svensson
This can be used as a simple form of overload protection, discarding the message before it's passed into diameter to become one more request process in a flood. Replying with 3004 would be more appropriate when the request has been directed at a specific server (the RFC's requirement) however, and possibly it should be possible for a callback to do this as well.
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.
2016-03-13Make throttling callbacks on message receptionAnders Svensson
The callback is now applied to the atom 'false' when asking if another message should be received on the socket, and to a received binary message after reception. Throttling on received messages makes it possible to distinguish between requests and answers. There is no callback on outgoing messages since these don't have to go through the transport process, even if they currently do.
2016-03-13Add diameter_tcp option throttle_cbAnders Svensson
To let a callback module decide whether or to receive another message from the peer, so that backpressure can be applied when it's inappropriate. This is to let a callback protect against reading more than can be processed, which is otherwise possible since diameter_tcp otherwise always asks for more. A callback is made after each message, and can answer to continue reading or to ask again after a timeout. It's each message instead of each packet partly for simplicity, but also since this should be sufficiently fine-grained. Per packet would require some interaction with the fragment timer that flushes partial messages that haven't been completely received.
2015-10-09Update DiameterHans Bolinder
Record field types have been modified due to commit 8ce35b2: "Take out automatic insertion of 'undefined' from typed record fields".
2015-06-18Change license text to APLv2Bruce Yinhe
2015-02-20Adapt tcp/sctp transport modules for pool_size > 1Anders Svensson
In particular, that starts for the same transport reference can now be concurrent. Looking up a listener process and starting a new one if not found did handle this (more than one process could find no listener), and diameter_sctp assumed there could only be one transport process waiting for an association.
2013-06-10Let diameter_{tcp,sctp} be configured with permissible remote addressesAnders Svensson
Option 'accept' allows remote addresses to be configured as tuples or regular expressions. The remote addresses for any incoming (aka accepted) connection/association are matched against the configured values, any non-matching address causing the connection/association to be aborted.
2013-06-10Fix diameter_{tcp,sctp} specAnders Svensson
The third argument to start/3 was just wrong.
2013-06-10Remove trailing whitespaceAnders Svensson
2013-04-11Make explicit local address to diameter_tcp:start/3 optionalAnders Svensson
Use the default address address (as selected by gen_tcp) if none is configured, passing it in the new 'connected' message introduced by the previous commit. The corresponding update to diameter_sctp has to wait until problems with inet:sockname/1 are resolved: the function currently only returns one address, and sometimes {0,0,0,0}. See OTP-11018.
2013-02-10Only start a fragment timer when there's something to flushAnders Svensson
2013-02-10Simplify and document diameter_tcp fragment timerAnders Svensson
Don't start a new timer with each incoming message. Instead, start a timer at timeout and flush after two successive timeouts with no message reception.
2013-02-10Remove upgrade code not needed after application restartAnders Svensson
Which will be the case in R16B.
2013-02-08Remove upgrade code not needed after application restartAnders Svensson
Which will be the case with R16B in this case.
2013-01-23Spec fixAnders Svensson
2012-08-29Merge branch 'anders/diameter/R15B02_release' into maintAnders Svensson
* anders/diameter/R15B02_release: Dialyzer spec fix Learn to keep time in diameter_gen_sctp_SUITE Update command line test for changed ct:run_test/1 return value OTP-10243
2012-08-29Dialyzer spec fixAnders Svensson
2012-08-27Maintain service_info callback data in process dictionaryAnders Svensson
To be used by diameter_service in constructing service_info.
2011-10-10Register tcp listener before transport start returnAnders Svensson
2011-10-10Add port resolution interface to transport modulesAnders Svensson