| Linha 835: | Linha 835: | ||
[[Arquivo:SIPexemploURI.png|center|frame|Exemplo]] | [[Arquivo:SIPexemploURI.png|center|frame|Exemplo]] | ||
=== Comparação de URI === | === Comparação de URI === | ||
* Regras: | |||
** Um URI SIPS e um URI SIP nunca são equivalentes. | |||
** Comparação do userinfo é case sensitive. | |||
** A ordenação dos campos não é significativa. | |||
** O IP resultado de busca DNS não bate com o nome do host. | |||
** Para dois URIs serem iguais: usuário, senha, host e porta devem ser iguais. | |||
** Um URI que omite um parâmetro não é igual um que declara o parâmetro no valor padrão. Isso vale pra porta, transport-parameter, ttl-parameter, o user-parameter e method. | |||
* Para comparar os componentes uri-parameter: | |||
** Qualquer uri-parameter aparecendo em ambos URI's precisam bater. | |||
** Os componentes user, ttl, parameter uri ou até maddr não podem aparecer em só um dos comparados. Os outros parâmetros podem. | |||
** Componentes Header do URI nunca são ignorados. | |||
* URIs equivalentes: | |||
[[Arquivo:SIPiguaisURI.png|center|frame|]] | |||
* URIs não-equivalentes: | |||
[[Arquivo:SIPdiferURI.png|center|frame|]] | |||
* Lembrando, se aparecer security em um dos URIs esse parâmetro é ignorado, mas se aparecer nos dois, eles devem ter o mesmo valor! | |||
=== Formando requisições a partir de um URI === | |||
Edição das 21h17min de 28 de outubro de 2013
Link
Introdução
- SIP(Session Initiation Protocol), trabalha com gerenciamento de sessões, com várias formas de sessões multimídia de tempo real.
- É um protocolo da aplicação que lida com chamadas de telefone pela Internet.
- o SIP suporta 5 "facetas":
- Localização do usuário
- Disponibilidade do usuário
- Aptidões do usuário
- Iniciação de sessão (setup)
- Gerenciamento de sessão
- Pode trabalhar com outros procolos (RTP,RSTP,SDP,MEGACO), mas não precisa deles necessariamente.
- O SIP não provê serviços, mas primitivas para que estes possam ser implementados.
- Não é oferecido nenhum controle sobre os serviços de conferência, para isto devem ser usados outros protocolos.
- São oferecidos serviços de segurança, que envolvem criptografia, autenticação, privacidade...
- Funciona com IPv4 e IPv6.
Overview das Operações
- As funções básicas do SIP envolvem: localização do ponto final, negociação de parâmetros da sessão, etc.
- O SIP usa identificadores (URI) chamados de SIP URI. Cada lado da chamada possui o seu identificador.
- Um "INVITE" é uma requisição de chamada, parecido com o acontece no HTTP. Esta mensagem pode conter informações adicionais em seus campos.
- Segue abaixo uma figura de uma troca de mensagens SIP, e o modelo de um INVITE:


- Os campos do INVITE:
- Via: contém o endereço pelo qual Alice espera respostas para esta requisição, que também contém um parâmetro que identifica a transação.
- To: contém o destino (nome) e seu SIP URI.
- From: tem o nome do solicitante, seu SIP URI adicionado de uma string randômica usada para identificação.
- Call-ID: identificador único para esta chamada. A combinação de To, From e Call-ID define o relacionamento SIP peer-to-peer.
- CSeq: é um número incrementado para cada requisição (como um numero de sequência).
- Contact: traz um SIP ou SIP URI para contato direto com o solicitante. Neste campo pode ter o IP.
- Max-Forwards: funciona como o TTL, limitando o número de saltos.
- Content-Type: descrição do corpo da mensagem.
- Content-Lenght: um contador de bytes do corpo da mensagem.
- Uma mensagem SDP pode ser carregada pelo SIP com informações sobre a sessão.
- Se Alice não conhece a localização de Bob, seu servidor SIP (atlanta.com) passa a fazer a busca, e manda um Trying falando que recebeu o INVITE. A busca pode ser feita usando DNS e vai passando pelos servidores até chegar no Bob. Estes servidores podem ser chamados de proxy.
- Bob manda para Alice um reconhecimento de que recebeu o INVITE e depois um OK, aceitando-o.
- A mensagem OK copia os campos do INVITE e adiciona uma tag no "To" que vai ser usada pelo resto da comunicação. Segue abaixo a mensagem OK:

- Um servidor proxy pode mandar vários invites ao mesmo tempo, isso é chamado de forking.
- Alice responde o OK com um ACK, fechando o tree way handshaking do SIP. O ACK é direto pois o endereço de Bob já foi "aprendido".
- Um re-INVITE pode ser mandado paraa mudar as características da sessão, o qual deve ser respondido com um OK e depois ACK. Se não for aceito vem uma mensagem de "não aceitável" de número 488.
- Para encerrar é gerada uma mensagem BYE que deve ser respondida com uma 200(OK). Neste caso não há ACK.
- Um servidor proxy pode solicitar que todas as mensagens passem por ele.
- Uma operação comum é regitrar, para que o servidor proxy saiba a localização corrente do SIP phone. Aí fica claro que a distinção entre os servidores SIP é lógica e não física.
- Um usuário pode ter vários phones e um phone pode ser usado por vários usuários, assim o proxy pode fazer múltiplas buscas. O "registrar" pode ajudar nisto, mas não é o único meio, algumas funções de mapping podem ser configuradas pelo administrador.
- Existem outras mensagens SIP que serão apresentadas depois.
Estrutura
- O SIP pode ser estruturado em camadas.
- A primeira seria da sintaxe e codificação. A segunda seria a de transporte, que define como o cliente envia e recebe respostas. A terceira seria de transação, que envolve retransmissões, respostas,timeouts. A próxima camada seria o usuário de transação.
- Siglas:
- UA: User Agent
- UAC: User Agent Client
- UAS: User Agent Server
- Obs: estes componentes serão explicados posteriormente.
- Um diálogo é um relacionamento SIP peer-to-peer.
- O método mais importante do SIP é o INVITE.
Definições
- AOR (Address-of-Record): é como se fosse o endereço público de um usuário, sendo o SIP ou SIPS URI que aponta para um domínio com um serviço de localização.
- Back-to-Back User Agent (B2BUA): entidade local que recebe requisições e as processa como um UAS, e para determinar como seriam respondidas funciona como um UAC
- Call: refere a alguma comunicação entre peers.
- Call Stateful: mantém o estado de um diálogo desde o INVITE até o BYE.
- Conferência: Uma sessão com vários participantes.
- Core: funções específicas de uma entidade SIP.
- Downstream: do UAC até o UAS.
- Home Domain: Que oferece servíço de domínio ao usuário.
- Location Service: Usado por um redirecionamento SIP ou proxy para obter informações sobre a localização do callee (que recebe a requisição)
- Roteamento solto (Loose): segue procedimentos definidos para processar o campo de cabeçalho de roteamento, separando o destino do conjunto de proxies que devem ser visitados.
- Proxy de Saída (Outbound): Não pode ser resolvido pelo Request-URI.
- Busca paralela: Um proxy procura um usuário em várias possibilidades ao mesmo tempo.
- Resposta provisória: indica um avanço na busca, transação SIP, mas não o fim.
- "Registrar": Um servidor que aceita requisições do tipo REQUEST.
- Transação Regular: Uma transação que não envolva INVITE, CANCEL ou ACK.
- Ringback: Um tom produzido na chamada, indicando que a chamada foi alertada.
- Route Set: conjunto de SIPs ou SIPS URI que representa uma lista de proxies.
- Spiral: a mesma requisição chegando de diferentes formas em um proxy, o que resulta em diferentes respostas.
- Stateful/Stateless proxy: mantém ou não máquinas de estado do cliente ou servidor. É uma entidade lógica.
- Strict Routing: Outro tipo de roteamento seguindo a RFC 2543. O Proxy destrói os conteúdos do Request URI quando um Route header é presente.
- Usuário de Transição (TU): Camada que contém os cores (UAC, UAS, proxy).
- Upstream: Do UAS para o UAC.
- UAC: Cria uma requisição e a envia.
- UAS: Recebe um request e gera uma resposta. Tanto UAC quanto UAS recebem este nome enquanto durar a transação.
- UA: Pode ser UAC ou UAS.
Mensagens SIP
- O SIP é baseado em texto e usa o UTF-8.
- A mensagem pode ser uma requisição ou uma resposta, bem parecidas com o HTTP, mas o SIP NÃO É uma extensão do HTTP.
Requisições
- Toda requisição tem uma "Request-Line" como início que termina com CRLF (carriage-return line-feed).
- SP = single space
- Request-Line = Method SP Request-URI SP SIP-Version CRLF
- Method: caracteriza um dos possíveis métodos, que podem ser: INVITE, ACK, CANCEL, BYE, REGISTER e OPTIONS.
- Request-URI: SIP ou SIPS URI de quem está fazendo a requisição.
- SIP-Version: versão do protocolo.
Respostas
- A primeira linha é uma Status-Line.
- Status-Line = SIP-Version SP Status-Code SP Reason-Phrase SP
- O status é um valor de 3 dígitos que indica a satisfação de uma requisição. A Reason-Phrase é um resumo textual do status.
- O primeiro dígito do status indica a classe da resposta. São 6 classes:
- 1xx: Provisória, requisição recebida mas continua sendo processada.
- 2xx: Sucesso, recebida e aceita.
- 3xx: Redirecionamento, outra ação deve ser tomada
- 4xx: Erro no Cliente
- 5xx: Erro no Servidor
- 6xx: Erro global: a requisição não pode ser "cumprida" em nenhum servidor.
Campos do cabeçalho
- Cada campo do cabeçalho é formado por um par separado por ":". O número de espaços entre as duas palavras é ignorado.
- Para escrever várias linhas em um campo basta deixar um único SP no fim da linha ou um tab horizontal.
- A ordem dos campos não é significante, mas os campos que são usados no processamento dos proxys devem ficar mais acima para ser mais rápido.
- Podem ser adicionados vários valores pro campo, desde que sejam separados por vírgula, exceto alguns campos.

- Podem ser adicionados parâmetros aos campos, mas num nome de parâmetro não pode repetir.
- Campos do cabeçalho, valores, nomes de parâmetro, valores de parâmetro e tokens são case-insensitive.
- Exemplo:
- Contact: <sip:alice@atlanta.com>;expires=3600
- CONTACT: <sip:alice@atlanta.com>;ExPiReS=3600
- Estes dois são equivalentes, sendo que expires é um parâmetro.
- Alguns parâmetros só fazem sentido em requisições ou respostas, se eles forem percebidos em outro caso a mensagem deve ser ignorada.
- Existem formas compactas para os campos do SIP, que são usadas para evitar ultrapassar o MTU por exemplo.
Corpo da Mensagem
- Respostas e requisições incluem o corpo, que varia segundo o método.
- O Content-Type, indica o que vem no corpo, e se ouver compressão por exemplo, deve ser indicado no content type.
- Quando não é definido um conjunto de caracteres é adotado o UTF-8.
- Request com "multipart" devem mandar uma descrição da sessão.
- O campo Content-Length indica o tamanho do corpo.
- O SIP pode usar o UDP (diferente do HTTP), e num fluxo deste qualquer CRLF antes da "start-line" é ignorado.
Comportamento do UA (User Agent)
- O UA representa a "ponta" do sistema. É um UAC quando faz requisições (de acordo com estímulos externos) e é um UAS quando responde (por estímulos, entradas ou execução de programa).
- Os processos de um UA depende de duas coisas:
- Se a mensagem está em um diálogo
- O método da requisição
Comportamento UAC
Gerando Requisições
- Uma requisição válida deve ter no mínimo: To, From, CSeq, Call-ID, Max-Forwards e Via.
- O Request-URI da mensagem deve ser copiado do URI presente em "To" (a não ser no método REGISTER). Uma rota pré-existente (conjunto de URIs ordenados) pode afetar o Request-URI.
- To: Designa o recipiente lógico destino da requisição ou o endereço. Geralmente contém SIP ou SIPS URI, mas pode conter outras combinações.
- O UAC preenche esse campo conforme informações do usuário. Ele tenta validar este nome em um domínio (RHS - Right Hand Side) que geralmente é home domain, mas pode ser um proxy mais próximo.
- Uma requisição fora do diálogo pode não conter uma tag "to", já que esta identifica o peer do diálogo.
- From: Recebe o endereço, URI, do solicitante da requisição, não contém o IP. Pode ser preenchido com "Anonymous". Geralmente este campo é gerado pelo usuário ou administradores do domínio. Se vários usuários usam o mesmo UA, devem existir "Switchable profiles", com uma forma de autenticação.
- Este campo deve possui uma tag.
- Call-ID: Um campo que identifica todas as mensagens de um diálogo unicamente. Este valor é gerado pelo UAC que tem métodos para garantir. Certas requisições novas não precisam mudar o Call-ID dependendo da falha que aconteceu.
- O Call-ID é case sensitive, existe uma comparação byte por byte. É recomendado usar identificadores randomicamente criptografados para proteção.
- Exemplo: Call-ID: f81d4fae-7dec-11d0-a765-00a0c91e6bf6@foo.bar.com
- CSeq: identifica a ordem das transações. Consiste de um número de sequência e de um método (que deve bater com o da request). O valor varia até 2^31.
- Para requisições fora de um diálogo (que não sejam REQUEST) este valor é arbitrário.
- Exemplo: CSeq: 4711 INVITE
- Max-Forwards: Número máximo de saltos, que geralmente é 70. Se o UA conhece a rota este valor pode diminuir.
- Via: Indica o transporte usado e identifica a localização para a resposta. Este campo deve conter um parâmetro (branch) que identifica a transação criada pelo request.
- Este branch deve ser único no tempo e espaço pelo UA, exceto para CANCEL e ACK para respostas não-2xx. Ele começa com 7 caracteres (z9hG4bK) que funcionam como um cookie.
- Contact: Contém um SIP ou SIPS URI pelo qual o UA quer receber requisições. Se o Request-URI é um SIPS URI, contact também deve ser.
- Supported and Require: o Supported pode ser incluído listando as extensões suportadas pelo requisitante. O Require deve ser incluído caso o UAC queira "forçar" o UAS a usar uma extensão, pode incluir também Proxy-Require, aí os proxys pelo caminho devem ter a extensão. Estas extensões são definidas por RFCs.
- Outras mensagens adicionais podem ser incluídas após os campos anteriormente definidos serem construídos
Enviando a Requisição
- É feita uma busca DNS. Se o primeiro elemento na rote é um strict router, os procedimentos são aplicados ao Request-URI, em outros casos ao primeiro valor do campo route.
- Políticas locais podem influenciar nos destinos. Não é recomendado usar um único proxy na rota pré configurada.
- O UAC pode usar o processo de tentar cada endereço até que um servidor seja contactado, cada tentaiva caracteriza uma nova transação, com branch diferente.
Processando Respostas
- Respostas são processadas na sequência: Camada de transporte -> camada de transação -> TU (Transaction User)
- Algumas mensagens retornadas pela camada de transação não são SIP, mas erros!
- Se um UAC recebe uma mensagem que não seja x00 ele retorna um erro (resposta não reconhecida), assim deve processar todas respostas x00.
- Se tiver mais de um valor no campo Via em uma resposta, a mensagem é descartada.
- Quando vier uma mensagem do tipo 3xx os clientes usam uma URI que está no "Contact" para enviar novas requisições. Uma URI não deve ser testada mais de uma vez, para evitar loops.
- Estas novas requisições podem ser feitas em série ou em paralelo.
- Se toda a lista de contatos acabar, a requisição falha. Algumas respostas podem indicar uma nova tentativa de requisição, isto não é uma falha.
- No caso do 3xx o URI target deve ser todo copiado no Request-URI.
- Nas novas requisições podem ser inseridos novos valores se comparado a original se esta permitir uma lista separada por vírgulas, se não, valores podem ser sobrescritos. É recomendado que sejam usados os mesmos To, From e Call-ID do original, mas o UAC pode mudar o Call-ID.
- As novas requisições devem ter um novo branch ID.
- Certas repostas 4xx necessitam de processamento específico:
- 401(Unauthorized) ou 407(Proxy Authentication Required): o UAC pode tentar retomar a requisição com credenciais.
- 413 (Request Entity Too Large): Se possível o UAC tenta retomar request emitindo o corpo ou diminuindo a mensagem.
- 415 (Unsupported Media Type): o UAC tenta outra requisição atendendo ao campo "Accept" que estava na resposta do UAS que não suporta a mídia inicialmente tentada.
- 416 (Unsupported URI Scheme): O cliente pode tentar outra requisição usando SIP URI.
- 420 (Bad Extension): as extensões no Require, ou opções não são suportadas, e o cliente pode tentar de novo emitindo estas extensões.
- Nestes casos as novas requisições mantém os campos Call-ID, To e From, mas CSeq pode mudar.
- Outros tipos de 4xx, um "retry" pode ou não ser possível dependendo do método.
Comportamento UAS
- O fato de estar ou não em um diálogo influencia no processamento da UAS.
- Quando uma requisição é aceita todas as mudanças de estado devem ser feitas (Seção 12), se não, não devem ser feitas mudanças.
Inspeção de Método
- Uma requisição autenticada deve ter seu método inspecionado. Se o método não for suportado gera uma resposta 405(Method Not Allowed).
- O UAS pode incluir um campo Allow, mostrando quais são os métodos suportados por ele, quando dá a resposta 405.
Inspeção do Cabeçalho
- A UAS pode ignorar qualquer cabeçalho mal formado que não seja necessário para o processamento.
- O destino da mensagem "To", pode não ser este UAS, assim ele pode repassar adiante.
- Se não há nada em To, o UAS pode usar qualquer política para processá-lo.
- É recomendado ao UAS que processe a mensagem quando o To não for reconhecido, mas se ele resolver rejeitar pode responder com um 403 (Forbidden).
- Se o Request-URI não for suportado pelo UAS, pode ser respondido com 416 (Unsupported URI Scheme). Se o Request-URI não corresponder aos endereços que o UAS está habilitado a receber requisições, este responde com 404 (Not Found).
- Se não há tag no To, o UAS checa as transações. Se bater exatamente o From, Call-ID e CSeq e a requisição não bater com a transação é gerado 482 (Loop Detected).
- No caso do Require, se o UAS não entende o campo ele responde com 420 (Bad Extension). Este campo não pode ser usado em CANCEL e ACK para não-2xx.
Processamento de conteúdo, Requisições e extensões
- Se o UAS não entende algo, responde com um campo Accept, ou Accept-Encoding ou Accept-Language.
- Um servidor pode exigir extensões, mas deve verificar o campo Supported na requisição. Se ele não puder processar sem essa extensão e ela não for suportada pelo UAC, então retorna 421 (Extension Required).
- As condições acima atendidas passa-se para o método.
Gerando a Resposta
- Para uma requisição não INVITE, a UAS pode gerar uma resposta final o mais cedo possível.
- Respostas provisórias são mandadas (100 - Trying), e o timestamp deve ser copiado, e adicionado o delay de gerar a resposta.
- Os campos From, Call-ID, CSeq e Via (inclusive a ordem) são mantidos de acordo com a requisição.
- O campo To quando já possui tags deve ser copiado, se não possui o URI é mantido, mas podem ser adicionadas tags.
Stateless UAS
- Não guarda o estado de transição.
- Ele responde uma requisição normalmente, mas se tiver que guardar algum estado, ele descarta após enviar a resposta.
- Ele não tem camada de transação, recebem a resposta direto da de transporte.
- Este UAS não manda repostas provisórias (1xx), não retransmite respostas, ignora requisições ACK e CANCEL.
- As tags do To devem ser geradas de forma "stateless", de uma maneira que gera a mesma tag para a mesma requisição consistentemente.
Servidores de Redirecionamento
- Usados para diminuir a "responsabilidade" dos proxies.
- Quando o requisitante recebe uma resposta de redirecionamento, ele usa o URI desta.
- Tem um sistema de localização baseado em um banco de dados, associando um URI a várias localizações alternativas.
- Este servidor não emite SIP requests por si próprio. Quando recebe uma requisição não CANCEL, retorna um 3xx (redirecionamento) e rejeita este request. Para um CANCEL retorna 2xx (sucesso).
- Na resposta 3xx ele adiciona mais opções de tentativas em Contact.
- Existe um valor "expire" no contact que indica por quantos segundos o URI é válido. Quando não entende o valor do expire, usa 3600. Pode também existir um campo "Expire".
- Estes servidores ignoram as mensagens que eles não entendem.
Cancelando uma Requisição
- Um CANCEL indica que o processamento deve ser parado, e retornado um erro. Geralmente usadas para INVITEs que podem demorar a ser processados.
- Um CANCEL vai de hop em hop (proxies ou clientes podem mandá-la e ela desde de elemento por elemento)
Comportamento do Cliente
- Um CANCEL não deve ser usado para cancelar um não INVITE.
- Request-URI, Call-ID, To, a parte numérica de Cseq e From devem ser iguais ao da requisição, até as tags.
- O CANCEL tem um valor em Via que confere com o avlor mais alto de Via da requisição sendo cancelada, além do método ser especificado no CSeq.
- Os valores de Route precisam também ser incluídos se existirem, já Require não pode existir.
- Cancel não pode ser enviada se nenhuma resposta provisória foi recebida, nem se já recebeu a resposta final.
- Se demorar a resposta para o CANCEL a transação é considerada cancelada.
Comportamento do Servidor
- Um stateless apenas redireciona, enquanto o stateful responde e gera alguns CANCEL por sí próprio.
- O CANCEL só tem efeito em INVITES ainda sem resposta final. Se não for encontrada a transação a ser cancelada envia-se 481 (Call Leg/Transaction Does Not Exist).
- As tags To devem ser iguais na resposta à requisição original e na resposta ao CANCEL.
Pedidos de Registro
- Os proxys e redirects consultam um serviço de localização para encontrar o usuário.
- Eles associam um URI do endereço de registro com um ou mais endereços de contato, se o Request-URI bate com um endereço de registro são tentados os contatos.
- O Servidor registrador é responsável por receber o REGISTER, e montar as associações entre os endereços. É importante lembrar que estas funções são lógicas (proxy e registrador)
- O Registrador escreve, e os proxies e redirects leem os serviços de localização.
Construindo a requisição REGISTER
- Essas requisições podem adicionar ou remover ligações.
- Não existe estabelecimento de diálogo com esta requisição.
- Record-Route deve ser ignorado por um registrador.
- Os campos que precisam ser incluídos em um REGISTER (o Contact pode ser incluído):
- Request-URI: nomeia o domínio para o qual o pedido é destinado, onde não existe "userinfo" nem "@".
- To: contém o endereço de registro que deve ser criado ou modificado. Precisa ser um URI ou SIPS URI.
- From: Costuma ser o mesmo valor do To, ou seja contém o endereço de registro da pessoa responsável por pedí-lo. Só não é o mesmo de To quando o pedido é de um terceiro.
- Call-ID: É sempre o mesmo para um UAC.
- CSeq: Deve ser incrementado para garantir ordem.
- Pedidos de registro não podem ser reenviados até que o pedido anterior tenha sido respondido ou expirado.
- O parâmetro "action" ficou obsoleto e o "expires" indica por quanto tempo deveria ser válido. Estes são parâmetros do Contact.
- Segue uma figura com um exemplo de REGISTER:

Bindings
- Pode ser usado o campo Contact para registrar números de telefone ou email. Assim podem ser registrados vários "bindings", que são retornados em uma resposta 2xx no campo Contact.
- Tipicamente um UA só atualiza seus próprios endereços de contato.
- A expiração de um binding pode ser feita como descrito umas linhas atrás, com o parâmetro expires ou o campo Expires.
- O Parêmtro "q" pode indicar preferência entre os endereços de contato.
- O Expires "0" exclui um binding em um REGISTER. Se o Contact for "*" exclui todos. Os dois não podem ser usados simultaneamente.
- Um UA não pode atualizar bindings de outros usuários. Para atualizar basta enviar um REGISTER alterando o valor de expires ou Expires.
Clock, Buscando Registrar, Transmitindo requisições e respostas de erro
- Se houver um campo Date na resposta de um REGISTER, este pode ser usado para definir relógios internos.
- Para descobrir um registrador pode ser usada uma configuração, uma busca a partir do URI, ou por multicast
- Se a camada de transação retorna erro quanto ao recebimento de uma reposta para o REGISTER, não se deve tentar o mesmo registrador de novo. (Pode esperar um tempo e tentar no mesmo depois).
- Uma resposta 423 (Interval Too Brief), faz com que o UA coloque os intervalos de expiração exigidos no campo "Min-Expires" da resposta.
Processando Requisições REGISTER
- O registrador só aceita requisições REGISTER, e não pode gerar respostas 6xx (erro global).
- O registrador não inclui e nem analisa o campo Record-Route. Ele pode redirecionar requisições.
- As requisições devem ser processadas automaticamente e em ordem.
- O registrador quando recebe um registar segue as etapas:
- 1. Ele verifica o Request-URI e vê se tem acesso aos bindings deste domínio, se não, ele redireciona.
- 2. Processa os valores do campo Require.
- 3. Ele deve autenticar o UAC. Se não tiver mecanismos pra isso, usa o From como identidade.
- 4. Determina se o usuário autenticado está autorizado a modificar pedidos de registro. Se não retorna 403 (Forbidden) e para o processamento.
- 5. Extrai o endereço de registro do "To", e se não estiver no domínio retorna 404. Depois os parâmetros URI são removidos para virar uma forma canônica e o resultado serve como um índice.
- 6. Verifica se tem o campo Contact, se não pula para a etapa 8. Então ele observa os campos Contact e Expires (se possui "*" ou "0" desde que não seja ao mesmo tempo), verifica o Call-ID e o CSeq(maior do que o último).
- 7. Depois percorre cada endereço no campo Contact e atualiza conforme expires, Expires ou valor padrão. O registrador pode adotar tempos menores ou responder com erro caso o valor esteja abaixo do permitido, daí vem o Min-Expires na resposta. Este valor mínimo é para evitar requisições exageradas. Depois ele atualiza o binding ou adiciona se ele não existir (compara URI, Call-ID e se CSeq > CSeq anterior). Um servidor com erro pode retornar 500 (Server Error).
- 8. Finalmente ele retorna 200 (OK), com os bindings no Contact (incluindo o expires) e um campo Date.
Consultando Capacidades
- O método OPTIONS do SIP permite a consulta de capacidade. Assim o cliente pode descobrir extensões, conteúdo, métodos e outras coisas suportadas pelo UA requisitado.
- O alvo é identificado pelo campo Request-URI, se for um proxu, este campo não tem a parte do usuário.
- O Max-Forwards igual a zero em uma requisição OPTIONS faz com que um servidor possa responder independente do Request-URI.
- A camada de transação pode retornar um erro se a resposta demorar.
- Uma requisição OPTIONS pode ser enviada em um diálogo estabelecido.
Construção de Requisição OPTIONS
- Usa-se as regras padrões.
- O campo Contacts pode estar presente.
- Um campo Accept deve ser incluído para indicar o que o UAC deseja receber.
- Somente em um diálogo é garantido que as futuras requisições serão recebidas pelo servidor que respondeu ao OPTIONS.

Processamento de Requisição OPTIONS
- A resposta é a mesma de uma requisição INVITE (200 - OK), e pode ser usada para ver se um INVITE seria aceito.
- A resposta a uma OPTIONS por um servidor proxy não contém corpo.
- Os campos Allow, Accept, Accept-Encoding, Accept-Language e Supported DEVEM estar presentes em uma resposta OK para o OPTIONS, o servidor proxy omite o Allow.
- Contact e Warning podem estar presentes ou não.
- Corpo da mensagem pode ser incluído, descrevendo capacidades de mídia por exemplo.

Diálogos
- Representa uma relação SIP fim a fim.
- O ID do diálogo é obtido a partir do Call-ID e de uma tag local e uma remota (são iguais). A Tag local vem do campo To e a remota do campo From.
- Presentes no diálogo: ID, número de sequência (local e remoto), URI (local e remoto), destino, um flag booleano (secure), e um conjunto de rota.
Criação de um Diálogo
- É criado por respotas 101-199 ou 2xx. Podem ser criados por uma resposta não-final sendo chamado de "early".
Comportamento do UAS
- O UAS precisa copiar todos os valores de Record-Route na mesma ordem para a resposta e adicionar o campo Contact (onde coloca um URI ou URI SIPS para ser contactado a partir deste). A parte host desse precisa ser um IP ou FQDN do host.
- Este URI tem escopo global.
- Se a requisição chega sobre o TLS (Transport Layer Security) o flag secure fica TRUE.
- O destino das respostas deve ser definido como o Contact da requisição. Se não houver rotas em Record-Route, este campo é respondido como uma lista vazia.
- O número de sequência remoto é o valor de Cseq (da requisição) e o local é vazio. O URI remoto é o do campo From e o local do campo To.
Comportamento UAC
- O UAC deve fornecer um URI de escopo global no campo Contact. Se o Request-URI ou valor do campo mais alto do Route for um URI do SIPS, então o Contact tem que ser um URI SIPS.
- O flag secure é TRUE se a requisição foi enviada através do TLS e o Request-URI continha um URI SIPS.
- Deve difinir a lista de rotas, ou um conjunto vazio.
- O número de sequência local é o valor do CSeq, o remoto é vazio. O tag local vem do From, e o remoto vem do To, a mesma coisa com o URI.
Requisições dentro de um diálogo
- Os UAs podem mudar de função depois do diálogo estabelecido.
- Requisições podem contar Contact e Record-Route, mas só mudam estes valores se forem requisições para atualizar. O que em um INVITE anterior seria um re-INVITE. Um ACK não é requisição para atualizar alvo.
- Estas requisições só atualizam o URI do alvo remoto.
Comportamento UAC
Gerando a Requisição
- As informações de estado do diálogo são usadas nestas requisições.
- Se o número de sequência local for vazio, um valor inicial precisa ser escolhido.
- O valor do CSeq pode ser escolhido com base no tempo.
- Se o conjunto de rotas estiver vazio o URI do alvo remoto é colocado no Request-URI. O UAC não pode colocar o campo Route na requisição.
- Se o conjunto de rotas não estiver vazio e o primeiro URI tiver o parâmetro lr, o UAC inclui o campo Route com os valores do conjunto de rotas em ordem. O request-URI é igual ao anterior
- Se não tiver o lr, o primeiro URI do conjunto de rotas é que vai pro Request-URI. Depois o Route é construído com o resto, sendo o último valor o URI do destino remoto.

- O campo Contact deve estar sempre presente. O URI deve ser o mesmo, e se secure for TRUE deve ser um URI do SIPS. O resto do procedimento é o padrão já descrito lá atrás.
Processando as Respostas
- As respostas são recebidas da camada de transação.
- Uma resposta 3xx para uma requisição dentro do diálogo tem o mesmo processamento se fosse fora.
- Uma resposta 2xx, indica a substituição do URI alvo pelo URI do campo Contact desta resposta.
- Para timeout ou respostas do tipo: 481 (Call/Transaction Does Not Exist) ou 408 (Request Timeout), o diálogo deve ser encerrado (mandando BYE).
Comportamento UAS
- Estas requisições são atômicas.
- O UAS recebe da camada de transação a requisição, e se existir uma tag no To, computa o identificador do diálogo e compara com os existentes, se bater, identifica uma requisição no meio do diálogo que é processada igual a fora de um diálogo.
- Se existe a tag do To, mas não bate o identificador, pode ser erro de roteamento ou este próprio UAS reiniciou/quebrou e perdeu as informações. Ele pode rejeitar ou aceitar, se rejeitar ele manda 481 (Call/Transaction Does Not Exist).
- Requisição que não muda estado, tipo OPTIONS são processadas como se estivessem fora do diálogo.
- Se o número de seq é vazio ele recebe o valor de CSeq da requisição. Se não for vazio e o número da requisição for inferior retorna 500 (Server Internal Error).
- O UAS atualiza o URI alvo a partir do campo Contact se ele existir em uma requisição de atualização.
Terminando um Diálogo
- O método BYE termina uma sessão e o diálogo associado a ela.
- Uma resposta final não-2xx encerra todos os diálogos early's.
Iniciando uma Sessão
- Uma sessão (jogo, áudio, vídeo) é iniciada com um INVITE. Um convite aceito por um UAS tem resposta 2xx, ou antes de terminar pode enviar respostas provisórias 1xx.
- Para cada resposta que recebe o UAC deve gerar um ACK. Uma resposta 2xx cria a sessão e também o diálogo.
- Um UA que suporta INVITE também deve suportar BYE, ACK e CANCEL.
Processamento do UAC
Criando o INVITE inicial
- Este INVITE é uma requisição fora do diálogo processada como já foi explicado.
- Devem estar presentes Allow e Supported.
- O Accept pode estar presente, indicando os Content-Types. O Expires também pode aparecer, e se acabar este tempo sem resposta, o UAC gera um CANCEL a este INVITE.
- Subject, Organization, User-Agent e um corpo da mensagem podem ser adicionados.
- Existe o modelo ofera/aceita, onde a sessão é "ofertada" com certas características, e aceita pelo outro UA, sendo que cada uma destas é um diálogo. Regras para este modelo:
- A oferta (offer) deve estar no INVITE e na resposta (2xx). O "aceite" também pode estar nas respostas provisórias.
- Se a oferta está na resposta, o aceite deve estar no ACK.
- Depois de um aceite o UAC pode fazer mais ofertas, desde que todas as anteriores foram aceitas. Já um UAS não pode gerar ofertas subsequentes.
- O SDP precisa ser suportado pelos UAs para descrever as sessões.
- O valor de Content-Disposition deve ser "session". Se este campo não existe application/sdp no Content-Type indica uma sessão, outros tipo de conteúdo implicam em "render".
Processando Respostas a INVITE
- No UAC se não chegar a resposta pode acontecer um 408 (Request Timeout).
- Respostas 1xx
- Estas podem gerar um diálogo early, que só existe quando o UAC quer enviar uma requisição antes do INVITE inicial se completar.
- Respostas 3xx
- Esta resposta pode contar novas opções em Contact que o UAC pode tentar.
- Respostas 4xx, 5xx e 6xx
- Encerram todos os diálogos early, e podem contar informações sobre o erro em um local descrito em Contact. A transação INVITE fica completa e um ACk é gerado.
- Respostas 2xx
- Múltiplas respostas 2xx podem chegar em resposta a um INVITE, cada uma representa um diálogo distinto. Cada resposta tem seu ACK, com credenciais correspondentes ao INVITE, se for um offer o ACK carrega um aceite, se não for aceitável, envia o ACK depois o BYE.
- Os ACKs vão direto pra camada de transporte. Quem trata a retransmissão é o núcleo UAC e não a camada de transação.
- O UAC considera um INVITE completado depois de um tempo após a primeira 2xx. Se chegar outra 2xx depois o UAC pode não querer continuar com o diálogo e enviar assim um BYE.
Processamento do UAS
Processamento do INVITE
- Se os procedimentos explicados lá atrás para processar uma requisição derem certo, seguem depois os seguintes passos:
- 1. Se houver Expires, o UAC inicia um timer. Se ele encerrar antes do fim do processamento responde com 487 (Request Terminated).
- 2. Uma requisição no meio do diálogo pode alterar a seção.
- 3. Se houver tag no To e o ID do diálogo não bater, o UAS pode ter reiniciado ou quebrado.
- Um usuário pode receber múltiplos invites, e assim o UAS pode detectar as duplicações (com ajuda do SDP).
- Um INVITE sem descrição da sessão está pedindo uma oferta do UAS, que deve ser enviada no 2xx.
- Se um UAS não puder responder de imediato, pode mandar repostas provisórias (entre 101 e 199), mas estas não são entregues de forma confiável.
- O UAS pode pedir uma extensão do tempo para responder ao invite.
- Se o UAS redirecionar a chamada envia uma resposta 3xx com o campo Contact.
- Um UAS que não tem mais espaço para sessões envia um 486 (Busy Here), e um que não seja capaz de atender a oferta envia 488 (Not Acceptable Here), sendo que esta deve incluir um campo Warning explicando o motivo.
- A transação é destruída com a resposta final, então respostas 2xx é passada periodicamente ao transporte para possíveis retransmissões (até chegar o ACK). Isso independe do protocolo da camada abaixo.
- Se o ACK não chega a sessão é encerrada com um BYE (o tempo segundo a RFC é 64*T1 - T1 será definido depois)
Modificando uma sessão existente
- É diferente de atualizar/modificar um diálogo, aqui podem ser redefinidas portas e até fluxos de mídia. Para modificar uma sessão envia-se outro INVITE dentro do mesmo diálogo.
- Um único re-INVITE pode modificar sessão e diálogo ao mesmo tempo.
- Em caso de falha as mensagens devem ser enviadas após intervalos de tempo aleatórios, para não inundar a rede, em casos que re-INVITEs ou BYEs são gerados automaticamente.
Comportamento UAC
- Aqui usa-se o mesmo modelo oferta/aceite (offer-answer), e uma descrição completa da sessão deve ir junto.
- Se não houver descrição da sessão, espera-se o offer na resposta 2xx. Se houver capacidade para número de versão, o proponente deve atualizar este.
- Os campos To, From, Call-ID, CSeq e Request URI de um re-INVITE seguem o mesmo padrão das requisições de um diálogo existente.
- o UAC pode não adicionar um campo Alert-Info.
- Um re-INVITE só gera uma resposta final.
- Não se pode gerar um INVITE enquanto outro está em curso. Mas transações regulares e INVITEs não tem esse problema um com o outro.
- Uma resposta não 2xx para um re-INVITE mantém a sessão inalterada, a não ser que seja por timeout ou 481 (Call/Transaction Does Not Exist), ou uma 408 (Request Timeout), aí o diálogo é encerrado.
- Se o UAC receber a resposta 491, deve ser iniciado um timer:
- Se o UAC é dono do Call-ID o valor é aleatoriamente escolhido entre 2.1 a 4 segundos em intervalos de 10ms.
- Se ele não for dono o valor é entre 0 e 2 segundos.
- Se o timer acabar um re-INVITE deve ser tentado de novo, a não ser que já desligou a chamada com um BYE.
Comportamento do UAS
- Um UAS que recebe um segundo INVITE enquanto processa um outro, e com um CSeq inferior retorna 500 (Server Internal Error) ao segundo e inclui um campo Retry-After com um valor entre 0 e 10 seg.
- Um UAS que recebe um INVITE enquanto aguarda a resposta de um que ele enviou retorna 491 (Request Pending)
- Se o UAS gerar 2xx e não receber ACK, depois envia BYE.
- O UAS fazendo uma oferta precisa sobrepor a descrição da sessão anterior e colocar as mídias que ele suporta.
Terminando uma Sessão
- O BYE encerra uma sessão e só pode ser enviado em um diálogo.
- Um BYE que encerra um diálogo encerra todas as sessões associadas.
- Um UA chamado não pode enviar BYE em um early.
- o UA chamado só pode encerrar um diálogo se receber o ACK para o 2xx.
- Para um INVITE em curso (respostas não-2xx) usa-se CANCEL.
Requisição BYE
Comportamento UAC
- o UAC passa a requisição BYE para a transação não INVITE.
- Se o BYE receber 481 (Call/Transaction Does Not Exist) ou 408 (Request Timeout) considera-se a sessão encerrada.
- O BYE é construído como qualquer outra requisição dentro de um diálogo
Comportamento UAS
- O UAS compara a requisição BYE, para ver se o diálogo existe (o BYE tem que ter tags)
- Se não existir retorna 481.
- O UAS encerra a sessão desde que não seja multicast (mais usuários)
- O UAS deve gerar uma resposta 2xx ao BYE.
- O UAS deve responder as requisições pendentes, é recomendado que a resposta seja 487 (Request Terminated)
Comportamento do Proxy
- Roteiam requisições e respostas SIP.
- Respostas percorrem o caminho inverso das requisições.
- É uma função lógica, e pode responder mensagens mal formadas.
- Se for o destino de um requisição, comporta-se como um UAS.
- Um stateless só encaminha a mensagem sem guardar informações, diferente do stateful
- Um proxy pode passar de stateful para stateless, desde que nada o "segure" no primeiro.
- Não deve mandar mensagens CANCEL.
Proxy Stateful
- Este tem uma transação servidor associada a uma ou mais de clientes por um componente de processamento, conhecido como núcleo proxy.
- Requisições entrantes -> transação servidor.
- Requisições que saem -> transação cliente.
- As respostas percorrem o caminho inverso.
- O proxy precisa se comportar como um UAS quando envia provisórias
- Passos no proxy:
- 1. Validar a requisição
- 2. Pré-processar informação de roteamento.
- 3. Determinar alvo(s)
- 4. Encaminhar a requisição para cada alvo
- 5. Processar as respostas

(1)Validação da Requisição
- Para validar o proxy segue os passos:
- 1. Sintaxe Razoável
- 2. Esquema URI
- 3. Max-Forwards
- 4. Detecção de Loop (Opcional)
- 5. Proxy-Require
- 6. Proxy-Authorization
- Se uma dessas falhar o proxy como um UAS envia um código de erro
- O proxy não pode tratar requisições mescladas como erro
1.Sintaxe Razoável
- Campos não fundamentais não fazem a requisição ser rejeitada, mas não são alterados.
- Campos não conhecidos também não resultam na rejeição
2.Esquema URI
- Se o Request-URI contém um esquema não conhecido, rejeita-se e responde com 416 (Unsupported URI Scheme)
3.Max-Forwards
- Se não existe o campo, não há rejeição
- Se o valor for zero, rejeita, a não ser que seja OPTIONS que pode ser respondido pelo proxy.
4.Loops
- Se o campo via for igual de um anterior ele está em loop.
- Ele pode calcular o branch e comparar com via (espiral !=, loop ==).
- Resposta: 482 (Loop Detected)
5.Proxy-Require
- Informa extensões que não precisam ser processadas pelo proxy, a menos que ele entenda.
- Se esse campo tiver tags options que não são entendidos, retorna 420 (Bad Extension) e inclui na mensagem um campo Unsupported.
6.Proxy Authorization
- Se exigir credenciais a requisição precisa ser inspecionada, depois vai ser explicado.
(2)Pré-processamento de informação de rota
- Se o valor do Request-URI tiver um valor que o proxy já colocou em Record-Route, ele precisa substituir o Request-URI pelo último valor do campo Route, e remover este valor do Route.
- Se existe o maddr no Request-URI, e bate com os endereços do proxy, ele retira o maddr ou parâmetro transport da requisição (caso a porta e transporte sejam os que estão sendo usados)
- Se a porta ou transporte for diferente, encaminha-se ao que foi indicado.
- Se o primeiro valor de Route indica esse proxy, ele remove esse valor.
(3)Determinação de alvos
- Se existir o maddr o Request-URI é o URI alvo, mesmo que o Request-URI não esteja no domínio do proxy.
- Se não existe maddr o Request-URI pertence ao proxy, e pode ser redirecionado por QUALQUER método (como o serviço de localização)
- Se não der pra determinar a rota com o Request-URI retorna 485 (Ambiguous), com um campo Contact para novas tentativas.
- Informações na requisição ou ambiente atual podem interferir na redireção.
- Um proxy só pode alterar um Request-URI se ele é responsável por ele.
- URI's só podem ser acrescentadas ao conjunto alvo uma vez, e se um recurso do Request-URI é um pelo qual este proxy é responsável.
- O URI ou SIPS URI do próximo salto é adicionado ao Route.
- Se o conjunto destino estiver vazio -> 480 (Temporarily Unavailable)
- Se existe um recurso não suportado pelo proxy em Request-URI -> 404
(4)Encaminhando a Requisição
- Como existe um conjunto de destino o proxy stateful pode enviar para cada um em série ou paralelo.
- Pode ser usado o parâmetro qvalue de Contact, do maior para o menor.
- o proxy stateful tem que ter um mecanismo para manter o conjunto de destinos para manipular as respostas
- Para cada destino, seguem as etapas:
- 1. Fazer uma cópia da requisição recebida
- 2. Atualizar o Request-URI
- 3. Atualizar o campo-cabeçalho Max-Forwards
- 4. Opcionalmente adiciona um valor no campo-cabeçalho Record-Route
- 5. Opcionalmente adiciona campos-cabeçalhos adicionais
- 6. Pós-processa informação de roteamento
- 7. Determina o endereço, porta e transporte do next-hop
- 8. Adiciona um valor no campo-cabeçalho Via
- 9. Adiciona um campo-cabeçalho Content-Length se necessário
- 10. Encaminha a nova requisição
- 11. Define o timer C
1.Copiar Requisição
- Todos os campos são copiados em ordem, sem adição, nem modificação do corpo da msg.
2.Request-URI
- O Request-URI da cópia é substituído pelo URI destino, parâmetros não permitidos são removidos.
3.Max-Forwards
- Decrementa o valor detse campo por 1 se existir.
- Se não existir, adiciona com valor 70.
4.Record-Route
- Se este proxy quer ser caminho para futuras requisições ele grava em Record-Route, antes dos outros existentes.
- Se ele não adicionar nada no Record-Route, em requisições de um mesmo diálogo ele pode sair do caminho se um endpoint que falhou reconstituir o diálogo.
- Esta escolha é independente (de adicionar no Record-Route) nos proxys.
- O URI adicionado tem que ter o parâmetro lr, e não ter o tranport, a não ser que este proxy garanta que o próximo elemento suporte isso.
- Este proxy precisa se limitar a uma implementação do SIP por causa dos outros elementos.
- Se o Request-URI é um URI SIPS e o campo mais alto de Route também, então o URI adicionado deve ser um URI SIPS.
- Podem ser colocados parâmetros em Record-Route
- o URI adicionado só tem que ser válido até o fim do diálogo.
- Só deve adicionar em Record-Route se for necessário, porque isso causa processamento mais lento.
5.Campos Adicionais
- Neste ponto a cópia pode receber quaisquer campos adicionais apropriados.
6. Pós-processamento das informações de roteamento
- Se o proxy quiser que uma requisição passe por um conjunto de proxys específicos ele adiciona em Route, desde que estes prxys sejam menos rígidos, o que só pode ser conhecido em um mesmo domínio administrativo.
- No caso de um proxy específico pode colocar até a porta e o transporte, a menos que existe o Route, aí isto não pode ser usado.
- Se o primeiro valor do Route (se existir) não tem lr, adiciona o Request-URI no fim do Route e remove este primeiro valor e coloca no Request-URI (encaminhar para rígido)
7.Determinar endereço, porta e transporte do next-hop
- O mecanismo de encaminhar por um next-hop específico não é recomendado, e só pode ser usado se houver certeza de menos rigidez neste.
- O proxy precisa tentar entragar a mensagem com a primeira tupla em Route, e formatar a mensagem quando apropriado, e enviar a requisição usando uma nova transação cliente.
- O valor branch (em Via - próximo tópico) precisa ser diferente para cada tentativa.
- Se nenhum do conjunto responder retorna 408 (Request Timeout)
8.Adicionar um valor no campo Via
- Cada proxy computa o seu próprio parâmetro branch, que precisa ser adicionado no campo Via antes dos valores já exisstentes.
- O branch é diferente para cada instância de uma requisição.
- Se o proxy detecta loops o branch é dividido em 2, a primeira parte segue a regra, a segunda é para a detecção.
- A segunda parte pode ser baseada em campos, para que requisições em espiral passem (Route, Proxy-Require e Proxy-Authentication podem mudar por exemplo em expirais, mas não em loops)
- O método não pode ser usado no cálculo do branch.
9.Adicionar Content-Length
- Se a requisição for enviada usando um transporte baseado em fluxo, o campo Content-Length deve ser adicionado.
10.Encaminhar a Requisição
- Cria-se uma nova transação cliente e instrui a transação a usar os valores determinados no passo 7.
11.Timer C
- O timer tem que ser maior que 3 min e deve estar presente em cada transação cliente, para casos em que não há resposta final.
(5)Processando Resposta
- Confere a resposta com as transações clientes, se não existir relação, processa como um proxy stateless.
- Se existir passa para a transação cliente correspondente.
- Os passos para passar da trabsação cliente para a camada proxy:
- 1. Busca o contexto apropriado
- 2. Atualiza o timer C
- 3. Remove o Via mais alto
- 4. Adiciona a resposta ao contexto de resposta
- 5. Verifica se a resposta deve ser encaminhada imediatamente.
- 6. Se necessário, escolhe a melhor resposta final no contexto.
- Para cada resposta seguem os passos:
- 7. Agregar valores nos campos-cabeçalhos Authorization se necessário.
- 8. Reescrever valores no Record-Route (opcional)
- 9. Encaminha a resposta
- 10. Gera requisições CANCEL necessárias
1.Busca de contexto
- O proxy localiza o "contexto resposta" que ele criou antes de encaminhar a requisição.
2.Atualiza timer C
- O timer é ressetado para cada resposta provisória que recebe. (> 3min)
3.Via
- Remove o valor mais alto do campo, se não sobrar valores este proxy é o destino.
4.Adiciona Resposta ao Contexto
- Respostas finais são armazenadas no contexto até que a transação servidor gere a resposta associada a esse contexto.
- O contato não pode ser removido da resposta.
- Se o proxy colocar um URI não SIP e receber 416 (Unsupported URI Scheme) como resposta, ele deve colocar um URI SIP no lugar daquele.
5.Verifica Resposta para encaminhamento
- Respostas provisórias e 2xx devem ser encaminhadas imediatamente.
- 6xx não precisa ser encaminhada imediatamente. O proxy stateful deve cancelar todas as transações clientes pendentes.
- Uma resposta 2xx (a um INVITE) deve ser enviada após uma resposta final ter sido enviada na transação servidor.
- Um proxy não pode enviar a resposta 100 (Trying).
6.Escolhendo a melhor resposta
- Se não houver nenhuma resposta no contexto, o proxy envia 408 (Request Timeout).
- Do contrário ele precisa escolher a melhor. Primeiro as 6xx, se não houver as outras (a mais baixa). Desta classe ele escolhe qualquer resposta, com algumas preferências.
- Uma resposta 503 (Service Unavailable) não deve ser enviada ao upstream, mas uma 500 no lugar. A menos que ele saiba que as próximas requisições também vão gerar 503.
- Respostas 3xx-6xx são entregues de salto a salto.
- O proxy não pode modificar uma tag To de um resposta na qual a requisição tinha uma tag. Assim como em respostas 1xx e 2xx ele não pode adicionar a tag em situação nenhuma (a não ser que seja a que já estava na requisição).
- O proxy não pode gerar respostas provisórias por conta própria, para isto ele pode usar um UAS que partilha o mesmo elemento que ele.
7.Agregando valores no Authorization
- Para respostas 401 (Unauthorized) ou 407 (Proxy Authentication Required) o proxy pega todos os campos WWW-Authenticate e Proxy-Authenticate do contexto a adiciona à resposta sem modificação.
8.Record-Route
- O proxy pode escolher reescrever um valor previsto que esteja nesse campo.
- De um não-TLS para um TLS -> URI SIP
- De um TLS para um não-TLS -> URI SIPS
- Pode ser usado um identificador único no URI, para identificá-lo na hora de reescrever em espirais.
- As vezes as respostas podem não conter Record-Route.
9.Encaminhar Resposta
- O proxy não pode: mexer no corpo da msg, não pode remover nada dos campos (a não ser do Via), não pode remover qualquer parâmetro "received".
- O proxy passa para a transação servidor, se essa não responder, envia como stateless, direto pelo transporte servidor.
- O contexto resposta precisa ser mantido até o fim de todas as transações associadas.
10.Gerar CANCEL's
- Gera-se CANCEL para todas as transações clientes após uma resposta final, ou para as associadas com uma resposta 6xx.
Processando o Timer C
- Se o timer disparar sem resposta provisória envia-se a resposta 408 (Request Timeout). Se houver resposta provisória, envia um CANCEL. Ele deve ser ressetado.
Tratando erros de transporte
- Se o transporte identificar um erro ao tentar transmitir, o proxy trata isso como 503 (Serviço Indisponível).
- Se o proxy é notificado com um erro quando encaminha uma resposta ele simplesmente a descarta.
Processando CANCEL
- O proxy stateful pode gerar um CANCEL para qualquer requisição que ele tenha gerado, e cancelar as transações clientes associadas quando recebe um.
- O proxy pode gerar CANCEL com base em Expires.
- Quando recebe CANCEL, se bate com um contexto resposta existente, ele retorna 200 (ok). Se não ele encaminha o CANCEL sem guardar estado.
Proxy Stateless
- Se comporta como um encaminhador.
- Um stateless é proibido de gerar respostas 100 ou provisórias, ele não transmite mensagens por conta própria.
- Os passos explicados 1, 2, 3, 4 precisam ser seguidos pelo stateless, com as excessões:
- Ele só escolhe um destino do conjunto destino.
- O parâmetro branch deve ser o mesmo em retransmissões (mas continua sendo único)
- A requisição é enviada direto para o transporte (ao invés da transação cliente)
- Para variações no tempo no estado de configuração, pode-se optar por um comportamento stateful.
- Não há processamento especial para CANCEL.
- O passo (5) do stateful não vale aqui, o stateless pega o campo Via, olha se o primeiro endereço corresponde a ele, remove e repassa. Se não ele descarta.
Processamento do Route no Proxy
- Se não existir uma política local que comprometa, seguem os passos:
- 1. Inspeciona o Request-URI e o altera usando os serviços de localização se este pertencer ao seu domínio, se não, não há alterações no Request-URI.
- 2. Olha o URI do campo mais alto de Route, se for ele, remove-o.
- 3. A requisição é encaminhada para o Route mais alto, e se não existir para o Request-URI.
Exemplos e Cenários
- Começa na página 118 até 122 da RFC.
Transações
- Uma transação é uma requisição, mais todas as respostas pra ela.
- Em um invite a transação só inclui o ACK se a resposta final não for um 200 (ok).
- As transações cliente e servidor são funções lógicas.
- Proxys stateless não tem essas transações.

- A transação cliente recebe as respostas e filtra as retransmissões, ou respostas anuladas, além de gerar o ACK em resposta a uma 2xx. (Passa as respostas ao TU)
- A servidor é igual só que para requisições, e ela é que absorve o ACK.
- A retransmissão de respostas 2xx é responsabilidade do núcleo UA.
Transação Cliente
- Ela executa suas funções através de uma máquina de estado.
- Quando o TU quer uma nova transação, ele cria a transação cliente e passa para ela a requisição SIP (com IP, porta e transporte)
- Existem duas transações clientes, a INVITE e a não-INVITE. O ACK passa direto do TU para o transporte, e não entre em nenhum dos tipos.
Transação INVITE Cliente
- Esta transação consiste em um tree way handshake. Em caso de UDP a retransmissão é padronizada em 500ms(T1).
- Respostas provisórias cessam retransmissões da TC, mas estas não são em transporte confiável.
- Quando é TCP a resposta final é mandada só uma vez.
- Um timer B de valor 64*T1 é iniciado de qualquer forma para tratar timeouts de transação.
- O timer A que cuida de retransmitir a requisição tem tempo T1, que dobra a cada retransmissão. Essas retransmissões só são feitas enquanto estiver no estado calling.
- O T1 é uma estimativa do RTT.
- Se o timer B disparar ainda no estado calling a transação avisa o TU.
- Se receber uma resposta provisória no estado "calling" passa-se para o estado "Proceeding". Neste estado para a retransmissão, e todas estas mensagens provisórias devem ser passadas ao TU.
- Se estiver em um dos dois estados e receber uma resposta 3xx até 6xx a transação vai para o estado "Completed" e envia um ACK mesmo que o transporte seja confiável. Um timer D é disparado com valor de pelo menos 32s para não confiável e 0s para confiável, que é o tempo em que permanece neste estado.
- Uma recepção de uma retransmissão de uma resposta final enquanto está no "Completed" exige um novo ACK, mas essa resposta não é passada ao TU.
- Se o timer D dispara no Completed a transação deve ir para Terminated.
- Nos estados Calling e Proceeding uma resposta 2xx passa para o estado Terminated e a resposta é passada ao TU. Um UAC responde com ACK, já um proxy com 200 (OK).
- A camada de transação do cliente deve ser destruída quando ela entra em terminated.

Contrução da requisição ACK
- Os ACKs aqui descritos são os que são gerados na transação cliente.
- Os campos Call-ID, From e Request-URI são iguais ao da requisição.
- O Campo To é igual ao da resposta sendo reconhecida.
- O Campo CSeq deve ser igual ao da requisição, mas o method deve mudar para "ACK".
- O Via deve possui o valor no topo do Via da requisição original.
- Se a resposta possui Route, esse deve aparecer no ACK também.
- Não é recomendado que ACKs para não-2xx possuam corpo.

Transação não-INVITE Cliente
- Não fazem o uso de ACK.
- Modelo requisição-resposta.
- Requisições são retransmitidas em intervalo T1, que dobra até atingir T2.
- Quando uma resposta provisória é recebida, as retransmissões são em T2.
- Retransmissões da requisição continuam mesmo após uma resposta provisória, para garantir a entrega confiável.
- Não existe tratamento especial para uma resposta 2xx.
- O estado Trying define um timer F de 64*T1, e se não for um meio confiável um timer E que dispara em T1 s é definido (que dobra até T2).
- Se uma resposta 2xx for recebida, passa-se para Completed. Se uma resposta provisória for recebida, passa-se para Proceeding. Se o timer F disparar ocorreu timeout e passa para Terminated.
- Mo estado Completed um timer K é definido com T4 (não confiável) ou 0 (confiável), o valor padrão de T4 é 5s, e se ele dispara passa-se para o estado "Terminated". Este estado (Completed) existe para receber qualquer retransmissão de resposta adicional.

Respostas às Transações Clientes
- Uma resposta deve ser direcionada a uma transação, comparando o method (o mesmo da requisição) e o branch.
- Em multicast, o branch de cada resposta é o mesmo, apesar da tag de To mudar, mas apenas a primeira resposta é recebida, as outras são consideradas retransmissões.
Tratando Erros de Transporte
- Se o transporte falhar, a transação cliente deve informar ao TU a falha e passa-se direto ao estado Terminated.
Transação Servidor
- Entrega de requisições ao TU e transmissão confiável de respostas.
Transação INVITE Servidor
- Quando uma transação servidor é criada para um requisição ela entra no estado Proceeding. Neste ponto deve ser gerada uma resposta 100 (Trying), a menos que se saiba que o TU vai gerar uma resposta provisória dentro de 200ms, aí o 100 é opcional.
- Se receber uma requisição retransmitida (no estado Proceeding), reenvia a última resposta recebida do TU.
- Se durante esse mesmo estado a transação servidor receber do TU uma resposta 2xx ela precisa ser passada ao transporte, e passa-se ao estado Terminated. Retransmissões de 2xx são tratadas pelo TU.
- Se o TU passa uma resposta de 300-699 para a transação, ela vai para o estado Completed. Para transaportes não confiáveis um timer G é definifo com T1 seg.
- No completed o timer H também é definido (64*T1) para abandonara as retransmissões e passar ao estado Terminated (e indica ao TU que ouve falha), já o G é para retransmitir e duplica até no máximo T2.
- Um ACK recebido no estado Completed, passa para o estado Confirmed e cessam as retransmissões.
- O propósito do Confirmed é absorver todos ACKs adicionais que chegam. Um timer I igual a T4 é iniciado, e se disparar passa-se ao estado Terminated, I é zero se o transporte for confiável.
- Quando chega em Terminated a transação deve ser destruída imediatamente.

Transação não-INVITE Servidor
- Essa transação é inicializada para requisições diferentes de INVITE ou ACK, e começa no estado Trying. Uma vez nesse estado, retransmissões adicionais de requisição são descartadas.
- Se receber uma resposta provisória do TU passa para Proceeding. Qualquer resposta provisória recebida nesse estado á passada para o transporte, e se receber retransmissões de requisição, reenvia a última resposta provisória. Se receber do TU uma resposta final 200-699 passa-se para o estado Completed.
- No estado Completed cria-se um timer J de 64*T1 seg para transportes não confiáveis. Sempre que uma retransmissão de requisição for recebida, repassa a resposta final. Qualquer outra resposta final passadas pelo TU devem ser descartadas nesse estado. Se J disparar passa-se para Terminated.
- Como sempre, deve ser destruída a transação no estado Terminated.

Conferindo requisições às Transações Servidor e Erros de transporte
- Para conferir uma requisição com uma transação:
- Obs: Se o branch começa com "z9hG4bK" a requisição foi gerada por uma transação cliente, e assim será único ao longo de todas as transações desse cliente.
- Confere o branch, o parâmetro sent-by do Via e o método da requisição (exceto para ACK)
- Se não existir o parâmetro branch, os outros campos são usados, como tag de To e From, Call-ID e CSeq, além de Via.
- Em caso de erro no tranporte, tenta-se fazer um backup da resposta e se os procedimentos falharem, comunica ao TU e encerra.
Transporte
- Responsável pela transmissão real, sobre TCP, SCTP...
- Conexões indexadas por: endereço IP, porta e protocolo de transporte.
- São duas conexões entre os proxys, uma para enviar outra para receber.
- As conexões precisam (é recomendado) ficar abertas pelo menos um tempo depois após a última mensagem.
- Todos elementos SIP precisam implementar TCP e UDP.
Clientes
- O usuário da camada de transporte passa ao transporte cliente o IP, porta, transporte e possivelmente TTL.
- Se uma requisição está a 200 bytes do MTU, ou se ela for maior que 1300 bytes e o MTU for desconhecido, então deve-se usar o TCP (controle de congestionamento). Se não der certo com o TCP reenvia usando UDP.
- Em requisições multicast deve adicionar o parâmetro maddr no Via com o endereço multicast e adicionar o parâmentro ttl p/ IPv4 com valor l.
- Antes de enviar a requisição o transporte cliente insere um valor do campo "sent-by" no Via que contém endereço IP ou nome do host e a porta. Se a porta não for especificada usa-se o padrão (5060 - UDP, TCP e SCTP; 5061 - TLS)
- Geralmente é usada a mesma conexão (no caso confiável) para enviar a resposta, se não der, o servidor pode tentar uma nova conexão, aí a porta em sent-by será usada. Pode acontecer de usar outra porta, assim o cliente deve estar preparado.
- Quando recebe a resposta, se o sent-by não é um valor configurado para inserir requisições, descarta-se a mensagem silenciosamente.
- O mecanismo de conferir a resposta com uma transação já foi descrito.
Servidores
- Qualquer IP, porta e combinação que possa ser retornada em uma consulta DNS, o servidor deve estar preparado para atender.
- É bom sempre ouvir as portas padrões, e escutar na porta UDP também o TCP, já que se a msg for grande ela pode vir em TCP.
- O servidor adiciona um parâmetro received em Via, que contém o endereço origem pelo qual o pacote foi recebido.

- O transporte tenta bater requisição com transação e se não bate manda ao núcleo, que decide se cria uma nova ou não (como no caso do ACK).
- O transporte servidor usa o campo mais alto do Via para mandar uma resposta.
- No caso de transporte confiável, usa-se a conexão se ela ainda existir, se não, tenta abrir conexão com o endereço IP de received e da porta em sent-by.
- Se o Via contém o maddr a resposta é encaminhada ao endereço listado lá, usando a porta sent-by (ou a padrão se essa não for especificada). Se for multicast usa o TTL indicado mo parâmetro, ou com TTL igual a l se esse parâmetro não existir.
Enquadramento e Tratamento de Erro
- Se existe o campo Content-Lenght no UDP, se bytes do pacote de transporte passarem esse tamanho são descartados esses bytes, se forem menores é considerado um erro. Se não tem o campo, o corpo da mensagem termina ao final do pacote de transporte.
- O resultado de falhas no transporte são erros ICMP, o qual são geralmente informados ao usuário de transporte (menos source quench e TTL exceeded). No caso confiável, se não conseguir conectar, o usuário de transporte também é informado.
Componentes Comuns de Mensagem
= URI do SIP e SIPS
- Um URI do SIPS especifica que o recurso seja contactado de forma segura. Um URI SIP pode ser atualizado para SIPS.
- Seguem padrões parecidos com URL.
- Exemplo de URI do SIP:
- sip:user:password@host:port;uri-parameters?headers
- O URI do SIPS é igual só que escreve "sips" no lugar de "sip".
- Os significados:
- user: Indicador de um recurso particular, onde host se refere frequentemente a um domínio.
- password: o uso não é recomendado, mas é a senha associada ao usuário.
- host: que fornece o recurso SIP.
- port: número da porta aonda a requisição deve ser enviada.
- uri-parameters: parâmetros que afetam uma requisição construída a partir da URI. São da seguintes forma: par-name = par-value
- Um nome de parâmetro não pode aparecer mais de uma vez
- Mecanismos SIP precisam ignorar parâmetros que eles não entendem.
- Parâmetros: transport (mecanismo de transporte a ser usado), maddr (endereço do servidor a ser contactado, ttl (time-to-live do pacote multicast UDP e só é usado se maddr for um endereço multicast), method, lr (indica que o elemento responsável por este recurso implementa os mecanismos de roteamento)
- Por exemplo, especificar uma chamada para alice@atlanta.com usando multicast para 239.255.255.1 com valor TTL 15, o URI seguinte seria usado:
- sip:alice@atlanta.com;maddr=239.255.255.1;ttl=15
- O parâmetro URI existe para distinguir nomes de usuários e números de telefone (que podem aparecer antes do @)
- Headers: campos cabeçalhos a serem incluídos em uma requisição.
- Tabela: A coluna externa descreve URI's que aparecem em qualquer lugar fora de uma mensagem SIP, por exemplo, em página Web ou cartão de visita. Entradas marcadas com "m" são obrigatórios, aqueles marcados com "o" são opcionais, e aqueles marcados com "-" não são permitidos. Elementos que processam URI's DEVEM ignorar quaisquer componentes não permitidos se estiverem presentes. A segunda coluna indica o valor padrão de um elemento opcional, se não estiver presente. O "--" indica que o elemento nem é opcional, e nem possui valor padrão.

- Para escapar caracteres usa-se o modelo % HEX HEX. Por exemplo "j@son" vira "j%40son".
- Exemplos de URIs:

Comparação de URI
- Regras:
- Um URI SIPS e um URI SIP nunca são equivalentes.
- Comparação do userinfo é case sensitive.
- A ordenação dos campos não é significativa.
- O IP resultado de busca DNS não bate com o nome do host.
- Para dois URIs serem iguais: usuário, senha, host e porta devem ser iguais.
- Um URI que omite um parâmetro não é igual um que declara o parâmetro no valor padrão. Isso vale pra porta, transport-parameter, ttl-parameter, o user-parameter e method.
- Para comparar os componentes uri-parameter:
- Qualquer uri-parameter aparecendo em ambos URI's precisam bater.
- Os componentes user, ttl, parameter uri ou até maddr não podem aparecer em só um dos comparados. Os outros parâmetros podem.
- Componentes Header do URI nunca são ignorados.
- URIs equivalentes:

- URIs não-equivalentes:

- Lembrando, se aparecer security em um dos URIs esse parâmetro é ignorado, mas se aparecer nos dois, eles devem ter o mesmo valor!