-- Leo's gemini proxy

-- Connecting to tilde.team:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini; lang=en

SRV Records And Gemini: A Proposal

Published: 2021-06-15

Tags: gemini


In this gemlog post, I'm going to lay out a proposal for using SRV records with Gemini.


Why?


Because of failover. Specifically, what prompted this was ew0k asking how you could handle failover for gemini servers. While the initial proposed solution (a reliable VPS which proxies the request to the right server) would work, it requires an additional VPS on top of whatever other servers you could have. In any case, there's already a solution for this sort of failover system: SRV records.


What are SRV records?


For the uninitiated, a SRV record (short for "Service") tells a client where it can find a specific service at a domain. For instance, if you wanted to know what server and port to connect to for, say, an XMPP client attempting to connect to a server, you would request an SRV record. SRV records follow the following format:


_service._proto.domain.name. TTL class SRV priority weight port target.

Where:


`service` is the service,

`proto` is the protocol (`tcp` or `udp` in practice),

`domain.name.` is the domain,

`class` is the DNS class (`IN` in practice),

`priority` is the priority of the record, where a lower number is contacted first,

`weight` is a relative weight, used to affect which server is chosen first within a priority level,

`port` is the port to connect to, and

`target` is the hostname to connect to.


How do you apply this to gemini?


Well, quite simply:


`service` is "gemini", and

`proto` is "tcp" (as Gemini is served over TCP).


The rest of the information is filled out as normal. So, a gemini SRV record for tilde.team would read:


_gemini._tcp.tilde.team. 3600 IN SRV 10 5 1965 tilde.team.

This also has the added bonus of allowing non-standard ports more easily:


_gemini._tcp.nonstandard.example.com. 3600 IN SRV 10 5 3000 example.com

A request for `gemini://nonstandard.example.com` would result in a connection to `example.com` on port 3000.


Doesn't this violate the principle of simplicity?


To an extent: yes. However, clients that didn't want to go through the hassle of implementing SRV records could simply continue doing what they do now. Nobody would be forcing new client devs to figure out SRV records. That being said, SRV records are a widespread-enough phenomenon that no matter what programming language you're writing a client in, someone has probably already written logic to handle SRV records. In Java, for instance, a library to do this was written by Spotify, of all companies.


Yes, Spotify really did write a library to resolve SRV records in Java (GitHub, HTTP)


I also wrote a fairly simplistic resolver in about 35 lines of Python, so it's not /that/ bad.


SRV resolver in about 35 lines of Python (GitHub Gist, HTTP)


Do you have example code?


You bet your bottom dollar I do.


Spartan client that handles SRV records (GitHub Gist, HTTP)

-- Response ended

-- Page fetched on Sat Apr 20 13:33:11 2024