On the subject of “P2P”, it should be noted that in “serverless” systems, the user program (client) usually takes over the tasks of a server. The server is virtually the end device itself where the appropriate settings must also be made - there is only no third party that takes over this task as a service provider (“server”).
P2P according to Wikipedia:
In a pure peer-to-peer network, all computers have equal rights and can both use and provide services.
Jami (external) puts it this way, for example:
Jami works as a server and gets new ports for each connections (randomly binded). These are the ranges that can be used for each component …
This documentation states that Jami works as a server. So, it is a distributed system where peers are both clients and servers. Servers exist.
What is pure P2P? The very name suggests that nothing issues accept() nor listen(). However, that is unlikely. Most implementations I’ve seen of P2P have nodes which behave as clients (they connect to things) and servers (they accept() and listen() for connections). The definitions are intentionally ambiguous. A peer is defined as something that cannot be connected to while a server is something that things connect to. In P2P networks, this is most likely the behavior regardless of the model (coordinated or distributed or whatever (perhaps magic cosmic dust)). P2P: clients accept() / listen() and / or connect(). Those are hybrid peers. Some are pure peers because they only connect(). As this is not my investigation, I would inquire about the specifics of the projects you list.
Above is an implementation which will be released soon demonstrating a model where two clients connect to each other without issuing accept() and listen(). They both bind to local addresses and repeatedly issue connect() every millisecond.
P2P is not to be equated with Anonymity!