forked from jart/gosip
-
Notifications
You must be signed in to change notification settings - Fork 1
/
via.go
executable file
·124 lines (112 loc) · 2.82 KB
/
via.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// Copyright 2020 Justine Alexandra Roberts Tunney
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// SIP Via Address Library
package sip
import (
"bytes"
"strconv"
"github.com/jart/gosip/util"
)
// Example: SIP/2.0/UDP 1.2.3.4:5060;branch=z9hG4bK556f77e6.
type Via struct {
Protocol string // should be "SIP"
Version string // protocol version e.g. "2.0"
Transport string // transport type "UDP"
Host string // name or ip of egress interface
Port uint16 // network port number
Param *Param // param like branch, received, rport, etc.
Next *Via // pointer to next via header if any
}
func (via *Via) Append(b *bytes.Buffer) {
if via.Protocol == "" {
b.WriteString("SIP/")
} else {
b.WriteString(via.Protocol)
b.WriteString("/")
}
if via.Version == "" {
b.WriteString("2.0/")
} else {
b.WriteString(via.Version)
b.WriteString("/")
}
if via.Transport == "" {
b.WriteString("UDP ")
} else {
b.WriteString(via.Transport)
b.WriteString(" ")
}
b.WriteString(via.Host)
if via.Port != 5060 {
b.WriteString(":")
b.WriteString(strconv.Itoa(int(via.Port)))
}
via.Param.Append(b)
}
// Copy returns a deep copy of via.
func (via *Via) Copy() *Via {
if via == nil {
return nil
}
res := new(Via)
res.Protocol = via.Protocol
res.Version = via.Version
res.Transport = via.Transport
res.Host = via.Host
res.Port = via.Port
res.Param = via.Param
res.Next = via.Next.Copy()
return res
}
// Branch adds a randomly generated branch ID.
func (via *Via) Branch() *Via {
via.Param = &Param{"branch", util.GenerateBranch(), via.Param}
return via
}
// Detach returns a shallow copy of via with Next set to nil.
func (via *Via) Detach() *Via {
res := new(Via)
*res = *via
res.Next = nil
return res
}
// Last returns pointer to last via in linked list.
func (via *Via) Last() *Via {
if via != nil {
for ; via.Next != nil; via = via.Next {
}
}
return via
}
func (via *Via) CompareHostPort(other *Via) bool {
if via != nil && other != nil {
if via.Host == other.Host &&
via.Port == other.Port {
return true
}
}
return false
}
func (via *Via) CompareBranch(other *Via) bool {
if via != nil && other != nil {
if b1 := via.Param.Get("branch"); b1 != nil {
if b2 := other.Param.Get("branch"); b2 != nil {
if b1.Value == b2.Value {
return true
}
}
}
}
return false
}