Original gist: https://gist.github.com/schmichael/7034672
See: http://whispering-gophers.appspot.com/talk.slide#1 via
{
"ID": "<unique string>",
"Addr": "<IP:Port of sender>",
"Body": "<the actual message to display>"
}
Basic protocol:
- Manually connect to at least 1 peer; connect to new peers seen in Addr fields
- Accept connections from any peer
- Broadcast all messages to all peers (except Addr); store list of Seen messages by ID to avoid rebroadcasting
- Output non-local messages to stdout; send messages from stdin
- Payloads without a Body and/or with unknown keys should be silently ignored to support extensions
Stretch goals:
Roughly ordered based on difficulty.
- Drop old messages - requires Timestamp field
- Forget old messages (the basic daemon slowly uses all memory) - may use Timestamp field - see below
- Base ID on hash of Addr + Body + Timestamp - see below
- Discover based on UDP broadcasts See below
- Build web interface into daemon
- Simple input form (textbox + submit button)
- Chat output (refreshed on a timer or using websockets if you're really fancy)
- Peer connection controls (connect to a new host, disconnect from a host)
- File transfers - see below
- Send backlog to newly connected peers - see backlog below
- Flood control: Disconnect and blacklist peers whose activity exceeds a threshold
- PKI all the things
- Scalable routing
UDP Broadcast Protocol
Broadcasts should be of the form: ":" and may be sent on behalf of any peers.
Timestamp field
To support various features, messages should include an optional Timestamp field of the format milliseconds since UNIX epoch as a number. For example:
{
"ID": "abc123",
"Addr": "192.168.1.53:2345",
"Body": "Hello world!",
"Timestamp": 1382050782085
}
Hashed ID field
To support very rudimentary payload verification, use a hash of the concatenated Addr, Body, and Timestamp fields. To allow backward compatibility with old clients, hashed IDs should be of the form:
{
"ID": "hash:sha256:<hash>",
...
}
Where each string starts with "hash:" followed by the name of the hash function used, followed by a colon and the hex encoded hash.
Unknown hash functions should cause the reader to revert to the basic random-string-ID behavior.
Peers should drop messages whose hashes don't match the current message payload.
File transfers
Two new keys: "FileType" and "FileContents"
- FileType should be the MIME type like: "image/gif"
- FileContents should be the Base64 encoded file contents
Backlog
Upon receiving a new connection from a peer, a daemon should replay that peer the last N messages (the actual number shouldn't be important) to the peer.
- Make protocol newline delimited. Golang's Decoder makes it quick and easy to get up and running quickly, but it also makes lots of common error cases impossible to handle. Breaking change.
- Define whether Addrs (the sender's address) should be ephemeral or persistent. Seemed like most implementations had ephemeral conenctions for sending which breaks the peer autodetection.
- Gavin's UDP broadcast feature is another fix for this, but ephemeral clients are still troublesome.
- Polyglot hack night?
With our network up could we could trade develop our own cyber currency. It could present some fun problems to work on.