soul

package module
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 12, 2025 License: Unlicense Imports: 2 Imported by: 0

README

Soul

Go Reference codecov Go Report

A Go implementation of the SoulSeek protocol.

Protocol Specification

This implementation and naming convention is based on the Nicotine+ documentation but aioslsk was also consulted regularly too.

The library offers complete coverage of all server, peer, distributed and file messages' serialization and deserialization.

On top there is a client package with file sharing capabilities (global search/download/upload API/distributed network participation, obfuscation) but no chat, rooms, room searches & direct messages/searches (PRs are welcome :).

How to use

SoulSeek protocol has 4 different connection types. Server, Peer, File and Distributed. For each connection type there is a unique set of messages the server and peers expect from us and vice versa.

For a simple search & download example see /cmd/search-download.

Low level

Low level code facilitating the serialization and deserialization of each connection type and message code lives under the server, peer, file and distributed packages respectively. Each package offers a pair of Read/Write functions and the complete in use message codes (I did not implement obsolete protocol message codes.)

Each message is a struct, for example to make use of the server connection Login message code you need to:

// Open a connection with the server.
conn, _ = net.Dial("tcp", "server.slsknet.org:2242")

// Send the login message.
login := new(server.Login)
req, _ := login.Serialize("username", "password")
server.MessageWrite(conn, req)

// Receive the server message.
res, _, code, _ := server.MessageRead(conn)
switch server.Code(code) { // Uint32 to own server.Code type (int.)
case server.CodeLogin:
	login := new(server.Login)
	login.Deserialize(res)
	fmt.Println(login.Greet, login.IP, login.Sum)
...
}

Client

To successfully make use of the network, you will need certain procedures involving multiple types of connections at once. Under client package you will find the most common actions a client will probably make (login, search, download, participation in the distributed network and API for responding to search quests and uploads.) If like me your goal is to make a CLI, preferably one that will run on a server rather than a desktop and used as a library inside other Go software, then client code in the client package can be potentially useful as is, albeit incomplete (no file indexing/management, no database for state etc and yes PRs are still very welcome!)

API
Client
Peer
State

Tests

The library is thoroughly covered via unit and integration tests. Running the -short test suite will result in running the unit tests. The integration tests need docker available in host to run. This is because we are opening a local Soulfind instance (check the /client/Dockerfile for more.)

Units cover all connection types' serialization/deserialization and internal packages.

The client package contains the integration tests.

go test -parallel 100 --cover -covermode=atomic -coverpkg=./... ./...

Acknowledgements

Fork of goose. Thanks to a-cordier for starting the effort as this is usually the hardest part.

If this library was not what you were looking for consider checking out spotseek.

Documentation

Overview

Package soul holds the common types used by the rest of the sub-packages.

Index

Constants

This section is empty.

Variables

View Source
var ErrDifferentPacketSize = errors.New("the declared size of the package does not match the size of the actual read")

ErrDifferentPacketSize is returned when the declared size of the package does not match the size of the actual read.

View Source
var ErrMismatchingCodes = errors.New("mismatching codes")

ErrMismatchingCodes is returned when the code read from the stream does not match the expected of the consumer.

Functions

This section is empty.

Types

type ConnectionType

type ConnectionType string

ConnectionType represents the type of connection. Possible values are "P", "F" and "D".

type Token added in v1.0.0

type Token uint32

Token is a unique identifier of type uint32 that is used throughout the protocol.

func NewToken added in v1.0.0

func NewToken() Token

NewToken returns a new randomly generated uint32 long token. Under the hood, it uses math/rand/v2.Uint32().

Directories

Path Synopsis
cmd
Package distributed messages are sent to peers over a D connection (TCP), and are used for the distributed search network.
Package distributed messages are sent to peers over a D connection (TCP), and are used for the distributed search network.
Package file messages are sent to peers over a F connection (TCP), and do not have messages codes associated with them.
Package file messages are sent to peers over a F connection (TCP), and do not have messages codes associated with them.
Package internal holds low level functions that are meant to be used internally only.
Package internal holds low level functions that are meant to be used internally only.
Package peer messages are sent to peers over a P connection (TCP).
Package peer messages are sent to peers over a P connection (TCP).
Package server messages are used by clients to interface with the server over a connection (TCP).
Package server messages are used by clients to interface with the server over a connection (TCP).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL