Code Monkey home page Code Monkey logo

sipgo's Introduction

SIPGO

Go Report Card License GitHub go.mod Go version

SIPGO is library for writing fast SIP services in GO language.
It comes with SIP stack (RFC 3261|RFC3581) optimized for fast parsing.

For experimental features checkout also
github.com/emiago/sipgox It adds media, call, dialog creation on top of sipgo more easily.

Fetch lib with:

go get github.com/emiago/sipgo

NOTE: LIB MAY HAVE API CHANGES UNTIL STABLE VERSION.

To keep project development you can support it

Also, if you are using lib in any way, we would like to share it here.

Supported protocols

  • UDP
  • TCP
  • TLS
  • WS
  • WSS

Examples

Tools developed:

  • CLI softphone for easy testing gophone
  • Simple proxy where NAT is problem psip
  • ... your tool can be here

Performance

As example you can find example/proxysip as simple version of statefull proxy. It is used for stress testing with sipp. To find out more about performance check the latest results:
example/proxysip

Used By

babelforce

Usage

Lib allows you to write easily sip servers, clients, stateful proxies, registrars or any sip routing. Writing in GO we are not limited to handle SIP requests/responses in many ways, or to integrate and scale with any external services (databases, caches...).

UAS/UAC build

Using server or client handle for UA you can build incoming or outgoing requests.

ua, _ := sipgo.NewUA() // Build user agent
srv, _ := sipgo.NewServer(ua) // Creating server handle
client, _ := sipgo.NewClient(ua) // Creating client handle
srv.OnInvite(inviteHandler)
srv.OnAck(ackHandler)
srv.OnCancel(cancelHandler)
srv.OnBye(byeHandler)

// For registrars
// srv.OnRegister(registerHandler)
ctx, _ := signal.NotifyContext(ctx, os.Interrupt)
go srv.ListenAndServe(ctx, "udp", "127.0.0.1:5060")
go srv.ListenAndServe(ctx, "tcp", "127.0.0.1:5061")
go srv.ListenAndServe(ctx, "ws", "127.0.0.1:5080")
<-ctx.Done()

TLS transports

// TLS
conf :=  sipgo.GenerateTLSConfig(certFile, keyFile, rootPems)
srv.ListenAndServeTLS(ctx, "tcp", "127.0.0.1:5061", conf)
srv.ListenAndServeTLS(ctx, "ws", "127.0.0.1:5081", conf)

Server Transaction

Server transaction is passed on handler

// Incoming request
srv.OnInvite(func(req *sip.Request, tx sip.ServerTransaction) {
    res := sip.NewResponseFromRequest(req, code, reason, body)
    // Send response
    tx.Respond(res)

    select {
        case m := <-tx.Acks(): // Handle ACK . ACKs on 2xx are send as different request
        case m := <-tx.Cancels(): // Handle Cancel 
        case <-tx.Done():
            // Signal transaction is done. 
            // Check any errors with tx.Err() to have more info why terminated
            return
    }

    // terminating handler terminates Server transaction automaticaly
})

Server stateless response

srv := sipgo.NewServer()
...
func ackHandler(req *sip.Request, tx sip.ServerTransaction) {
    res := sip.NewResponseFromRequest(req, code, reason, body)
    srv.WriteResponse(res)
}
srv.OnACK(ackHandler)

Client Transaction

Using client handle allows easy creating and sending request. Unless you customize transaction request with opts by default client.TransactionRequest will build all other headers needed to pass correct sip request.

Here is full example:

ctx := context.Background()
client, _ := sipgo.NewClient(ua) // Creating client handle

// Request is either from server request handler or created
req.SetDestination("10.1.2.3") // Change sip.Request destination
tx, err := client.TransactionRequest(ctx, req) // Send request and get client transaction handle

defer tx.Terminate() // Client Transaction must be terminated for cleanup
...

select {
    case res := <-tx.Responses():
    // Handle responses
    case <-tx.Done():
    // Wait for termination
    return
}

Client stateless request

client, _ := sipgo.NewClient(ua) // Creating client handle
req := sip.NewRequest(method, &recipment)
// Send request and forget
client.WriteRequest(req)

Dialog handling (NEW)

DialogClient and DialogServer allow easier managing multiple dialog (Calls) sessions

UAC:

contactHDR := sip.ContactHeader{
    Address: sip.Uri{User: "test", Host: "127.0.0.200", Port: 5088},
}
dialogCli := NewDialogClient(cli, contactHDR)

// Attach Bye handling for dialog
srv.OnBye(func(req *sip.Request, tx sip.ServerTransaction) {
    err := dialogCli.ReadBye(req, tx)
    //handle error
})

// Create dialog session
dialog, err := dialogCli.Invite(ctx, recipientURI, nil)
// Wait for answer
err = dialog.WaitAnswer(ctx, AnswerOptions{})
// Check dialog response dialog.InviteResponse (SDP) and return ACK
err = dialog.Ack(ctx)
// Send BYE to terminate call
err = dialog.Bye(ctx)

UAS:

uasContact := sip.ContactHeader{
    Address: sip.Uri{User: "test", Host: "127.0.0.200", Port: 5099},
}
dialogSrv := NewDialogServer(cli, uasContact)

srv.OnInvite(func(req *sip.Request, tx sip.ServerTransaction) {
    dlg, err := dialogSrv.ReadInvite(req, tx)
    // handle error
    dlg.Respond(sip.StatusTrying, "Trying", nil)
    dlg.Respond(sip.StatusOK, "OK", nil)
    
    // Instead Done also dlg.State() can be used
    <-dlg.Done()
})

srv.OnAck(func(req *sip.Request, tx sip.ServerTransaction) {
    dialogSrv.ReadAck(req, tx)
})

srv.OnBye(func(req *sip.Request, tx sip.ServerTransaction) {
    dialogSrv.ReadBye(req, tx)
})

Stateful Proxy build

Proxy is combination client and server handle that creates server/client transaction. They need to share same ua same like uac/uas build. Forwarding request is done via client handle:

srv.OnInvite(func(req *sip.Request, tx sip.ServerTransaction) {
    ctx := context.Background()
    req.SetDestination("10.1.2.3") // Change sip.Request destination
    // Start client transaction and relay our request. Add Via and Record-Route header
    clTx, err := client.TransactionRequest(ctx, req, sipgo.ClientRequestAddVia, sipgo.ClientRequestAddRecordRoute)
    // Send back response
    res := <-cltx.Responses()
    tx.Respond(res)
})

SIP Debug

You can have full SIP messages dumped from transport into Debug level message.

Example:

sip.SIPDebug = true
Feb 24 23:32:26.493191 DBG UDP read 10.10.0.10:5060 <- 10.10.0.100:5060:
SIP/2.0 100 Trying
Via: SIP/2.0/UDP 10.10.0.10:5060;rport=5060;received=10.10.0.10;branch=z9hG4bK.G3nCwpXAKJQ0T2oZUII70wuQx9NeXc61;alias
Via: SIP/2.0/UDP 10.10.1.1:5060;branch=z9hG4bK-1-1-0
Record-Route: <sip:10.10.0.10;transport=udp;lr>
Call-ID: [email protected]
From: "sipp" <sip:[email protected]>;tag=1SIPpTag001
To: "uac" <sip:[email protected]>
CSeq: 1 INVITE
Server: Asterisk PBX 18.16.0
Content-Length:  0

Documentation

More on documentation you can find on Go doc

E2E/integration testing

If you are interested using lib for your testing services then checkout article on how easy you can make calls and other

Tests

Coverage: 36.7%

Library will be covered with more tests. Focus is more on benchmarking currently.

go test ./...  

Credits

This project was based on gosip by project by @ghetovoice, but started as new project to achieve best/better performance and to improve API. This unfortunately required many design changes, therefore this libraries are not compatible.

Support

If you find this project interesting for bigger support or contributing, you can contact me on mail

For bugs features pls create issue.

sipgo's People

Contributors

emiago avatar oystedal avatar a12n avatar maratk1n avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.