Resumo

  • Replaces usa Call-ID, to-tag e from-tag para apontar um único diálogo SIP criado por INVITE. A correspondência não autentica o iniciador nem lhe concede poder de substituição.
  • O UA receptor precisa autorizar o pedido e admitir a nova sessão. Só depois de aceitar o novo INVITE ele envia BYE ao diálogo confirmado ou CANCEL a um early dialog aplicável; se a admissão falhar, o diálogo anterior fica intacto.
  • A aprovação de REFER, a procedência Referred-By, o 2xx do INVITE de substituição, o encerramento do leg anterior e a continuidade de mídia, gravação e cobrança são fatos diferentes. Um único status não pode governar todos.

A diferença entre pedir, localizar e substituir

Uma transferência atendida começa antes de Replaces. A atendente conversa com o cliente, abre uma consulta com um especialista e depois envia REFER ao telefone do cliente. O Refer-To conduz o cliente ao especialista e pode carregar, de forma escapada, os identificadores do diálogo de consulta que deverá ser substituído.

O telefone do cliente pode aceitar o REFER e ainda assim não completar a transferência. Ele precisa gerar um novo INVITE. O especialista precisa receber esse INVITE na instância certa, localizar o diálogo, reconhecer a autoridade de quem chega e aceitar a nova sessão. Só então o diálogo de consulta pode ser encerrado.

Se o especialista negar a autorização, a localização correta não ajuda. Se aceitar a identidade mas não conseguir negociar mídia ou chaves, a intenção não ajuda. Se o INVITE novo for aceito mas o BYE antigo se perder, o resultado agregado ainda exige reconciliação.

RFC 3891 trata Replaces como uma primitiva explícita e limitada. Ela coordena qual diálogo um novo INVITE pretende substituir. Não cria um dono remoto da sessão.

Um novo INVITE preserva a decisão local

Replaces não reescreve o diálogo antigo. O campo aparece em um INVITE novo, com Call-ID próprio. O novo caminho precisa passar pelos controles normais de uma sessão nova.

Isso deixa a intenção visível e evita associações implícitas. Se o UA não entender o mecanismo, o diálogo atual não deve ser alterado por engano. Supported: replaces anuncia capacidade; Require: replaces pode exigir falha explícita em um peer sem suporte. O registro de parâmetros SIP da IANA mantém ambos.

Capacidade é uma informação sobre software, não uma promessa de política. O mesmo terminal pode permitir uma substituição entre dois dispositivos do mesmo usuário, negar outra entre tenants e exigir confirmação humana numa terceira.

REFER e Replaces também são independentes. REFER pede que um destinatário acesse um recurso. Replaces indica que o novo INVITE quer ocupar o lugar de um diálogo específico. Juntos formam um fluxo comum de transferência, mas não uma única transação.

O receptor é quem define local e remoto

O valor de Replaces contém Call-ID e exatamente um to-tag e um from-tag. O UAS compara o to-tag com seu tag local e o from-tag com seu tag remoto.

Essa orientação precisa ser reconstruída no ponto que recebe o novo INVITE. Copiar a ordem To/From de uma mensagem antiga pode inverter os tags. Em uma cadeia com SBC, B2BUA, state replication e failover, o erro pode surgir muito depois da captura original.

O registro de errata do RFC 3891 possui uma correção editorial verificada para tags invertidos no exemplo de early dialog; há também uma correção editorial mantida para futura atualização do documento. Elas não mudam a regra normativa, mas mostram que exemplos precisam ser lidos à luz da perspectiva local/remota.

O escopo é um diálogo, não uma “chamada” abstrata. Replaces não seleciona múltiplos diálogos, uma transação inteira nem uma árvore de proxy forking. Se o INVITE inicial criou várias ramificações, a substituição de uma não encerra as demais. Se o INVITE novo for retargeted para outros Contacts, não herda a lógica do primeiro fork.

Já o identificador de interação de um contact center pode reunir cliente, atendente, consulta, fila, gravação e cobrança. Um evento de um diálogo só pode mudar o agregado se uma regra posterior provar que todos os legs relevantes chegaram ao estado esperado.

O triplete não contém um verbo

O UAS rejeita com 400 um INVITE com mais de um Replaces, Replaces em outro método ou semânticas de call control contraditórias.

O contraste com RFC 3911 é útil. Join também localiza um diálogo com Call-ID e tags, mas pede para incluir o novo diálogo no espaço de conversa. Replaces pede para encerrar o diálogo indicado e substituí-lo. Os identificadores são semelhantes; os verbos são opostos.

Portanto, o triplete diz qual é o objeto. O header diz a operação proposta. A autenticação diz quem pede. A autorização diz se pode. A admissão diz se é viável. BYE, CANCEL, mídia e aplicação mostram o que ocorreu.

Se houver mais de uma correspondência, o UA age como se não houvesse nenhuma. Sem correspondência, ou com um diálogo que não nasceu de INVITE, a resposta é 481. Se o diálogo já terminou, a recomendação é 603, evitando que um pedido atrasado vire uma nova chamada tocando sem contexto.

Não se deve classificar todo 481 como ataque. Tags invertidos, estado expirado, instância errada, perda em failover, retargeting e corrida com encerramento são explicações distintas e pedem responsáveis distintos.

Autoridade é uma etapa obrigatória depois do match

Ao encontrar um diálogo ativo, o UA precisa verificar se o iniciador do novo INVITE está autorizado a substituí-lo. O RFC não deixa essa etapa implícita.

Uma identidade autenticada como equivalente ao usuário substituído pode ser aceita sob uma política apropriada. Referred-By pode indicar que o outro participante originou o pedido via REFER. O UAS pode aplicar outros critérios locais e pode avaliar o diálogo novo de modo diferente do antigo.

As possibilidades não formam uma procuração universal. Credenciais compartilhadas podem representar vários aparelhos da mesma identidade ou uma delegação legítima. Se forem amplas demais, transformam uma service account em autoridade transversal sobre usuários e tenants. Autenticação prova controle de uma credencial, não a intenção humana naquele momento nem poderes jurídicos e comerciais.

RFC 3892 explicita a fragilidade de Referred-By sem proteção. O referee transporta a informação do referrer para o refer target, podendo vê-la ou alterá-la. Quando a informação afeta admissão ou é mostrada à pessoa, o target deve considerar a exigência de um token válido. Sem ele, o dado é suspeito.

Mesmo um token válido protege declarações específicas sobre a referral; ele não comprova automaticamente consentimento de gravação, autoridade corporativa, mandato financeiro ou elegibilidade de serviço. O policy owner precisa definir e registrar o alcance.

Saber os identificadores pode ajudar, mas não possuir

RFC 4538 define Target-Dialog para pedidos cuja autorização pode depender do conhecimento de um diálogo existente. Em um diálogo estabelecido com SIPS, com identificadores imprevisíveis e uma relação de confiança definida com o caminho original, esse conhecimento pode servir como prova.

As condições fazem parte do valor da prova. Em um caminho não protegido, um observador pode aprender os mesmos identificadores. E, mesmo no caso protegido, o UAS pode decidir que a relação demonstrada não basta para a operação pedida.

Conhecimento de contexto é evidência. Não é propriedade do contexto. O método, a identidade, a proteção do caminho e a política local determinam se aquela evidência autoriza algo.

Essa é a distinção de Heng Lu em escala de protocolo: participação e conhecimento podem informar a decisão, mas não assumem o lugar do principal que suporta a consequência. O UA que detém o diálogo continua sendo o ponto de decisão.

O diálogo antigo é a garantia contra uma nova sessão inviável

Depois de autorizar, o UAS tenta aceitar o novo INVITE, realocar a interface e outros recursos, e encerrar o diálogo antigo. Tentar não significa conseguir.

O RFC cita falha de QoS, keying e mídia incompatível. Também pode haver falta de recursos ou outro erro normal de admissão. Quando não puder aceitar a nova sessão, o UAS deve responder com o erro apropriado e deixar o diálogo correspondente inalterado.

A ordem impede que um pedido incompleto destrua a única conversa funcional. Encerrar no match dá poder a identificadores vazados. Encerrar na autenticação sacrifica a sessão diante de uma oferta tecnicamente impossível. Encerrar depois da admissão preserva o fallback.

Para diálogo confirmado, sem early-only, o UAS envia primeiro o 2xx do novo INVITE e depois BYE no antigo. Para um early dialog iniciado pelo próprio UA, aceita o novo e envia CANCEL ao INVITE anterior.

early-only protege a intenção de substituir somente uma ramificação ainda tocando. Se o diálogo já foi confirmado, o resultado é 486. Se o early dialog não foi iniciado pelo UA receptor, o resultado é 481 e o estado fica preservado: o pedido de um único diálogo não pode recriar o forking de outro originador.

O 2xx prova a admissão do novo diálogo. Não prova sozinho a entrega do BYE, o desaparecimento dos legs internos de um B2BUA, o fim dos forks, a continuidade RTP, a troca correta da gravação nem o fim da cobrança anterior.

REFER tem sua própria aprovação e seu próprio relatório

RFC 3515 orienta o UA que aceita um REFER bem formado a obter aprovação do usuário, de modo interativo ou por política configurada. Depois disso, ele acessa o recurso em Refer-To pelas regras normais.

Em transferência atendida, o Refer-To costuma conter Replaces escapado. O transferee cria o novo INVITE, e o transfer target executa novamente match, autorização e admissão. A resposta positiva ao REFER não substitui essas decisões.

O resultado da ação referenciada é comunicado por NOTIFY. RFC 7647 atualiza a aceitação de REFER para 200 em vez de 202, disciplina o uso de GRUU e exige Target-Dialog quando for necessário identificar um diálogo existente. Ainda assim, o 200 responde ao REFER, não declara toda a transferência concluída.

RFC 5589 afirma que uma transação REFER bem-sucedida não encerra a sessão entre transferor e transferee; é necessário um BYE posterior. Nos fluxos de falha — busy, no answer ou rejeição — a sessão anterior pode sair de hold e ser retomada.

Logo, aprovação do REFER, resposta do REFER, resultado do INVITE disparado, encerramento do diálogo antigo e continuidade do serviço precisam de estados próprios.

Uma prova reconstruível em vez de um selo verde

Registre separadamente o Call-ID do INVITE novo e o triplete apontado por Replaces. Preserve os tags na perspectiva do receptor, o estado do diálogo no match, Contact, rota, fork branch e early-only.

Registre também quem decidiu: identidade autenticada, Referred-By, validação do token, versão da política, regra de usuário ou tenant, fonte de aprovação e justificativa. authorized=true sem origem não resiste a auditoria.

Na admissão, guarde response code, hash do SDP, codecs e direções, keying, QoS, instância e ACK. Após 2xx, relacione BYE/CANCEL do diálogo antigo, resposta, retransmissões e o último sinal e mídia observados.

REFER entra na mesma timeline com Call-ID, CSeq, Target-Dialog, fingerprint de Refer-To, aprovação, resposta e NOTIFY. O resultado notificado deve ser conferido com a transação target e os legs reais.

Os testes devem incluir tags invertidos, match ambíguo, diálogo terminado, corrida early-only, falta de suporte, negação de autoridade após match correto, token inválido, incompatibilidade de mídia/key/QoS, busy/no-answer, perda de BYE após 2xx, fork residual, retargeting, perda de estado em failover e mapping B2BUA não reconstruível.

O registro final precisa responder, em campos separados: o que foi solicitado, qual diálogo foi indicado, quem tinha autoridade, o que foi admitido, o que terminou e o que a pessoa realmente recebeu.

Fontes