phone

    • chevron_right

      Ignite Realtime Blog: Smack 4.5.0-alpha2 released

      news.movim.eu / PlanetJabber · Saturday, 9 December, 2023 - 17:46

    We are happy to announce the release of the second alpha release of Smack’s upcoming 4.5 version.

    This version fixes a nasty bug in Smack’s reactor, includes support for XMPP over WebSocket connections and much more. Even though Smack has a good test coverage, due its comprehensive unit test suite and integration test framework, we kindly ask you to test pre-releases and report feedback.

    As always, this Smack release is available via Maven Central .

    1 post - 1 participant

    Read full topic

    • chevron_right

      Erlang Solutions: Reimplementing Technical Debt with State Machines

      news.movim.eu / PlanetJabber · Wednesday, 6 December, 2023 - 10:29 · 16 minutes

    In the ever-evolving landscape of software development, mastering the art of managing complexity is a skill every developer and manager alike aspires to attain. One powerful tool that often remains in the shadows, yet holds the key to simplifying intricate systems, is the humble state machine. Let’s get started.

    Models

    State machines can be seen as models that represent system behaviour. Much like a flowchart on steroids, these models represent an easy way to visualise complex computation flows through a system.

    A typical case study for state machines is the modelling implementation of internet protocols. Be it TLS, SSH, HTTP or XMPP, these protocols define an abstract machine that reacts to client input by transforming its own state, or, if the input is invalid, dying.

    A case study

    Let’s see the case for –a simplified thereof– XMPP protocol. This messaging protocol is implemented on top of a TCP stream, and it uses XML elements as its payload format. The protocol, on the server side, goes as follows:

    1. The machine is in the “waiting for a stream-start” state, it hasn’t received any input yet.
    2. When the client sends such stream-start, a payload looking like the following:

    <stream:stream to='localhost' version='1.0' xml:lang='en' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>

    Then the machine forwards certain payloads to the client –a stream-start and a stream-features, its details are omitted in this document for simplicity– and transitions to “waiting for features before authentication”.

    1. When the client sends an authentication request, a payload looking like the following:

    <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>AGFsaWNFAG1hdHlncnlzYQ==</auth>

    Then the machine, if no request-response mechanism is required for authentication, answers to the client and transitions to a new “waiting for stream-start”, but this time “after authentication”.

    1. When the client again starts the stream, this time authenticated, with a payload like the following:

    <stream:stream to='localhost' version='1.0' xml:lang='en' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>

    Then the machine again answers the respective payloads, and transitions to a new “waiting for features after authentication”.

    1. And finally, when the client sends

    <iq type='set' id='1c037e23fab169b92edb4b123fba1da6'>

    <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>

    <resource>res1</resource>

    </bind>

    </iq>

    Then in transitions to “session established”.

    1. From this point, other machines can find it and send it new payloads, called “stanzas”, which are XML elements whose names are one of “message”, “iq”, or “presence”. We will omit the details of these for the sake of simplicity again.

    Because often one picture is worth a thousand words, see the diagram below:

    GhYeFukbpkkBRqqI_uX7wUX-bdr7mQA6xjJ55VWCrsU07DbMXwu1XYpNxYV6BYPsd6PgyjaGzmpIogKwV2ONZxC6qEqtxkvScSwnmpNBKSXuTmPmz7ndZMEyqxMyEmFKC8tr3sRgYPS5XUFmK5P5un2C40vTNOMzvLL4IaAud2CS0uQHGo28mx39zzYxHw

    Implementing the case

    Textbook examples of state machines, and indeed the old OTP implementation of such behaviour, gen_fsm, always give state machines whose states can be defined by a single name, not taking into account that such a name can be “the name of” a data structure instead. In Erlang in particular, gen_fsm imposed the name of the state to be an atom, just so that it can be mapped to a function name and be callable. But this is an unfortunate oversight of complexity management, where the state of a machine depends on a set of variables that, if not in the name, need to be stored elsewhere, usually the machine’s data, breaking the abstraction.

    Observe in the example above, the case for waiting for stream-start and features: they both exist within unauthenticated and authenticated realms. A naive implementation, where the function name is the state, the first parameter the client’s input, and the second parameter the machine’s data, would say that:

    wait_for_stream(stream_start, Data#data{auth = false}) ->
    	{wait_for_feature, Data}.
    
    wait_for_feature(authenticate, Data#data{auth = false}) ->
    	{wait_for_stream, Data#data{auth = true}}.
    
    wait_for_stream(stream_start, Data#data{auth = true}) ->
    	{wait_for_feature, Data}.
    
    wait_for_feature(session, Data#data{auth = true}) ->
    	{session, Data}.

    In each case, we will take different actions, like building different answers for the client, so we cannot coalesce seemingly similar states into less functions.

    But what if we want to implement retries on authentication?

    We need to add a new field to the data record, as follows:

    wait_for_stream(stream_start, Data#data{auth = false}) ->
    	{wait_for_feature, Data#data{retry = 3}}.
    
    wait_for_feature(authenticate, Data#data{auth = false}) ->
    	{wait_for_stream, Data#data{auth = true}};
    wait_for_feature(_, Data#data{auth = false, retry = 0}) ->
    stop;
    wait_for_feature(_, Data#data{auth = false, retry = N}) ->
    	{wait_for_feature, Data#data{auth = true, retry = N - 1}}.

    The problem here is twofold:

    1. When the machine is authenticated, this field is not valid anymore, yet it will be kept in the data record for the whole life of the machine, wasting memory and garbage collection time.
    2. It breaks the finite state machine abstraction –too early–, as it uses an unbounded memory field with random access lookups to decide how to compute the next transition, effectively behaving like a full Turing Machine — note that this power is one we will need nevertheless, but we will introduce it for a completely different purpose.

    This can get unwieldy when we introduce more features that depend on specific states. For example, when authentication requires roundtrips and the final result depends on all the accumulated input of such roundtrips, we would also accumulate them on the data record, and pattern-match which input is next, or introduce more function names.

    Or if authentication requires a request-response roundtrip to a separate machine, if we want to make such requests asynchronous because we want to process more authentication input while the server processes the first payload, we would also need to handle more states and remember the accumulated one. Again, storing these requests on the data record keeps more data permanent that is relevant only to this state, and uses more memory outside of the state definition. Fixing this antipattern lets us reduce the data record from having 62 fields to being composed of only 10.

    Before we go any further, let’s talk a bit about automatas.

    Automata theory

    In computer sciences, and more particularly in automata theory, we have at our disposal a set of theoretical constructs that allow us to model certain problems of computation, and even more ambitiously, define what a computer can do altogether. Namedly, there are three automatas ordered by computing power: finite state machines, pushdown automatas, and Turing machines. They define a very specific algorithm schema, and they define a state of “termination”. With the given algorithm schema and their definition of termination, they are distinguished by the input they are able to accept while terminating.

    Conceptually, a Turing Machine is a machine capable of computing everything we know computers can do: really, Turing Machines and our modern computers are theoretically one and the same thing, modulo equivalence.

    Let’s get more mathematical. Let’s give some definitions:

    1. Alphabet: a set denoted as Σ of input symbols, for example Σ = {0,1}, or Σ = [ASCII]
    2. A string over Σ: a concatenation of symbols of the alphabet Σ
    3. The Power of an Alphabet: Σ*, the set of all possible strings over Σ, including the empty set (an empty string).

    An automaton is said to recognise a string over if it “terminates” when consuming the string as input. On this view, automata generate formal languages, that is, a specific subset of Σ* with certain properties. Let’s see the typical automata:

    1. A Finite State Machine is a finite set of states Q (hence the name of the concept), an alphabet Σ and a function 𝛿 of a state and an input symbol that outputs a new state (and can have side-effects)
    2. A Pushdown Automata is a finite set of states Q, an alphabet Σ, a stack Γ of symbols of Σ, and a function 𝛿 of a state, an input symbol, and the stack, that outputs a new state, and modifies the stack by either popping the last symbol, pushing a new symbol, or both (effectively swapping the last symbol).
    3. A Turing Machine is a finite set of states Q, an alphabet Σ, an infinite tape Γ of cells containing symbols of Σ, and a function 𝛿 of a state, an input symbol, and the current tape cell, that outputs a new state, a new symbol to write in the current cell (which might be the same as before), and a direction, either left or right, to move the head of the tape.

    Conceptually, Finite State Machines can “keep track of” one thing, while Pushdown Automata can “keep track of” up to two things. For example, there is a state machine that can recognise all strings that have an even number of zeroes, but there is no state machine that can recognise all strings that have an equal number of ones and zeroes. However,this can be done by a pushdown automaton. But, neither state machines nor pushdown automata can generate the language for all strings that have an equal number of a’s, b’s, and c’s: this, a Turing Machine can do.

    How to relate these definitions to our protocols, when the input has been defined as an alphabet? In all protocols worth working on, however many inputs there are, they are finite set which can be enumerated. When we define an input element as, for example, <stream:start to=[SomeHost]/> , the list of all possible hosts in the world is a finite list, and we can isomorphically map these hosts to integers, and define our state machines as consuming integers. Likewise for all other input schemas. So, in order to save the space of defining all possible inputs and all possible states of our machines, we will work with schemas , that is, rules to construct states and input. The abstraction is isomorphic.

    Complex states

    We know that state machine behaviours, both the old gen_fsm and the new gen_statem, really are Turing Machines: they both keep a data record that can hold unbounded memory, hence acting as the Turing Machine tape. The OTP documentation for the gen_statem behaviour even says so explicitly:

    Like most gen_ behaviours, gen_statem keeps a server Data besides the state. Because of this, and as there is no restriction on the number of states (assuming that there is enough virtual machine memory) or on the number of distinct input events, a state machine implemented with this behaviour is in fact Turing complete. But it feels mostly like an Event-Driven Mealy machine .

    But we can still model a state machine schema with accuracy. ‘gen_statem’, on initialisation, admits a callback mode called ‘handle_event_function’. We won’t go into the details, but they are well explained in the available official documentation .

    By choosing the callback mode, we can use data structures as states. Note again that, theoretically, a state machine whose states are defined by complex data structures are isomorphic to giving unique names to every possible combination of such data structures internals: however large of a set, such a set is still finite.

    Now, let’s implement the previous protocol in an equivalent manner, but with no data record whatsoever, with retries and asynchronous authentication included:

    handle_event(_, {stream_start, Host},
                 [{wait_for_stream, not_auth}], _) ->
        StartCreds = get_configured_auth_for_host(Host),
        {next_state, [{wait_for_feature, not_auth}, {creds, StartCreds}, {retry, 3}]};
    
    handle_event(_, {authenticate, Creds},
                 [{wait_for_feature, not_auth}, {creds, StartCreds}, {retries, -1}], _) ->
    	stop;
    handle_event(_, {authenticate, Creds},
                 [{wait_for_feature, not_auth}, {creds, StartCreds}, {retries, N}], _) ->
        Req = auth_server:authenticate(StartCreds, Creds),
        {next_state, [{wait_for_feature, not_auth}, {req, Req}, {creds, Creds}, {retries, N-1}]};
    handle_event(_, {authenticated, Req},
                 [{wait_for_feature, not_auth}, {req, Req}, {creds, Creds} | _], _) ->
        {next_state, [{wait_for_stream, auth}, {jid, get_jid(Creds)}]};
    handle_event(_, Other,
                 [{wait_for_feature, not_auth} | _], _) ->
        {keep_state, [postpone]};
    
    handle_event(_, {stream_start, Host}, [{wait_for_stream, auth}, {jid, JID}], _) ->
        {next_state, [{wait_for_feature, auth}, {jid, JID}]};
    
    handle_event(_, {session, Resource}, [{wait_for_feature, auth}, {jid, JID}], _) ->
        FullJID = jid:replace_resource(JID, Resource),
        session_manager:put(self(), FullJID),
        {next_state, [{session, FullJID}]};

    And from this point on, we have a session with a known Jabber IDentifier (JID) registered in the session manager, that can send and receive messages. Note how the code pattern-matches between the given input and the state, and the state is a proplist ordered by every element being a substate of the previous.

    Now the machine is ready to send and receive messages, so we can add the following code:

    handle_event(_, {send_message_to, Message, To},
                 [{session, FullJID}], _) ->
        ToPid = session_manager:get(To),
        ToPid ! {receive_message_from, Message, FullJID,
        keep_state;
    handle_event(_, {receive_message_from, Message, From},
                 [{session, FullJID}], #data{socket = Socket}) ->
        tcp_socket:send(Socket, Message),
        keep_state;

    Only in these two function clauses, state machines interact with each other. There’s only one element that would be needed to be stored on the data record: the Socket. This element is valid for the entire life of the state-machine, and while we could include it on the state definition for every state, for once we might as well keep it globally on the data record for all of them, as it is globally valid.

    Please read the code carefully, as you’ll find it is self-explanatory.

    Staged processing of events

    A protocol like XMPP, is defined entirely in the Application Layer of the OSI Model , but as an implementation detail, we need to deal with the TCP (and potentially TLS) packets and transform them into the XML data-structures that XMPP will use as payloads. This can be implemented as a separate gen_server that owns the socket, receives the TCP packets, decrypts them, decodes the XML binaries, and sends the final XML data structure to the state-machine for processing. In fact, this is how this protocol was originally implemented, but for completely different reasons.

    In much older versions of OTP, SSL was implemented in pure Erlang code, where crypto operations (basically heavy number-crunching), was notoriously slow in Erlang. Furthermore, XML parsing was also in pure Erlang and using linked-lists as the underlying implementation of the strings. Both these operations were terribly slow and prone to produce enormous amounts of garbage, so it was implemented in a separate process. Not for the purity of the state machine abstractions, but simply to unblock the original state machine from doing other protocol related processing tasks.

    But this means a certain duplicity. Every client now has two Erlang processes that send messages to each other, effectively incurring a lot of copying in the messaging. Now OTP implements crypto operations by binding to native libcrypto code, and XML parsing is done using exml , our own fastest XML parser available in the BEAM world. So the cost of packet preprocessing is now lower than the message copying, and therefore, it can be implemented in a single process.

    Enter internal events:

    handle_event(info, {tls, Socket, Payload}, _, Data#{socket = Socket}) ->
    	XmlElements = exml:parse(tls:decrypt(Socket, Payload)),
    	StreamEvents = [{next_event, internal, El} || El <- XmlElements],
    	{keep_state, StreamEvents};

    Using this mechanism, all info messages from the socket will be preprocessed in a single function head, and all the previous handlers simply need to match on events of type internal and of contents an XML data structure.

    A pure abstraction

    We have prototyped a state machine implementing the full XMPP Core protocol (RFC6120) , without violating the abstraction of the state machine. At no point do we have a full Turing-complete machine, or even a pushdown automaton. We have a machine with a finite set of states and a finite set of input strings, albeit large as they’re both defined schematically, and a function, `handle_event/4`, that takes a new input and the current state and calculates side effects and the next state.

    However, for convenience we might break the abstraction in sensible ways. For example, in XMPP, you might want to enable different configurations for different hosts, and as the host is given in the very first event, you might as well store in the data record the host and the configuration type expected for this connection – this is what we do in MongooseIM’ s implementation of the XMPP server.

    Breaking purity

    But there’s one point of breaking in the XMPP case, which is in the name of the protocol. “ X” stands for extensible , that is, any number of extensions can be defined and enabled, that can significantly change the behaviour of the machine by introducing new states, or responding to new events. This means that the function 𝛿 that decides the next step and the side-effects, does not depend only on the current state and the current input, but also on the enabled extensions and the data of those extensions.

    Only at this point we need to break the finite state machine abstraction: the data record will keep an unbounded map of extensions and their data records, and 𝛿 will need to take this map to decide the next step and decide not only the next state and the side-effects, but also what to write on the map: that is, here, our State Machine does finally convert into a fully-fledged Turing Machine.

    With great power…

    Restraining your protocol to a Finite State Machine has certain advantages:

    • Memory consumption: the main difference, simplifying, between a Turing Machine and an FSM, is that the Turing Machine has infinite memory at its disposal, which means that when you have way too many Turing Machines roaming around in your system, it might get hard to reason about the amount of memory they all consume and how it aggregates. In contrast, it’s easier to reason about upper bounds for the memory the FSMs will need.
    • Determinism: FSMs exhibit deterministic behaviour, meaning that the transition from one state to another is uniquely determined by the input. This determinism can be advantageous in scenarios where predictability and reliability are crucial. Turing machines instead can exhibit a complexity that may not be needed for certain applications.
    • Halting: we have all heard of the Halting Problem, right? Turns out, proving that a Finite State Machine halts is always possible.
    • Testing: as the number of states and transitions of an FSM are finite, testing all the code-paths of such a machine is indeed a finite task. There are indeed State Machine learning algorithms that verify implementations (see LearnLib ) and property-based testing has a good chance to reach all edge-cases.

    When all we wanted was to implement a communication protocol, as varied as XMPP or TLS, where what we implement is a relationship of input, states, and output, a Finite State Machine is the right tool for the job. Using hierarchical states can model certain states better than using a simplified version of the states and global memory to decide the transitions (i.e., implement 𝛿) and will result in a purer and more testable implementation.

    Further examples:

    The post Reimplementing Technical Debt with State Machines appeared first on Erlang Solutions .

    • chevron_right

      Erlang Solutions: Advent of Code 2023

      news.movim.eu / PlanetJabber · Friday, 1 December, 2023 - 12:26 · 3 minutes

    Hello! I’m Piotr from Erlang Solutions Poland and I have the pleasure of saving Christmas this year with the power of Erlang for you!

    This is the second time we participate in the amazing event called the Advent of Code . Last year’s edition was solved by my colleague Aleksander and as far as I know – many of you enjoyed following his efforts. I hope you’ll like my tale of helping Santa too!

    I’m going to publish my solutions in my GitHub repository . They will be accompanied by a commentary, added to this page on a daily basis. I will add solutions for each day in an individual folder, with my input file downloaded from the AoC website.

    I’m also going to include a bit of microbenchmarking in every solution, with and without JIT. Firstly, to measure the overall performance of the code and secondly to see how much the efficiency improves thanks to JIT. I’m going to measure the computation time only with `timer:tc/3` call, as I consider time needed to compile a module and load the input file irrelevant. By “load” I mean: read it and split it into lines. Any further processing of individual lines is considered a computation. I will provide min, max and arithmetic average of 100 runs.

    I’ll be implementing solutions as EScripts, so running them is a bit more straightforward. And frankly – I think they are underrated and sometimes I prefer them over writing BASH scripts. I’ll always include `-mode(compile).` directive to avoid the interpretation performance penalty. For those who are not aware of this capability, I’ll also run Day 1 without this option to show you how the timings change.

    I’m going to run every piece of the code on Linux Mint 21.2 VirtualBox machine with 4 cores and 8GB of memory, hosted on my personal PC with Ryzen 3700X and DDR4 at 3200MHz. I will use OTP 26.1.1.

    Day 1

    Part 1

    I would never suspect that I’ll begin the AoC challenge with being loaded onto a trebuchet. I’d better do the math properly! Or rather – have Erlang do the calibration for me.

    FYI: I do have some extra motivation to repair the snow production: my kids have been singing “Do You Want to Build a Snowman?” for a couple of days already and there is still nowhere enough of it where I live.

    I considered three approaches to the first part of the puzzle:

    1. Run a regular expression on each line.
    2. Filter characters of a line with binary comprehension and then get the first and last digit from the result.
    3. Iterate over characters of a line and store digits in two accumulators.

    I chose the last one, as (1) felt like shooting a mosquito with a M61 Vulcan Cannon. Second one felt kind of less Erlang-ish than the third one. After all, matching binaries and recursive solutions are very natural in this language.

    Timings

    Min Avg Max
    Compiled + JIT 0.000091s 0.000098s 0.000202s
    Compiled + no JIT 0.000252s 0.000268s 0.000344s
    Interpreted 0.091494s 0.094965s 0.111017s

    Part 2

    By choosing the method of matching binaries, I was able to add support for digits as words pretty easily. If there were more mappings than just nine, I’d probably use a map to store all possible conversions and maybe even compile a regular expression from them.

    Eventually, the temptation of violating the DRY rule a bit was too strong and I just went for individual function clauses.

    And my solution was invalid. Shame on me but I admit I needed a hint from other participants – it turned out that some words can overlap and they have to be treated as individual digits. It wasn’t explicitly specified and ignoring overlaps in the example did not lead to an invalid result – a truly evil decision of AoC maintainers!

    Simply put, at first I thought such a code would be enough:

    parse(<<"one", Rest/binary>>, First, _Last) -> store(1, Rest, First);

    But the actual Rest must be defined as <<_:8, Rest/binary>>.

    Timings

    Min Avg Max
    Compiled + JIT 0.000212s 0.000225s 0.000324s
    Compiled + no JIT 0.000648s 0.000679s 0.000778s
    Interpreted 0.207670s 0.213344s 0.242223s

    JIT does make a difference, doesn’t it?

    The post Advent of Code 2023 appeared first on Erlang Solutions .

    • chevron_right

      yaxim: Planned downtime + Happy 10th anniversary, yax.im!

      news.movim.eu / PlanetJabber · Monday, 27 November, 2023 - 15:56 · 2 minutes

    Our Android XMPP client yaxim was created in 2009. A decade later, we celebrated its round birthday . To make the user experience more straightforward, we launched the yax.im public XMPP service in November 2013, to become the default server in yaxim. Now, ten years later, it’s time to recap and to upgrade the hosting infrastructure.

    Downtime announcement

    We will migrate the server from the old infrastructure to the new one, on November 31st, between 8:00 and 11:00 UTC. Please expect a few hours of downtime until everything is settled!

    The migration will also include an upgrade to prosody 0.12 and the deactivation of TLS v1.0 and v1.1 in favor of TLS v1.3.

    Many thanks go to boerde.de for being our home for the last decade, and for enduring a few DDoS attacks on our behalf. Additional thanks go to AS250 for offering us a new home.

    Ten years review

    We started the service on Debian Squeeze with the freshly released Prosody 0.9 on it. Since then, there were quite a few upgrades of both the OS and of prosody. However, for technical reasons, the server is currently running on a prosody development snapshot that predates the current 0.12 major update .

    In that time we’ve grown significantly, and are currently processing on average 100 thousand messages and 6.3 million presence stanzas every day.

    Back in 2013, we were quite avantgarde to support not only TLSv1.0, but also v1.1 and v1.2. The support was only added into Android with the 4.1 release in 2012 and wasn’t enabled by default until 2014 with Android 5 . Now we are lagging behind, given that TLS v1.3 came with Android 10 four years ago .

    IRC transports

    Since 2017, we are operating a beta (internal only) biboumi IRC transport on irc.yax.im and two dedicated transports for IRCnet on ircnet.yax.im and for euIRC on euirc.yax.im .

    These were never officially announced and have just a few users. They will be migrated to the new host as well, but with a lower priority.

    Spam fighting efforts

    The XMPP spam problem has been a significant annoyance to most users. We have the opinion that XMPP spam can be best fought at the server level, where aggregate views and statistics are available, and spam can be blocked centrally for all users with mod_firewall .

    In 2017, we have implemented spam detection and prevention both for yax.im users and against spam bots registered on our server. In 2020, we extended that to auto-quarantine suspicious account creations .

    In the last two weeks, our spam fighting efforts have blocked 21.000 spam messages from 7.600 accounts on 72 servers, including 480 auto-flagged bot accounts on yax.im. We were not explicitly keepig note, but the number of auto-flagged accounts since the measure was introduced in 2020 is around 30.000 .

    As part of the JabberSPAM initiative, we have helped report abuse and bring down unmaintained spam relays.

    Future

    With the new hosting platform and our committed team of three administrators, we are ready to take on the challenges of the future and to sustain the growth of our user base.

    • wifi_tethering open_in_new

      This post is public

      yaxim.org /blog/2023/11/27/happy-10th-yax_im/

    • chevron_right

      Ignite Realtime Blog: New Openfire plugin: Reporting Account Affiliations

      news.movim.eu / PlanetJabber · Monday, 27 November, 2023 - 14:48 · 1 minute

    I’m excited to announce a new Openfire plugin: the Reporting Account Affiliations Plugin!

    This plugin implements a new prototype XMPP extension of the same name .

    To quote the specification:

    In practice, a server may not trust all accounts equally. For example, if a server offers anonymous access or open registration, it may have very little trust in such users. Meanwhile a user account that was provisioned by a server administrator for an employee or a family member would naturally have a higher level of trust.

    Even if a server alters its own behaviour based on how much it trusts a user account (such as preventing anonymous users from performing certain actions), other entities on the network have no way of knowing what trust to place in JIDs they have not encountered before - they can only judge the server as a whole.

    This lack of insight can result in the negative actions (spam, abuse, etc.) by untrusted users on a domain causing the whole domain to be sanctioned by other servers.

    This new plugin allows for Openfire to report to other entities the relationship it has with a user on its domain.

    Note: at the time of writing, the protocol as implemented by this plugin has not yet been accepted for consideration or approved in any official manner by the XMPP Standards Foundation, and this document is not yet an XMPP Extension Protocol (XEP). This plugin should be considered experimental.

    The plugin will be visible in the list of available plugins of your Openfire instance in a matter of hours. You can also download it directly from its archive page .

    For other release announcements and news follow us on Mastodon or X

    1 post - 1 participant

    Read full topic

    • chevron_right

      Ignite Realtime Blog: Smack 4.4.7 released

      news.movim.eu / PlanetJabber · Sunday, 26 November, 2023 - 16:42 · 1 minute

    We are happy to announce the release of Smack 4.4.7. For a high-level overview of what’s changed in Smack 4.4.7, check out Smack’s changelog

    As with the last release, 4.4,6, parts of the release where driven by feedback from the Jitsi folks.

    Due to SMACK-927, we had to change the behavior of a certain kind of incoming stanzas listeners, namely the ones added with XMPPConnection.addStanzaListener() . Before Smack 4.4.7, they where invoked outside of Smack’s main loop, now they are invoked as part of the main loop. As a result, all listeners have to finish before the main loop of the connection can continue. Consequently, if you use these kinds of listeners, make sure that they do not block, as otherwise the connection will also stop processing incoming stanzas, which can easily lead to a deadlock.

    You usually should not need to use these kinds of incoming stanza listeners, alternaives include XMPPConnection.addSyncStanzaListener() and XMPPConnection.addAsyncStanzaListeners() . Especially the latter ones, asynchronous stanza listeners, are efficiently processed and safer to use. Note that those listeners are not guranteed to be processed in-order.

    As always, this Smack patchlevel release is API compatible within the same major-minor version series (4.4) and all Smack releases are available via Maven Central .

    We would like to use this occasion to point at that Smack now ships with a NOTICE file. Please note that this adds some requirements when using Smack as per the Apache License 2.0 . The content of Smack’s NOTICE file can conveniently be retrieved using Smack.getNoticeStream() .

    1 post - 1 participant

    Read full topic

    • chevron_right

      Ignite Realtime Blog: External Service Discovery plugin 1.0.2 released!

      news.movim.eu / PlanetJabber · Wednesday, 22 November, 2023 - 19:21

    Version 1.0.2 of the External Service Discovery plugin has been released!

    This Openfire plugin allows your users to use external STUN and TURN services, optionally making use of temporary credentials for those services. It often is a prerequisite for being able to set up audio or video calls with Openfire.

    This version brings better compatibility with TURN services other than those implemented by CoTurn. A big thank you for Holger and @Zoidberg for implementing and extensively testing this improvement!

    Other changes include new translations for Spanish, Ukrainian, French and Portuguese and better compatibility with Java 17, while now requiring at least Java 8.

    The update should be visible in the Plugins section of your Openfire admin console within the next few days. You can also download it from the plugin’s archive page .

    For other release announcements and news follow us on Mastodon or X

    1 post - 1 participant

    Read full topic

    • chevron_right

      ProcessOne: Automatic schema update in ejabberd

      news.movim.eu / PlanetJabber · Tuesday, 21 November, 2023 - 15:11

    ejabberd 23.10 has a new feature that is currently in beta testing:
    Automatic relational schema creation and update.

    Previously, if you were using ejabberd with an external relational database , you might have to manually apply some schema changes that come with new features when you upgrade to a new ejabberd release. ejabberd can now handle this schema upgrade automatically. It can also create the schema on an empty database during a new deployment. It works with both old and new schemas .

    This feature paves the way for more changes to our schema in the future. It is currently in beta testing, we recommend backing up your database before using it. To enable it in ejabberd 23.10, set this top-level option in your ejabberd.yml configuration file and restart ejabberd:

    update_sql_schema: true
    

    This is compatible with the following relational databases:

    Feel free to test it and report any problems on GitHub Issues .

    The post Automatic schema update in ejabberd first appeared on ProcessOne .
    • wifi_tethering open_in_new

      This post is public

      www.process-one.net /blog/automatic-schema-update-in-ejabberd/

    • chevron_right

      Ignite Realtime Blog: Openfire plugin maintenance release galore!

      news.movim.eu / PlanetJabber · Tuesday, 21 November, 2023 - 11:12 · 5 minutes

    After I performed a release of an Openfire plugin yesterday, @akrherz apparently had a ‘hold-my-beer’ moment, and apparently went through all of our plugins source repositories, creating maintenance releases for pretty much every one of them that had outstanding changes.

    Wow!

    As I do not believe we’re doing anyone a favor with 16 individual blog posts, I have combined all release notifications in this one.

    Most of these changes are minor: many of them add no functional change, but were needed to keep our build systems happy. Various plugins have new translations, provided by various community members (through the translation service provided by Transifex ). Thank you!

    The list of changes contains 18 plugins, 16 of which were updated, while 2 were archived. Here goes!

    Version 1.8.0 of the Registration plugin was released. The registration plugin allows admins to configure various actions whenever a new user creates an account. In this release, the reCaptcha implementation was replaced with Google’s reCAPTCHA v3 and various smaller improvements have been applied.

    Version 1.0.1 of the MUC Service Discovery Extensions plugin was released. This plugin for Openfire allows an admin to configure Extended Service Discovery information to Multi User Chat entities (chat rooms). This can be useful if you’re working on an XMPP-based application that uses chat rooms for more than regular chat functionality. This release was a maintenance release, in which a testing dependency was updated.

    Version 1.2.7 of the SIP Phone plugin was released. This plugin for Openfire lets you configure SIP phone support in Spark from the server. In this release the Chinese, Russian, Czech and Spanish translations are improved.

    Version 1.8.2 of the Content Filter plugin was released. This plugin for Openfire allows admins to configure various actions based on message content. These actions include notifying the admin of content matches, notifying the sender that a message was rejected or masking the content withalternative content. This release was a maintenance release, with minor refactoring (that didn’t affect functionality) and a new translation for the Ukrainian language.

    Version 0.0.2 of the IRMA Server plugin was released. This plugin for Openfire adds support for the privacy-friendly Yivi/IRMA identity platform . Minor bugs in the admin console page were fixed in this version.

    Version 0.2.1 of the Tiki Token plugin was released. This plugin adds authentication integration between Openfire and the Tiki Wiki CMS Groupware project . This is a minor maintenance release, updating the project structure without changing functionality.

    Version 1.0.1 of the Non-SASL Authentication plugin was released. TThe Non-SASL Authentication plugin provides a an implementation for authentication with Jabber servers and services using the jabber:iq:auth namespace.simple, as specified in XEP-0078: Non-SASL Authentication . This is a minor maintenance release, updating the project structure without changing functionality.

    Version 1.2.2 of the Callback on offline plugin was released. This plugin for Openfire sends an Async POST request with a JSON body to a configurable URL when a message is received for a user that’s offline. This is a minor maintenance release that does not introduce functionality changes.

    Version 1.0.0 of the JID Validation plugin was released. The JID Validation plugin adds JID Validation XEP-0328 capabilities to Openfire. This plugin is designed to work with various Jabber clients to allow other users to prepare and validate a given JID. This release was made to force the version numbering into the format used by our tooling, and does not introduce functional changes as compared to the earlier ‘1.0’ release.

    Version 1.7.6 of the XML Debugger plugin was released. This plugin for Openfire records XMPP traffic which can be useful for debugging purposes. This is a minor maintenance release that does not introduce functionality changes.

    Version 1.4.2 of the Subscription plugin was released. This plugin can be configured to automatically accept or reject subscription requests. When set to accept subscription requests users will be able to add someone to their roster (aka “Buddy List” or “Contacts”) without having to wait for a manual subscription acceptance from the requested user. Conversely, when the plugin is set to reject subscription requests users will not be able to add people to their roster. This is a minor maintenance release that does not introduce functionality changes.

    Version 3.3.2 of the Packet Filter plugin was released. The packet filter plugin allows you to create rules that will block or reject certain packets to the server. In this release a Portuguese translation is added.

    Version 2.7.1 of the User Import/Export plugin was released. The user import/export plugin provides a way to import and export Openfire user data via the Admin Console, compliant with XEP-0227 . The user data consists of username, password, name, email address, creation and modified date, and roster list (aka “buddy list”). This plugin also can aid in the migration of users from other Jabber/XMPP based systems to Openfire. This is a minor maintenance release, updating the project structure and adding new entries to the Openfire Admin Console for this plugin.

    Version 1.2.4 of the MotD plugin was released. The MotD (Message of the Day) plugin allows admins to have a message sent to a user each time they login. In this release a French and Portuguese translation is added.

    Version 1.2.4 of the STUN Server plugin was released. The STUN Server plugin provides address discovery for peer-to-peer sessions to be used for media transmission and receiving of UDP packets. It’s especially useful for clients behind NAT devices. In this release a Spanish and Portuguese translation is added.

    Version 2.2.4] of the GoJara plugin was released. This plugin implements XEP-0321 Remote Roster Management , allowing components to manage user’s roster to provide a simple way to keep rosters in sync. This is a minor maintenance release, adding a Portuguese translation and updating dependencies.

    We have archived the Openfire NodeJS plugin, as development of that plugin stalled, and the bundled version of NodeJS is outdated. This plugin should no longer be used.

    We have archived the Openfire MUC Service plugin. This plugin was replaced long ago with the REST API plugin . Please use that instead.

    For other release announcements and news follow us on Mastodon and X .

    1 post - 1 participant

    Read full topic