Skip to content

Commit

Permalink
GenerateBranch is now optimized although it increased allocs
Browse files Browse the repository at this point in the history
  • Loading branch information
emiago committed Jan 30, 2023
1 parent 1fe088e commit b8846b8
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 16 deletions.
4 changes: 3 additions & 1 deletion client.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
8 changes: 4 additions & 4 deletions example/dialog/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
Expand Down
2 changes: 1 addition & 1 deletion example/proxysip/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
8 changes: 4 additions & 4 deletions example/proxysip/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
19 changes: 15 additions & 4 deletions sip/sip.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.<n chars>
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.
Expand Down
26 changes: 25 additions & 1 deletion sip/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import (
)

const (
letterBytes = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
letterBytes = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
letterIdxBits = 6 // 6 bits to represent a letter index
letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits
)

func init() {
Expand Down Expand Up @@ -41,6 +44,27 @@ func RandString(n int) string {
return string(output)
}

var src = rand.NewSource(time.Now().UnixNano())

// https://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-go
func RandStringBytesMask(sb *strings.Builder, n int) string {
sb.Grow(n)
// A src.Int63() generates 63 random bits, enough for letterIdxMax characters!
for i, cache, remain := n-1, src.Int63(), letterIdxMax; i >= 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
Expand Down
2 changes: 1 addition & 1 deletion transaction/layer.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit b8846b8

Please sign in to comment.