diff --git a/sip/addr.go b/sip/addr.go index fca34c7..eae9907 100755 --- a/sip/addr.go +++ b/sip/addr.go @@ -143,7 +143,7 @@ func (addr *Addr) Tag() *Addr { } // Reassembles a SIP address into a buffer. -func (addr *Addr) Append(b *bytes.Buffer) { +func (addr *Addr) Append(b *bytes.Buffer) error { if addr.Display != "" { b.WriteString("\"") b.WriteString(util.EscapeDisplay(addr.Display)) @@ -154,9 +154,10 @@ func (addr *Addr) Append(b *bytes.Buffer) { b.WriteString(">") addr.Params.Append(b) if addr.Next != nil { - b.WriteString(", ") + b.WriteString(",") addr.Next.Append(b) } + return nil } // Deep copies a new Addr object. @@ -207,5 +208,5 @@ func (addr *Addr) Reversed() *Addr { a.Next = res res = a } - return addr + return res } diff --git a/sip/addr_test.go b/sip/addr_test.go index f236c36..79d424b 100755 --- a/sip/addr_test.go +++ b/sip/addr_test.go @@ -139,7 +139,7 @@ func TestParseAddr(t *testing.T) { t.Error(err) continue } else { // Test was supposed to fail. - panic("TODO(jart): Implement failing support.") + t.Fatal("TODO(jart): Implement failing support.") } } if !reflect.DeepEqual(&test.addr, addr) { @@ -162,3 +162,30 @@ func TestAddrString(t *testing.T) { } } } + +func TestReversed(t *testing.T) { + a := &sip.Addr{ + Uri: &sip.URI{ + Scheme: "sip", + Host: "1.2.3.4", + Port: 5060, + }, + Next: &sip.Addr{ + Uri: &sip.URI{ + Scheme: "sip", + Host: "2.3.4.5", + Port: 5060, + }, + }, + } + b := a.Reversed() + if b.Uri.Host != "2.3.4.5" { + t.Error("first bad", b.Uri.Host) + } + if b.Next.Uri.Host != "1.2.3.4" { + t.Error("second bad", b.Next.Uri.Host) + } + if b.Next.Next != nil { + t.Error("wtf", b.Next.Next) + } +} diff --git a/sip/messages.go b/sip/messages.go index 3e0da7a..23be348 100644 --- a/sip/messages.go +++ b/sip/messages.go @@ -18,7 +18,6 @@ func NewRequest(tp *Transport, method string, to, from *Addr) *Msg { Via: tp.Via.Copy().Branch(), From: from.Or(tp.Contact).Tag(), To: to, - Contact: tp.Contact, CallID: util.GenerateCallID(), CSeq: util.GenerateCSeq(), CSeqMethod: method, @@ -46,9 +45,9 @@ func NewResponse(msg *Msg, status int) *Msg { func NewAck(original, msg *Msg) *Msg { return &Msg{ Method: MethodAck, - Request: original.Request, + Request: msg.Contact.Uri, Via: original.Via.Copy().SetNext(nil), - From: original.From, + From: msg.From, To: msg.To, CallID: original.CallID, CSeq: original.CSeq, diff --git a/sip/msg.go b/sip/msg.go index b37fd85..d7992bf 100755 --- a/sip/msg.go +++ b/sip/msg.go @@ -97,12 +97,14 @@ func ParseMsg(packet string) (msg *Msg, err error) { } else { if i := strings.Index(hdr, ": "); i > 0 { k, v = hdr[0:i], hdr[i+2:] + k = strings.Trim(k, " \t") + v = strings.Trim(v, " \t") + k = uncompactHeader(k) if k == "" || v == "" { - log.Println("[NOTICE]", "blank header found", hdr) + log.Println("Blank header found:", hdr) } - k = uncompactHeader(k) } else { - log.Println("[NOTICE]", "header missing delimiter", hdr) + log.Println("Header missing delimiter:", hdr) continue } } @@ -274,6 +276,22 @@ func (msg *Msg) Append(b *bytes.Buffer) error { b.WriteString("\r\n") } + if msg.Route != nil { + b.WriteString("Route: ") + if err := msg.Route.Append(b); err != nil { + return err + } + b.WriteString("\r\n") + } + + if msg.RecordRoute != nil { + b.WriteString("Record-Route: ") + if err := msg.RecordRoute.Append(b); err != nil { + return err + } + b.WriteString("\r\n") + } + if msg.MaxForwards < 0 { return errors.New("MaxForwards is less than 0!!") } else if msg.MaxForwards == 0 { diff --git a/sip/transport.go b/sip/transport.go index f2afc50..6c04df0 100755 --- a/sip/transport.go +++ b/sip/transport.go @@ -64,6 +64,7 @@ func NewTransport(contact *Addr) (tp *Transport, err error) { contact.Uri.Params["transport"] = addr.Network() tp = &Transport{ C: make(chan *Msg, 32), + E: make(chan error, 1), Sock: sock.(*net.UDPConn), Contact: contact, Via: &Via{ @@ -107,6 +108,7 @@ func (tp *Transport) launchConsumer() { for { msg, err := tp.recv() if err != nil { + log.Println("shutting down", err) tp.E <- err return } @@ -202,6 +204,9 @@ func (tp *Transport) route(old *Msg) (msg *Msg, dest string, err error) { var port uint16 msg = new(Msg) *msg = *old // Start off with a shallow copy. + if msg.Contact == nil { + msg.Contact = tp.Contact + } if msg.IsResponse { if msg.Via.CompareAddr(tp.Via) { // In proxy scenarios we have to remove our own Via. @@ -229,7 +234,8 @@ func (tp *Transport) route(old *Msg) (msg *Msg, dest string, err error) { if msg.Route.Uri.Params.Has("lr") { // RFC3261 16.12.1.1 Basic SIP Trapezoid route := msg.Route - msg.Route = msg.Route.Next + // TODO(jart): Remove if same as Contact. + // msg.Route = msg.Route.Next host, port = route.Uri.Host, route.Uri.Port } else { // RFC3261 16.12.1.2: Traversing a Strict-Routing Proxy diff --git a/sip/uri.go b/sip/uri.go index c20c567..e094816 100755 --- a/sip/uri.go +++ b/sip/uri.go @@ -155,7 +155,7 @@ func (uri *URI) Append(b *bytes.Buffer) { } else { b.WriteString(util.URLEscape(uri.Host, false)) } - if uri.Port > 0 && uri.Port != 5060 { + if uri.Port > 0 { b.WriteString(":" + strconv.FormatInt(int64(uri.Port), 10)) } uri.Params.Append(b) diff --git a/sip/uri_test.go b/sip/uri_test.go index 25af202..de063e8 100755 --- a/sip/uri_test.go +++ b/sip/uri_test.go @@ -43,6 +43,16 @@ var uriTests = []uriTest{ }, }, + uriTest{ + s: "sip:+12125650666@cat.lol", + uri: sip.URI{ + Scheme: "sip", + User: "+12125650666", + Host: "cat.lol", + Port: 5060, + }, + }, + uriTest{ s: "sip:jtunney@bsdtelecom.net:5060", s2: "sip:jtunney@bsdtelecom.net", diff --git a/util/escape.go b/util/escape.go index 7502adf..f2b3386 100755 --- a/util/escape.go +++ b/util/escape.go @@ -41,7 +41,7 @@ func shouldEscape(c byte) bool { switch c { case '<', '>', '#', '%', '"', // RFC 2396 delims '{', '}', '|', '\\', '^', '[', ']', '`', // RFC2396 unwise - '?', '&', '=', '+': // RFC 2396 reserved in path + '?', '&', '=': // RFC 2396 reserved in path return true } return false