func (e *endpoint) ServeNonInvite() { log.Info("Listening for incoming requests...") tx := <-e.tm.Requests() r := tx.Origin() log.Info("Received request: %v", r.Short()) log.Debug("Full form:\n%v\n", r.String()) // Send a 200 OK resp := base.NewResponse( "SIP/2.0", 200, "OK", []base.SipHeader{}, "", ) base.CopyHeaders("Via", tx.Origin(), resp) base.CopyHeaders("From", tx.Origin(), resp) base.CopyHeaders("To", tx.Origin(), resp) base.CopyHeaders("Call-Id", tx.Origin(), resp) base.CopyHeaders("CSeq", tx.Origin(), resp) resp.AddHeader( &base.ContactHeader{ DisplayName: &e.displayName, Address: &base.SipUri{ User: &e.username, Host: e.host, }, }, ) log.Info("Sending 200 OK") <-time.After(1 * time.Second) tx.Respond(resp) }
// Send an automatic ACK. func (tx *ClientTransaction) Ack() { ack := base.NewRequest(base.ACK, tx.origin.Recipient, tx.origin.SipVersion, []base.SipHeader{}, "") // Copy headers from original request. // TODO: Safety base.CopyHeaders("From", tx.origin, ack) base.CopyHeaders("Call-Id", tx.origin, ack) base.CopyHeaders("Route", tx.origin, ack) cseq := tx.origin.Headers("CSeq")[0].Copy() cseq.(*base.CSeq).MethodName = base.ACK ack.AddHeader(cseq) via := tx.origin.Headers("Via")[0].Copy() ack.AddHeader(via) // Copy headers from response. base.CopyHeaders("To", tx.lastResp, ack) // Send the ACK. tx.transport.Send(tx.dest, ack) }
// Handle a request. func (mng *Manager) request(r *base.Request) { t, ok := mng.getTx(r) if ok { t.Receive(r) return } // If we failed to correlate an ACK, just drop it. if r.Method == base.ACK { log.Warn("Couldn't correlate ACK to an open transaction. Dropping it.") return } // Create a new transaction tx := &ServerTransaction{} tx.tm = mng tx.origin = r tx.transport = mng.transport // Use the remote address in the top Via header. This is not correct behaviour. viaHeaders := tx.Origin().Headers("Via") if len(viaHeaders) == 0 { log.Warn("No Via header on new transaction. Transaction will be dropped.") return } via, ok := viaHeaders[0].(*base.ViaHeader) if !ok { panic(errors.New("Headers('Via') returned non-Via header!")) } if len(*via) == 0 { log.Warn("Via header contained no hops! Transaction will be dropped.") return } hop := (*via)[0] port := uint16(5060) if hop.Port != nil { port = *hop.Port } tx.dest = fmt.Sprintf("%s:%d", hop.Host, port) tx.transport = mng.transport tx.initFSM() tx.tu = make(chan *base.Response, 3) tx.tu_err = make(chan error, 1) tx.ack = make(chan *base.Request, 1) // Send a 100 Trying immediately. // Technically we shouldn't do this if we trustthe user to do it within 200ms, // but I'm not sure how to handle that situation right now. // Pretend the user sent us a 100 to send. trying := base.NewResponse( "SIP/2.0", 100, "Trying", []base.SipHeader{}, "", ) base.CopyHeaders("Via", tx.origin, trying) base.CopyHeaders("From", tx.origin, trying) base.CopyHeaders("To", tx.origin, trying) base.CopyHeaders("Call-Id", tx.origin, trying) base.CopyHeaders("CSeq", tx.origin, trying) tx.lastResp = trying tx.fsm.Spin(server_input_user_1xx) mng.requests <- tx }