From b8846b83284900d243dcf2345c26f6c1f9698016 Mon Sep 17 00:00:00 2001 From: Emir Aganovic Date: Tue, 31 Jan 2023 00:33:49 +0100 Subject: [PATCH] GenerateBranch is now optimized although it increased allocs --- client.go | 4 +++- example/dialog/main.go | 8 ++++---- example/proxysip/docker-compose.yml | 2 +- example/proxysip/main.go | 8 ++++---- sip/sip.go | 19 +++++++++++++++---- sip/utils.go | 26 +++++++++++++++++++++++++- transaction/layer.go | 2 +- 7 files changed, 53 insertions(+), 16 deletions(-) diff --git a/client.go b/client.go index d63cf2e..c8cd7b5 100644 --- a/client.go +++ b/client.go @@ -138,9 +138,11 @@ func ClientRequestAddVia(c *Client, r *sip.Request) error { Params: sip.NewParams(), Next: nil, } - newvia.Params.Add("branch", sip.GenerateBranch()) + // NOTE: Consider lenght of branch configurable + newvia.Params.Add("branch", sip.GenerateBranchN(16)) if via, exists := r.Via(); exists { + // newvia.Params.Add("branch", via.Params["branch"]) if via.Params.Has("rport") { h, p, _ := net.SplitHostPort(r.Source()) via.Params.Add("rport", p) diff --git a/example/dialog/main.go b/example/dialog/main.go index 04a3eb5..4269b81 100644 --- a/example/dialog/main.go +++ b/example/dialog/main.go @@ -120,18 +120,18 @@ func (h *Handler) route(req *sip.Request, tx sip.ServerTransaction) { clTx.Cancel() case err := <-clTx.Errors(): - log.Error().Err(err).Str("caller", req.Method().String()).Msg("Client Transaction Error") + log.Error().Err(err).Str("caller", req.Method.String()).Msg("Client Transaction Error") return case err := <-tx.Errors(): - log.Error().Err(err).Str("caller", req.Method().String()).Msg("Server transaction error") + log.Error().Err(err).Str("caller", req.Method.String()).Msg("Server transaction error") return case <-tx.Done(): - log.Debug().Str("req", req.Method().String()).Msg("Transaction done") + log.Debug().Str("req", req.Method.String()).Msg("Transaction done") return case <-clTx.Done(): - log.Debug().Str("req", req.Method().String()).Msg("Client Transaction done") + log.Debug().Str("req", req.Method.String()).Msg("Client Transaction done") return } } diff --git a/example/proxysip/docker-compose.yml b/example/proxysip/docker-compose.yml index 11dc55e..a9f44f1 100644 --- a/example/proxysip/docker-compose.yml +++ b/example/proxysip/docker-compose.yml @@ -36,7 +36,7 @@ services: uac: image: ctaloi/sipp - command: -sn uac -r 1 -rp 1000 -i 10.5.0.30 10.5.0.10:5060 + command: -sn uac -r 1000 -rp 1000 -i 10.5.0.30 10.5.0.10:5060 # network_mode: "host" cpuset: "5" networks: diff --git a/example/proxysip/main.go b/example/proxysip/main.go index 0a144f2..0a29a84 100644 --- a/example/proxysip/main.go +++ b/example/proxysip/main.go @@ -159,10 +159,10 @@ func setupSipProxy(proxydst string, ip string) *sipgo.Server { } // Early terminate - if req.Method == sip.BYE { - // We will call client Terminate - return - } + // if req.Method == sip.BYE { + // // We will call client Terminate + // return + // } case m := <-tx.Acks(): // Acks can not be send directly trough destination diff --git a/sip/sip.go b/sip/sip.go index 3bf04f0..692be04 100644 --- a/sip/sip.go +++ b/sip/sip.go @@ -22,10 +22,21 @@ const ( // GenerateBranch returns random unique branch ID. func GenerateBranch() string { - return strings.Join([]string{ - RFC3261BranchMagicCookie, - RandString(32), - }, ".") + return GenerateBranchN(16) +} + +// GenerateBranchN returns random unique branch ID in format MagicCookie. +func GenerateBranchN(n int) string { + sb := &strings.Builder{} + generateBranchStringWrite(sb, n) + return sb.String() +} + +func generateBranchStringWrite(sb *strings.Builder, n int) { + sb.Grow(len(RFC3261BranchMagicCookie) + 33) + sb.WriteString(RFC3261BranchMagicCookie) + sb.WriteString(".") + RandStringBytesMask(sb, 32) } // DefaultPort returns protocol default port by network. diff --git a/sip/utils.go b/sip/utils.go index a145aab..17202f3 100644 --- a/sip/utils.go +++ b/sip/utils.go @@ -10,7 +10,10 @@ import ( ) const ( - letterBytes = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + letterBytes = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + letterIdxBits = 6 // 6 bits to represent a letter index + letterIdxMask = 1<= 0; { + if remain == 0 { + cache, remain = src.Int63(), letterIdxMax + } + if idx := int(cache & letterIdxMask); idx < len(letterBytes) { + sb.WriteByte(letterBytes[idx]) + i-- + } + cache >>= letterIdxBits + remain-- + } + + return sb.String() +} + // ASCIIToLower is faster than go version. It avoids one more loop func ASCIIToLower(s string) string { var b strings.Builder diff --git a/transaction/layer.go b/transaction/layer.go index 47fd059..46be8e0 100644 --- a/transaction/layer.go +++ b/transaction/layer.go @@ -145,7 +145,7 @@ func (txl *Layer) Request(req *sip.Request) (*ClientTx, error) { } if _, exists := txl.clientTransactions.get(key); exists { - return nil, fmt.Errorf("transaction already exists") + return nil, fmt.Errorf("transaction %q already exists", key) } conn, err := txl.tpl.ClientRequestConnection(req)