# gosip puts SIP and RTP in a Go binary so a call can be a process

> gosip is a Go library for making phone calls, providing a full-stack SIP and RTP implementation aimed at backend telephony applications. Its design bet is that a call does not need a PBX underneath it, so you can run one process per call, which is what makes software upgrades free of dropped calls.

**jart/gosip** — Public Switched Telecommunications Network Unleashed

- Repository: https://github.com/jart/gosip
- Stars: 538 · Forks: 125
- Language: Go
- License: Apache-2.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/jart-gosip

## A SIP stack, not a telephony platform

gosip is pronounced gossip, and it is a library that lets you make phone calls using the Go programming language. It provides a full-stack SIP and RTP implementation tailored towards making calls over the PSTN through services such as Flowroute.

Full-stack is the phrase that sets expectations. This is not a client library that talks to an existing SIP stack. It implements the signalling and the media itself, so the thing you write is the whole application rather than a plugin inside somebody else's.

The README states the scope plainly and it is worth respecting. gosip is most suitable for backend telephony applications, and this is especially true for apps that do interesting things with audio.

That last clause is the real target. A great many telephony applications do nothing interesting with audio: they play a prompt, collect a keypad press, transfer the call. Those are better served by a general-purpose telephony server with a configuration file. gosip is for the case where the audio itself is the product, where you are mixing streams, applying an effect, running a recogniser over the call, or routing between participants.

The library says so itself. gosip is less suitable for PBX, IVR, and VoIP reselling, and for those things you should consider Asterisk, FreeSWITCH, or SER.

That kind of boundary statement is a good sign in a project description. It tells you the author knows what the library is not trying to be, and it means you can trust the rest of the description as a description of the intended use rather than as a sales pitch.

The project is Go, Apache-2.0 licensed, at version 0.1, with the default branch master and the last push on 2026-06-23. There are no GitHub releases, and the go.mod file names the module and asks for Go 1.14.

## The DSP is the reason to use it

The audio capabilities are listed as three specific things, and they are the most concrete part of the feature description.

SSE optimised audio mixing is the first. SSE here means the SIMD instruction set extension that modern x86 processors provide, and using it for mixing is the difference between audio mixing that scales to many streams and audio mixing that is CPU-bound. In a telephony application the mixing is on the critical path of every call, so this is not a micro-optimisation.

The second is an assembly implementation of the µLaw codec. µLaw is the compression format used in North American telephony, so it is not optional if you are terminating calls on that side of the Atlantic. Writing it in assembly rather than letting the compiler decide is a deliberate choice for the hot path, and the note in parentheses, that no other codecs are supported, is important.

That is a real constraint. There is one codec, and if your traffic is not µLaw, this library does not handle it. The same applies to the opposite side of the world, where the prevalent format is A-law.

The third is a comfort noise generator, which is one of those small protocol requirements that nobody thinks about until it is missing. When a call is on hold or during silence, the far end expects to hear something rather than a dead line, and a comfort noise generator produces the low-level hiss that keeps the connection alive.

DSP out of the box is the phrase the documentation uses, and the three items above are what that means in practice. The distinction from a framework like Adhearsion is that there is no separate media server to run and no second protocol between your code and the audio. The mixing happens inside your process, on the same machine as your logic, and it is as fast as the hardware allows.

For an application that does something interesting with audio, that is the whole argument. If your application does nothing interesting with audio, you would be paying for all of this and using none of it.

## One process per call, and why that matters for uptime

The design argument in the documentation is about process architecture, and it is the part that makes gosip different from the telephony frameworks it replaces.

The traditional setup is that telephony applications are written on top of PBX systems like Asterisk via an extension interface. Frameworks such as Adhearsion have introduced further layers of abstraction to this unwieldy regime, and the description of those systems is unflattering: they are slow, difficult to administer, and in many cases superfluous to the needs of the telephony app developer.

gosip sets you free from Asterisk because you can have everything in a single easy-to-deploy binary. And then the key sentence. gosip is lightweight enough that you can actually design your app to use a single process for each phone call, assuming your app is in the audio path.

The parenthetical is doing careful work. If your application is in the audio path, it is doing the mixing, so it has to hold the call's state, so putting it in its own process is natural rather than wasteful. And the payoff is stated: by taking this non-monolithic approach to design, you can actually build a higher availability global telephony service with zero interruptions during software upgrades.

That is the whole point of the architecture. If a call lives in one process, then deploying a new version means starting new processes and letting the old ones drain their calls. There is no shared call state to migrate, no long-running supervisor that has to be restarted, no window where an in-progress call is dropped because the software underneath it changed.

Compare that with the usual arrangement, where a media server holds the calls and the application logic is connected to it. The application can be upgraded independently, which is good, but the media server becomes a single point that has to be upgraded too, and it holds the state of every call in flight while it does.

That trade is a deliberate architectural bet and it only makes sense when the application genuinely is in the audio path. If your app is just doing IVR, the per-call process model costs you more than it saves.

## Failover, redirects and mid-call path changes

The networking behaviour is described with more specificity than most library documentation manages.

gosip has excellent support for SRV and NAPTR failover by way of timeouts, ICMP refusal, and 502 Service Unavailable responses.

Three failover signals is a meaningful list. A timeout is the obvious one and it is the slowest, since you have to wait for it. ICMP refusal is faster, because the network tells you the host is unreachable rather than the host silently dropping your packets. And a 502 Service Unavailable is the server telling you it is up but cannot serve you, which is different information from the host being unreachable.

SRV and NAPTR records are how DNS publishes the location of SIP services. SRV gives you a priority and a weight alongside the host and port, which is what lets a provider spread load and designate a backup. NAPTR goes further and can rewrite the URI itself.

A client that fails over only on timeout will sit waiting for a dead host. A client that also handles ICMP refusal and reads the server's own 502 can move to the next candidate quickly and, more importantly, can make the right choice, since the three signals mean different things.

The library also supports SIP redirects and changing the audio and signalling path mid-call. Redirects are the SIP mechanism for telling a client to contact a different server, and handling them properly is a common source of bugs in SIP stacks. Changing the path mid-call is the more unusual capability: the media stream and the signalling can be pointed somewhere else while a call is in progress, which is what you need for a transfer, a handover between servers, or a call that moves between machines.

That last capability is the one that connects back to the per-process design. If a call can be handed off mid-flight, then a process can exit once its call is elsewhere, and that is what makes the zero-downtime upgrade claim work rather than being an aspiration.

## A parser built from a finite state machine

The parsing approach is the one piece of the implementation that is explained with actual justification, and it is a good one.

gosip parses SIP messages using the Ragel finite state machine compiler, and much of the BNF was copied directly from the SIP RFC.

The reasoning given is that this implementation approach offers a fair amount of confidence that the parser is not only fast, but also correct and secure.

All three of those claims follow from the same property. Ragel compiles a regular expression into a finite state machine, and the input grammar becomes an executable state machine rather than a hand-written parser with hand-written branching. There are no early returns, no recursion depth to worry about, and no path through the code that was not described by the grammar.

That matters more for SIP than for most protocols, because a SIP message is text with headers, and a header can contain almost anything. A parser written with regular expressions and string operations tends to grow edge cases, and each edge case is a place where a malformed message can behave differently from what the author intended. In a protocol that crosses the public internet, that is a security surface.

The choice to copy the BNF from the RFC is also significant. The grammar in the specification is the authoritative description of what a valid SIP message is, and a parser built from that grammar accepts exactly what the specification describes. When a real-world implementation and the specification disagree, you know where the difference is.

The example RFCs the documentation lists explain how the project validates that. There is RFC 4475, the SIP Torture Test Messages, which is a deliberately nasty set of messages designed to break parsers. There are RFC 3665 and RFC 3666 for basic and PSTN call flows, and RFC 6216 for call flows using SIP security mechanisms. The reference RFCs that the implementation follows are RFC 3261 for SIP itself, RFC 4566 for SDP, RFC 3550 for RTP, RFC 4733 for RTP DTMF, RFC 3262 for SIP 100rel and RFC 3263 for locating a server.

The repository layout maps onto the protocol. There are sip/ for the signalling, rtp/ for the media, sdp/ for the session description, dialog/ for call dialogs, dsp/ for the audio processing, util/ and fone/ for the general helpers, and an example/ directory with echo, echo2, echo3, options and rawsip examples. The raw SIP example in particular is the one to look at if you want to see the parser working on the wire.

There are also AUTHORS and CONTRIBUTORS files at the root, which is the older Go convention rather than the git history convention.

## Conclusion

Adopt gosip if you are writing a backend telephony application that needs to handle audio itself, since the DSP and the signalling are both in the library and the whole thing deploys as one binary. Skip it if you are building a PBX, an IVR system or a wholesale resale platform, because the documentation says plainly that Asterisk, FreeSWITCH or SER are the right tools. Verify first which codec you need, since µLaw is the only one supported, which SIP provider you will register with, and that the failover behaviour you rely on matches what your carrier actually returns.

## FAQ

### What is gosip and what kind of application is it for?

It is a Go library for making phone calls, providing a full-stack SIP and RTP implementation tailored towards making calls over the PSTN through services such as Flowroute. It is most suitable for backend telephony applications, especially apps that do interesting things with audio, and the documentation says explicitly that it is less suitable for PBX, IVR and VoIP reselling, where Asterisk, FreeSWITCH or SER are the better choice.

### What audio features does gosip provide?

It supports DSP out of the box with SSE optimised audio mixing, an assembly implementation of the µLaw codec, and a comfort noise generator. µLaw is the only codec supported, which matters because it is the format used in North American telephony, so traffic in another format is not handled by the library.

### How does gosip handle failover and does it need a PBX?

It supports SRV and NAPTR failover through timeouts, ICMP refusal and 502 Service Unavailable responses, and it also supports SIP redirects and changing the audio and signalling path mid-call. You do not need Asterisk underneath it: the whole application can be a single easy-to-deploy binary, and because it is lightweight enough you can use one process per phone call, which is what allows a higher availability service with no interruptions during software upgrades.

## Sources

- [Issues](https://github.com/jart/gosip/issues)
- [jart/gosip on GitHub](https://github.com/jart/gosip)
- [License: Apache-2.0](https://github.com/jart/gosip/blob/master/LICENSE)
- [README](https://github.com/jart/gosip/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/jart-gosip
