Skip to content

Commit

Permalink
Refactoring code to support server and client better
Browse files Browse the repository at this point in the history
  • Loading branch information
emiago committed Oct 6, 2022
1 parent ea7e20d commit 5ba84ae
Show file tree
Hide file tree
Showing 7 changed files with 222 additions and 144 deletions.
82 changes: 82 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package sipgo

import (
"net"

"github.com/emiraganov/sipgo/sip"
"github.com/emiraganov/sipgo/transport"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)

type Client struct {
*UserAgent
log zerolog.Logger

AddViaHeader bool
AddRecordRoute bool
}

type ClientOption func(c *Client) error

func NewClient(ua *UserAgent, options ...ClientOption) (*Client, error) {
c := &Client{
UserAgent: ua,
log: log.Logger.With().Str("caller", "Client").Logger(),
}

for _, o := range options {
if err := o(c); err != nil {
return nil, err
}
}

// c.tx = transaction.NewLayer(c.tp)
return c, nil
}

// TransactionRequest uses transaction layer to send request
func (c *Client) TransactionRequest(req *sip.Request) (sip.ClientTransaction, error) {
c.updateRequest(req)
return c.tx.Request(req)
}

func (c *Client) WriteRequest(req *sip.Request) error {
return c.tp.WriteMsg(req)
}

func (c *Client) updateRequest(r *sip.Request) {
// We handle here only INVITE and BYE
// https://www.rfc-editor.org/rfc/rfc3261.html#section-16.6
if c.AddViaHeader {
if via, exists := r.Via(); exists {
newvia := via.Clone()
newvia.Host = c.host
newvia.Port = c.port
r.PrependHeader(newvia)

if via.Params.Has("rport") {
h, p, _ := net.SplitHostPort(r.Source())
via.Params.Add("rport", p)
via.Params.Add("received", h)
}
}
}

if c.AddRecordRoute {
rr := &sip.RecordRouteHeader{
Address: sip.Uri{
Host: c.host,
Port: c.port,
UriParams: sip.HeaderParams{
// Transport must be provided as well
// https://datatracker.ietf.org/doc/html/rfc5658
"transport": transport.NetworkToLower(r.Transport()),
"lr": "",
},
},
}

r.PrependHeader(rr)
}
}
14 changes: 11 additions & 3 deletions example/dialog/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,20 @@ func main() {
TimeFormat: "2006-01-02 15:04:05.000",
}).With().Timestamp().Logger().Level(zerolog.InfoLevel)

srv, err := sipgo.NewServerDialog()
ua, _ := sipgo.NewUA()

srv, err := sipgo.NewServerDialog(ua)
if err != nil {
log.Fatal().Err(err).Msg("Fail to setup dialog server")
}
client, err := sipgo.NewClient(ua)
if err != nil {
log.Fatal().Err(err).Msg("Fail to setup dialog server")
}

h := &Handler{
srv,
client,
*dst,
}

Expand All @@ -50,6 +57,7 @@ func setupRoutes(srv *sipgo.ServerDialog, h *Handler) {

type Handler struct {
s *sipgo.ServerDialog
c *sipgo.Client
dst string
}

Expand All @@ -76,7 +84,7 @@ func (h *Handler) route(req *sip.Request, tx sip.ServerTransaction) {
req.SetDestination(dst)
// Handle 200 Ack
if req.IsAck() {
if err := h.s.WriteRequest(req); err != nil {
if err := h.c.WriteRequest(req); err != nil {
log.Error().Err(err).Msg("Send failed")
reply(tx, req, 500, "")
return
Expand All @@ -85,7 +93,7 @@ func (h *Handler) route(req *sip.Request, tx sip.ServerTransaction) {
}

// Start client transaction and relay our request
clTx, err := h.s.TransactionRequest(req)
clTx, err := h.c.TransactionRequest(req)
if err != nil {
log.Error().Err(err).Msg("RequestWithContext failed")
reply(tx, req, 500, "")
Expand Down
23 changes: 18 additions & 5 deletions example/proxysip/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,27 @@ func httpServer(address string) {
func setupSipProxy(proxydst string, ip string) *sipgo.Server {
// Prepare all variables we need for our service
host, port, _ := sip.ParseAddr(ip)
srv, err := sipgo.NewServer(
ua, err := sipgo.NewUA(
sipgo.WithIP(ip),
)
if err != nil {
log.Fatal().Err(err).Msg("Fail to setup user agent")
}

srv, err := sipgo.NewServer(ua)
if err != nil {
log.Fatal().Err(err).Msg("Fail to setup server handle")
}

client, err := sipgo.NewClient(ua)
if err != nil {
log.Fatal().Err(err).Msg("Fail to setup proxy")
log.Fatal().Err(err).Msg("Fail to setup client handle")
}

client.AddViaHeader = true // Adds via header before shiping request
client.AddRecordRoute = true // Adds record route header before shiping request
srv.RemoveViaHeader = true

registry := NewRegistry()

var reply = func(tx sip.ServerTransaction, req *sip.Request, code sip.StatusCode, reason string) {
Expand Down Expand Up @@ -117,7 +130,7 @@ func setupSipProxy(proxydst string, ip string) *sipgo.Server {

req.SetDestination(dst)
// Start client transaction and relay our request
clTx, err := srv.TransactionRequest(req)
clTx, err := client.TransactionRequest(req)
if err != nil {
log.Error().Err(err).Msg("RequestWithContext failed")
reply(tx, req, 500, "")
Expand Down Expand Up @@ -149,7 +162,7 @@ func setupSipProxy(proxydst string, ip string) *sipgo.Server {
// Acks can not be send directly trough destination
log.Info().Str("m", m.StartLine()).Str("dst", dst).Msg("Proxing ACK")
m.SetDestination(dst)
srv.WriteRequest(m)
client.WriteRequest(m)

case m := <-tx.Cancels():
// Send response imediatelly
Expand Down Expand Up @@ -216,7 +229,7 @@ func setupSipProxy(proxydst string, ip string) *sipgo.Server {
dst = registry.Get(tohead.Address.User)
}
req.SetDestination(dst)
if err := srv.WriteRequest(req); err != nil {
if err := client.WriteRequest(req); err != nil {
log.Error().Err(err).Msg("Send failed")
reply(tx, req, 500, "")
}
Expand Down
Loading

0 comments on commit 5ba84ae

Please sign in to comment.