This directory contains small examples of simple Diameter nodes. They don't do everything a real node should do obviously, but they're a starting point. Each example consists of an interface module with functions to start and stop a service and add transport, and a corresponding callback module for the Diameter application the service configures. A real node might support multiple Diameter applications, either with the same callback or sharing a common callback, maybe using extra arguments to distinguish between callbacks for the different applications. The interface functions are named start, stop, connect, and listen; the client example also has a call function that sends an example message. Service names should be atoms in these modules (since the default setting of Origin-Host assumes this), but doesn't need to be in general. Options are passed directly to diameter:start_service/2 and diameter:add_transport/2, with some additional convenience options for the latter; in particular, the atoms tcp and sctp to connect to or listen on default endpoints (127.0.01:3868), or tuples with protocol and another endpoint {eg. {tcp, {192,168,1,5}, 3869}. This convenience makes the simplest usage like this in an Erlang shell: diameter:start(). server:start(). server:listen(tcp). client:start(). client:connect(tcp). client:call(). Or put a relay between the client and server: diameter:start(). server:start(). server:listen(sctp). relay:start(). relay:connect(sctp). relay:listen(tcp). client:start(). client:connect(tcp). client:call(). Most services should probably set the following options, which have been added to solve various problems over the years, while the defaults have not been changed for backwards compatibility. {decode_format, map} Provide decoded messages in #diameter_packet.msg of a handle_request or handle_answer callback in the form [Name | Avps], where Name is the atom() name of the message in the (Diameter) application dictionary in question (eg. 'ACR') and Avps is a map of AVP values. This avoids compile-time dependencies on the generated records and their (generally) long-winded names. The hrl files generated from dictionaries are best avoided. {restrict_connections, false} Accept multiple connections with the same peer. By default, diameter will only accept a single connection with a given peer, which the Diameter RFC can be interpreted as requiring. In practice, wanting multiple connections to the same peer is common. {string_decode, false} Disable the decoding of string-ish Diameter types to Erlang strings, leaving them as binary(). Strings can be costly if decoded Diameter messages are passed between processes. {strict_mbit, false} Relax the interpretation of the M-bit so that an AVP setting this bit is not regarded as a 5001 error when the message grammar in question doesn't explicitly list the AVP. Without this, a Redirect-Host AVP received in a 3006 (DIAMETER_REDIRECT_INDICATION) answer-message from a redirect agent will be treated as error, and there have been other situations in which the default value has caused problems (or at least surprise). {call_mutates_state, false} (on each configured application) Avoid pick_peer and subsequent callbacks going through a single process, which can be a bottleneck. Better to use the tid() of an ets table as (immutable) state, for example. Other options that are particularly useful/necessary in some situations are: pool_size - Create a pool of accepting processes for a listening transport, to avoid refused connections when many peers connect simultaneously. Can also be used on a connecting transport to establish multiple connections with a single call to diameter:add_transport/2. sequence - Ensure unique End-to-End and Hop-by-Hop identifiers over a cluster of Erlang nodes. share_peers - Share peer connections across a cluster of use_shared_peers Erlang nodes. spawn_opt - Replace diameter's spawning of a new handler process for each request by something else: diameter_dist is an example.