A FreePascal implementation of the Barev protocol - a simplified peer-to-peer XMPP protocol for Yggdrasil IPv6 networks.
Barev enables direct messaging between nodes on Yggdrasil networks without central servers, using a "one pipe per buddy" connection model.
- JID Format:
localpart@yggdrasil_ipv6_address - Port: 5299 (default, configurable)
- Protocol: TCP over IPv6 (Yggdrasil addresses only)
- Security: Provided by Yggdrasil network encryption
barevtypes.pas - Basic types, constants, and data structures
barevxml.pas - XML generation and parsing for XMPP stanzas
barevnet.pas - Network/socket management (IPv6)
barev.pas - Main client interface
testbarev.pas - Simple test/demo program
- FreePascal 3.0.0 or later
- Linux/Unix system (uses Unix sockets API)
- Yggdrasil network connection with IPv6 address
makeThis creates the testbarev executable.
fpc testbarev.pasmake install-unitsThis compiles all units into the lib/ directory.
uses
Barev, BarevTypes;
var
Client: TBarevClient;
Buddy: TBarevBuddy;
begin
// Create client with your nick and Yggdrasil IPv6
Client := TBarevClient.Create('mynick', '201:af82:9f2f:7809::1');
// Set up event handlers
Client.OnMessageReceived := @OnMessageReceived;
Client.OnBuddyStatus := @OnBuddyStatus;
Client.OnLog := @OnLog;
// Start listening
if not Client.Start then
WriteLn('Failed to start');
// Add a buddy
Buddy := Client.AddBuddy('friend', '201:7a74:aa1e:101a::a1');
// Connect to buddy
Client.ConnectToBuddy(Buddy.JID);
// Main loop
while Running do
begin
Client.Process; // Handle network events
// Your application logic here
Sleep(100);
end;
// Cleanup
Client.Stop;
Client.Free;
end../testbarevThe test program will prompt for:
- Your nickname
- Your Yggdrasil IPv6 address
Then provides an interactive command-line interface.
help - Show help
add <nick@ipv6> - Add a buddy
list - List all buddies
connect <nick@ipv6> - Connect to a buddy
msg <nick@ipv6> <text> - Send a message
status <status> [msg] - Set your status (available/away/dnd)
load <file> - Load contacts from file
save <file> - Save contacts to file
quit - Exit
Create a text file (e.g., contacts.txt):
# Barev Contacts
# Format: nick@ipv6_address or nick@ipv6_address:port
alice@201:af82:9f2f:7809:be0c:360a:1587:6be7
bob@201:7a74:aa1e:101a::a1:5299
charlie@202:baad:cafe:1234::1
Then load it:
> load contacts.txt
Main client class for Barev messaging.
constructor Create(const ANick, AMyIPv6: string; APort: Word = BAREV_DEFAULT_PORT);Client Control
Start: Boolean- Start the client and begin listeningStop- Stop the clientProcess- Process network events (call regularly in your main loop)
Buddy Management
AddBuddy(Nick, IPv6: string; Port: Word): TBarevBuddy- Add a buddyRemoveBuddy(JID: string): Boolean- Remove a buddyGetBuddy(JID: string): TBarevBuddy- Find buddy by JIDGetBuddyCount: Integer- Get number of buddiesGetBuddyByIndex(Index: Integer): TBarevBuddy- Get buddy by index
Contact List
LoadContactsFromFile(FileName: string): Boolean- Load contactsSaveContactsToFile(FileName: string): Boolean- Save contacts
Communication
ConnectToBuddy(JID: string): Boolean- Initiate connection to buddySendMessage(JID, Text: string): Boolean- Send a messageSendPresence(Status: TBuddyStatus; Message: string): Boolean- Broadcast presenceSendPresenceToBuddy(JID: string; Status: TBuddyStatus; Message: string): Boolean- Send presence to specific buddy
property OnBuddyStatus: TBuddyStatusEvent;
// Called when buddy status changes
// procedure(Buddy: TBarevBuddy; OldStatus, NewStatus: TBuddyStatus)
property OnMessageReceived: TMessageReceivedEvent;
// Called when message is received
// procedure(Buddy: TBarevBuddy; const MessageText: string)
property OnConnectionState: TConnectionStateEvent;
// Called when connection state changes
// procedure(Buddy: TBarevBuddy; State: TConnectionState)
property OnLog: TLogEvent;
// Called for log messages
// procedure(const LogLevel, Message: string)Represents a contact/buddy.
Nick: string- Buddy's nicknameIPv6Address: string- Buddy's Yggdrasil IPv6 addressPort: Word- Buddy's port numberJID: string- Full JID (nick@ipv6)Status: TBuddyStatus- Current statusStatusMessage: string- Status message
bsOffline
bsAvailable
bsAway
bsExtendedAway
bsDoNotDisturbcsDisconnected
csConnecting
csStreamInit
csAuthenticated
csOnline./testbarev
Enter your nick: alice
Enter your Yggdrasil IPv6: 201:af82:9f2f:7809::1
> add bob@201:7a74:aa1e:101a::a1
> connect bob@201:7a74:aa1e:101a::a1./testbarev
Enter your nick: bob
Enter your Yggdrasil IPv6: 201:7a74:aa1e:101a::a1
> add alice@201:af82:9f2f:7809::1
# Alice's connection should be accepted automatically# In Terminal 1:
> msg bob@201:7a74:aa1e:101a::a1 Hello Bob!
# In Terminal 2:
*** Message from alice: Hello Bob!
> msg alice@201:af82:9f2f:7809::1 Hi Alice!- Each buddy pair maintains exactly ONE active TCP connection
- First connection established wins
- All bidirectional communication flows through this single pipe
- Subsequent connections from the same buddy replace the existing connection
- Initiator sends stream header:
<?xml version="1.0" encoding="UTF-8" ?>
<stream:stream xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" from="you@your_ip" to="buddy@buddy_ip">- Receiver responds with their stream header:
<?xml version="1.0" encoding="UTF-8" ?>
<stream:stream xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" from="buddy@buddy_ip" to="you@your_ip">- Both exchange presence:
<presence/>- Chat communication begins
<message to="buddy@buddy_ip" type="chat">
<body>Hello world!</body>
</message>The library automatically sends pings every 30 seconds and marks buddies offline after 3 consecutive failures.
Current Limitations:
- No file transfer support (XEP-0096/XEP-0065 not implemented)
- No VCard support
- Simple XML parser (not full XMPP compliance)
- Unix/Linux only (socket API)
- No TLS (relies on Yggdrasil encryption)
Future Enhancements:
- File transfer support
- VCard/avatar support
- Better XML parsing (full DOM or SAX)
- Windows socket support
- Threading for better concurrency
- Logging levels
- Configuration file support
- Message history
- Port might already be in use
- Try a different port:
Client := TBarevClient.Create('nick', 'ipv6', 5300); - Check with:
netstat -tuln | grep 5299
- Buddy is not listening (not running Barev client)
- Wrong IPv6 address
- Firewall blocking port 5299
- Test connectivity:
ping6 <buddy_ipv6>
- Invalid IPv6 address format
- Not a Yggdrasil address (must start with 200-3ff)
- Buddy not in your contact list
- Add them first:
add <nick@ipv6>
This is an initial implementation. Improvements welcome!
Key areas for contribution:
- Windows support
- Better threading/async I/O
- Full XMPP compliance
- File transfer support
- Unit tests
GPL v2 or later (matching original Pidgin Bonjour plugin)
Based on the Pidgin Bonjour plugin, modified for Yggdrasil networks. Protocol specification: barev.md
- Barev Protocol: https://github.com/norayr/barev
- Yggdrasil Network: https://yggdrasil-network.github.io/
- XMPP Core: RFC 6120
- Pidgin: https://pidgin.im/