Browse Source

More goodies.

pull/2/head
Justine Alexandra Roberts Tunney 11 years ago
parent
commit
74d6d242b5
5 changed files with 1178 additions and 1049 deletions
  1. +13
    -13
      sip/dialog.go
  2. +1056
    -1032
      sip/msg_parse.go
  3. +12
    -4
      sip/msg_parse.rl
  4. +92
    -0
      sip/msg_test.go
  5. +5
    -0
      sip/util.go

+ 13
- 13
sip/dialog.go View File

@ -18,12 +18,12 @@ const (
DialogRinging = 2
DialogAnswered = 3
DialogHangup = 4
resendInterval = 200 * time.Millisecond
maxResends = 2
)
var (
looseSignalling = flag.Bool("looseSignalling", true, "Permit SIP messages from servers other than the next hop.")
looseSignalling = flag.Bool("looseSignalling", false, "Permit SIP messages from servers other than the next hop.")
resendInterval = flag.Int("resendInterval", 200, "Milliseconds between SIP resends.")
maxResends = flag.Int("maxResends", 2, "Max SIP message retransmits.")
)
// Dialog represents an outbound SIP phone call.
@ -163,15 +163,15 @@ func (dls *dialogState) popRoute() bool {
dls.lseq = dls.request.CSeq
}
dls.requestResends = 0
dls.requestTimer = time.After(resendInterval)
dls.requestTimer = time.After(duration(resendInterval))
return dls.send(dls.request)
}
func (dls *dialogState) connect() bool {
if dls.sock == nil || dls.sock.RemoteAddr().String() != dls.addr {
// Create socket through which we send messages. This socket is connected to
// the remote address so we can receive ICMP unavailable errors. It also
// allows us to discover the appropriate IP address for this machine.
// Create socket through which we send messages. This socket is connected
// to the remote address so we can receive ICMP unavailable errors. It also
// allows us to discover the appropriate IP address for the local machine.
dls.cleanupSock()
conn, err := net.Dial("udp", dls.addr)
if err != nil {
@ -345,7 +345,7 @@ func (dls *dialogState) handleRequest(msg *Msg) bool {
}
func (dls *dialogState) checkSDP(msg *Msg) {
if msg.Headers["Content-Type"] == sdp.ContentType {
if msg.ContentType == sdp.ContentType {
ms, err := sdp.Parse(msg.Payload)
if err != nil {
log.Println("Bad SDP payload:", err)
@ -382,12 +382,12 @@ func (dls *dialogState) resendRequest() bool {
if dls.request == nil {
return true
}
if dls.requestResends < maxResends {
if dls.requestResends < *maxResends {
if !dls.send(dls.request) {
return false
}
dls.requestResends++
dls.requestTimer = time.After(resendInterval)
dls.requestTimer = time.After(duration(resendInterval))
} else {
log.Printf("Timeout: %s (%s)", dls.sock.RemoteAddr(), dls.dest)
if !dls.popRoute() {
@ -401,7 +401,7 @@ func (dls *dialogState) resendRequest() bool {
func (dls *dialogState) sendResponse(msg *Msg) bool {
dls.response = msg
dls.responseResends = 0
dls.responseTimer = time.After(resendInterval)
dls.responseTimer = time.After(duration(resendInterval))
return dls.send(dls.response)
}
@ -409,12 +409,12 @@ func (dls *dialogState) resendResponse() bool {
if dls.response == nil {
return true
}
if dls.responseResends < maxResends {
if dls.responseResends < *maxResends {
if !dls.send(dls.response) {
return false
}
dls.responseResends++
dls.responseTimer = time.After(resendInterval)
dls.responseTimer = time.After(duration(resendInterval))
} else {
// TODO(jart): If resending INVITE 200 OK, start sending BYE.
log.Printf("Timeout sending response: %s (%s)", dls.sock.RemoteAddr(), dls.dest)


+ 1056
- 1032
sip/msg_parse.go
File diff suppressed because it is too large
View File


+ 12
- 4
sip/msg_parse.rl View File

@ -23,6 +23,10 @@ func ParseMsgBytes(data []byte) (msg *Msg, err error) {
return nil, nil
}
msg = new(Msg)
viap := &msg.Via
routep := &msg.Route
rroutep := &msg.RecordRoute
contactp := &msg.Contact
cs := 0
p := 0
pe := len(data)
@ -148,8 +152,9 @@ func ParseMsgBytes(data []byte) (msg *Msg, err error) {
}
action Contact {
msg.Contact, err = ParseAddr(string(data[mark:p]))
*contactp, err = ParseAddr(string(data[mark:p]))
if err != nil { return nil, err }
for *contactp != nil { contactp = &(*contactp).Next }
}
action ContentDisposition {
@ -255,8 +260,9 @@ func ParseMsgBytes(data []byte) (msg *Msg, err error) {
}
action RecordRoute {
msg.RecordRoute, err = ParseAddr(string(data[mark:p]))
*rroutep, err = ParseAddr(string(data[mark:p]))
if err != nil { return nil, err }
for *rroutep != nil { rroutep = &(*rroutep).Next }
}
action ReferTo {
@ -281,8 +287,9 @@ func ParseMsgBytes(data []byte) (msg *Msg, err error) {
}
action Route {
msg.Route, err = ParseAddr(string(data[mark:p]))
*routep, err = ParseAddr(string(data[mark:p]))
if err != nil { return nil, err }
for *routep != nil { routep = &(*routep).Next }
}
action Server {
@ -315,8 +322,9 @@ func ParseMsgBytes(data []byte) (msg *Msg, err error) {
}
action Via {
msg.Via, err = ParseVia(string(data[mark:p]))
*viap, err = ParseVia(string(data[mark:p]))
if err != nil { return nil, err }
for *viap != nil { viap = &(*viap).Next }
}
action Warning {


+ 92
- 0
sip/msg_test.go View File

@ -165,6 +165,95 @@ var msgTests = []msgTest{
},
},
msgTest{
s: "SIP/2.0 200 OK\r\n" +
"Via: SIP/2.0/UDP 1.2.3.4:55345;branch=z9hG4bK-d1d81e94a099\r\n" +
"From: <sip:+12126660420@fl.gg>;tag=68e274dbd83b\r\n" +
"To: <sip:+12125650666@fl.gg>;tag=gK0cacc73a\r\n" +
"Call-ID: 042736d4-0bd9-4681-ab86-7321443ff58a\r\n" +
"CSeq: 31109 INVITE\r\n" +
"Record-Route: <sip:216.115.69.133:5060;lr>\r\n" +
"Record-Route: <sip:216.115.69.144:5060;lr>\r\n" +
"Contact: <sip:+12125650666@4.55.22.99:5060>\r\n" +
"Content-Type: application/sdp\r\n" +
"Content-Length: 168\r\n" +
"\r\n" +
"v=0\r\n" +
"o=- 24294 7759 IN IP4 4.55.22.66\r\n" +
"s=-\r\n" +
"c=IN IP4 4.55.22.66\r\n" +
"t=0 0\r\n" +
"m=audio 19580 RTP/AVP 0 101\r\n" +
"a=rtpmap:101 telephone-event/8000\r\n" +
"a=fmtp:101 0-15\r\n" +
"a=maxptime:20\r\n",
msg: sip.Msg{
VersionMajor: 2,
Status: 200,
Phrase: "OK",
CallID: "042736d4-0bd9-4681-ab86-7321443ff58a",
CSeq: 31109,
CSeqMethod: "INVITE",
ContentType: "application/sdp",
Via: &sip.Via{
Version: "2.0",
Proto: "UDP",
Host: "1.2.3.4",
Port: 55345,
Params: sip.Params{"branch": "z9hG4bK-d1d81e94a099"},
},
From: &sip.Addr{
Uri: &sip.URI{
Scheme: "sip",
User: "+12126660420",
Host: "fl.gg",
},
Params: sip.Params{"tag": "68e274dbd83b"},
},
To: &sip.Addr{
Uri: &sip.URI{
Scheme: "sip",
User: "+12125650666",
Host: "fl.gg",
},
Params: sip.Params{"tag": "gK0cacc73a"},
},
Contact: &sip.Addr{
Uri: &sip.URI{
Scheme: "sip",
User: "+12125650666",
Host: "4.55.22.99",
Port: 5060,
},
},
RecordRoute: &sip.Addr{
Uri: &sip.URI{
Scheme: "sip",
Host: "216.115.69.133",
Port: 5060,
Params: sip.Params{"lr": ""},
},
Next: &sip.Addr{
Uri: &sip.URI{
Scheme: "sip",
Host: "216.115.69.144",
Port: 5060,
Params: sip.Params{"lr": ""},
},
},
},
Payload: "v=0\r\n" +
"o=- 24294 7759 IN IP4 4.55.22.66\r\n" +
"s=-\r\n" +
"c=IN IP4 4.55.22.66\r\n" +
"t=0 0\r\n" +
"m=audio 19580 RTP/AVP 0 101\r\n" +
"a=rtpmap:101 telephone-event/8000\r\n" +
"a=fmtp:101 0-15\r\n" +
"a=maxptime:20\r\n",
},
},
msgTest{
name: "INVITE",
s: "INVITE sip:10.11.34.37 SIP/2.0\r\n" +
@ -295,6 +384,9 @@ func TestParseMsg(t *testing.T) {
if !reflect.DeepEqual(test.msg.Contact, msg.Contact) {
t.Errorf("Contact:\n%#v !=\n%#v", test.msg.Contact, msg.Contact)
}
if !reflect.DeepEqual(test.msg.RecordRoute, msg.RecordRoute) {
t.Errorf("RecordRoute:\n%#v !=\n%#v", test.msg.RecordRoute, msg.RecordRoute)
}
}
}
}

+ 5
- 0
sip/util.go View File

@ -4,8 +4,13 @@ import (
"github.com/jart/gosip/util"
"strconv"
"strings"
"time"
)
func duration(ms *int) time.Duration {
return time.Duration(*ms) * time.Millisecond
}
func or5060(port uint16) uint16 {
if port == 0 {
return 5060


Loading…
Cancel
Save