Files
Michel de Graaf cd580e5173 docs: lead with the protocol coverage, and drop a stale upload assertion
The message-set coverage is the crate's strongest claim, so say it where
people look first: the README features list and About, the website home
and community pages, each pointing at the coverage table. The table now
carries a section naming what the message set does not reach, so the
claim has something behind it rather than standing on its own.

The upload streaming test still asserted the uploader was blocked
waiting for the downloader's close — the wait that came out when it
started costing the upload slot. It passed only while the thread had yet
to be scheduled, and failed whenever it had.
2026-09-09 19:45:06 +00:00

7.9 KiB

Soulseek protocol coverage

What this client speaks, and where each message is proven to work. "e2e" means a test in soulseek-rs-lib/tests/e2e.rs drives it against a real server (soulfind) or a real peer; "unit" means the encoder or parser is tested on its own, which is all some messages can have — a server we do not run may never send them.

Message names and codes follow the Soulseek protocol as implemented by soulfind and Nicotine+.

Server messages

Code Message State Covered by
1 Login yes e2e — login, wrong password, re-login
2 SetWaitPort yes e2e — the port a listening client reports
3 GetPeerAddress yes e2e — direct download, browse
5 WatchUser yes e2e — watching a user, and an unknown one
6 UnwatchUser yes e2e — updates stop after unwatching
7 GetUserStatus yes e2e — status and share counts, away status
13 SayChatroom yes e2e — a message between two users in a room
14 JoinRoom yes e2e — public rooms, and private ones
15 LeaveRoom yes e2e — room list and membership
16 UserJoinedRoom yes e2e — a member arriving is announced
17 UserLeftRoom yes e2e — a member leaving is announced
18 ConnectToPeer yes e2e — firewalled download and browse
22 MessageUser yes e2e — a private message between users
23 MessageAcked yes e2e — an offline message is delivered once
26 FileSearch yes e2e — search round trip, two clients
28 SetStatus yes e2e — going away is visible to another user
32 ServerPing yes e2e — the session survives pings
35 SharedFoldersFiles yes e2e — share counts as another user sees them
36 GetUserStats yes e2e — stats, and our own recorded speed
41 Relogged yes e2e — a second login reports the first lost
42 UserSearch yes e2e — the named user answers
51 / 52 AddThingILike / Remove yes e2e — interests and similar users
54 GetRecommendations yes e2e — recommendations from our interests
56 GlobalRecommendations yes e2e — the server-wide list
57 UserInterests yes e2e — another user's likes and hates
64 RoomList yes e2e — a joined room appears in the list
66 AdminMessage yes e2e — a server announcement
69 PrivilegedUsers yes e2e — a privileged peer overtakes in the queue
71 HaveNoParent yes e2e — a leaf adopting a parent
83 / 84 ParentMinSpeed / ParentSpeedRatio yes unit — they set the child limit
92 CheckPrivileges yes e2e — how much privilege time we have
93 EmbeddedMessage yes unit — soulfind never sends one
100 AcceptChildren yes e2e — serving children
102 PossibleParents yes e2e — a leaf adopting a parent
103 WishlistSearch yes e2e — a wish is answered like any search
104 WishlistInterval yes e2e — the announced interval is kept
110 SimilarUsers yes e2e — shared interests make users similar
111 ItemRecommendations yes e2e — what else people who like this like
112 ItemSimilarUsers yes e2e — who likes an item
113 / 114 / 115 RoomTickers and changes yes e2e — the board on join, and updates
116 SetRoomTicker yes e2e — a ticker reaches other members
117 / 118 AddThingIHate / Remove yes e2e — hates come back in UserInterests
120 RoomSearch yes e2e — a member of the room answers
121 SendUploadSpeed yes e2e — the server records a finished upload
123 GivePrivileges yes e2e — a privileged account hands time over
126 / 127 BranchLevel / BranchRoot yes e2e — leaf adoption, and children
130 ResetDistributed yes unit — a new session starts parentless
133 RoomMembers yes e2e — a private room's roster
134 / 135 AddRoomMember / Remove yes e2e — granted and revoked
136 CancelRoomMembership yes e2e — a member resigns
137 CancelRoomOwnership yes e2e — the owner disbands the room
139 / 140 RoomMembershipGranted / Revoked yes e2e — the guest is told
141 EnableRoomInvitations yes e2e — set before an invitation
142 ChangePassword yes e2e — the next login needs the new one
143 / 144 AddRoomOperator / Remove yes e2e — the guest is promoted
145 / 146 RoomOperatorshipGranted / Revoked yes e2e — the guest is told
147 CancelRoomOperatorship yes e2e — an operator stands down
148 RoomOperators yes e2e — the roster after a promotion
149 MessageUsers yes e2e — one message, two recipients
150 / 151 / 152 Global room yes e2e — the feed starts and stops
160 ExcludedSearchPhrases yes e2e — the list is kept for our replies
1001 CantConnectToPeer yes e2e — a dial we cannot complete reports back
1003 CantCreateRoom yes e2e — a private room owned by someone else

Not implemented, and deliberately so: the messages the protocol lists as obsolete or deprecated, which no current client sends and soulfind answers only to be polite — SendConnectToken (33), UploadSlotsFull (40), SimilarRecommendations (50), MyRecommendations (55), PlaceInLineRequest (59), GlobalUserList (67), ParentIP (73), UserPrivileged (122), NotifyPrivileges (124), AckNotifyPrivileges (125), ChildDepth (129) and RelatedSearch (153).

Peer messages

Code Message State Covered by
0 PierceFirewall yes e2e — download and browse through the server
1 PeerInit yes e2e — every direct peer test
4 / 5 GetShareFileList and its reply yes e2e — browsing, in both directions
9 FileSearchResponse yes e2e — searching, in both directions
15 / 16 UserInfoRequest and its reply yes e2e — asking a peer about itself, and answering
36 / 37 FolderContentsRequest and its reply yes e2e — one folder of a peer's shares
40 TransferRequest yes e2e — downloads and uploads
41 TransferResponse yes e2e — downloads, cancellations, refusals
43 QueueUpload yes e2e — queueing, slots, privileged peers
44 PlaceInQueueResponse yes e2e — answering, and asking
46 UploadFailed yes e2e — the download fails promptly
50 UploadDenied yes e2e — the download fails promptly
51 PlaceInQueueRequest yes e2e — both directions

Distributed messages

Code Message State Covered by
3 DistribSearch yes e2e — a leaf answers, a parent passes it down
4 DistribBranchLevel yes e2e — adoption, and telling children
5 DistribBranchRoot yes e2e — adoption, and telling children
93 DistribEmbeddedMessage yes unit — unwrapped once, as Nicotine+ does

Serving children is off by default; see accept_children in the README.

What the message set does not cover

Every message above is implemented, which is the whole of the protocol's live message set. Three things in the protocol are not messages of their own and are still open, so "complete" means the message set rather than every byte the protocol describes:

  • Privately shared (locked) results. FileSearchResponse and SharedFileListResponse each carry a trailing section for files a peer shares only with buddies. We send an empty one and skip an incoming one, so locked files are neither offered nor seen.
  • Obfuscated connections. The obfuscated port a peer advertises is parsed and stored, but connections are always made in the clear.
  • Adopting a firewalled child. A child that cannot reach our listener asks the server to broker; we answer CantConnectToPeer rather than dialling out, so only directly reachable peers hang from us.