Parâmetro canreinvite do sip Asterisk :: Admirável Mundo Novo




Muito Bem Vindo

Prezado Leitor, a proposta desse Blog é compartilhar conhecimento com as pessoas que trabalham com Linux, Asterisk, OpenSER, e com tecnologia de voz sobre a rede IP em geral, através de tutoriais, dicas, howto, notícias entre outros assuntos.

Atente para termo de uso do conteúdo do blog no rodapé da página.

segunda-feira, 23 de junho de 2008

Parâmetro canreinvite do sip Asterisk

A Definição de peer: Opção canreinvite do Arquivo sip.conf do Asterisk



Página original do tutorial: http://www.voip-info.org/wiki/view/Asterisk+sip+canreinvite. Esse tutorial é, a meu ver, um excelente documento que explica de maneira fácil um dos pontos mais importantes do funcionamento do Asterisk. Eu rendo créditos aos autores originais os usuários oej e rehan da wiki, respectivamente, o criador e o último atualizador da página original. Pela clareza da explanação, denotam ser os desenvolvedores do módulo SIP do Asterisk.


A opção de configuração do parâmetro canreinvite para o peer no arquivo sip.conf é usado para dizer ao servidor Asterisk para nunca emitir um reinvite ao cliente. Isso é usado para permitir interoperabilidade com alguns hardwares (toscos) que vai a crash quando nós fazemos reinvite, como por exemplo, o ATA-186 da Cisco.

Quando o SIP inicializa a chamada, a mensagem INVITE contem a informação para onde enviar as streams de media. O Asterisk se utiliza a si como as pontas das streams de media quando do estabelecimento da chamada. Uma vez que a chamada tenha sido aceita, o Asterisk envia outra mensagem (re) INVITE aos seus clientes com a informação necessária para ter os dois clientes enviando as streams de media diretamente entre si.


• Se algum dos clientes estiver configurado com o canreinvite=NO, o Asterisk não vai lançar de jeito algum um re-invite;
• Se os clientes usam codecs diferentes, o Asterisk não vai emitir um re-invite;
• Se o comando Dial() contem "t", "T", "h", "H", "w", "W" ou "L" ou (esses aparecerem em uma combinação de múltiplos argumentos) o Asterisk não vai inserir um re-invite.

'canreinvite=no' interrompe o envio dos (re) INVITE’s, uma vez que a chamada tenha sido estabelecida. Alguém vai encontrar nos arquivamentos de mensagens dos mail-lists e no handbook Asterisk que o ATA-186 da Cisco não trata muito bem o (re) INVITE. Isso também é necessário se o cliente e o servidor Asterisk estão em lados opostos de um gateway que executa NAT ou firewall.


* canreinvite = yes; "permite o direcionamento do tráfego da media RTP"
* canreinvite = no; "não permite fazer re-invites"
* canreinvite = nonat; "permite fazer reinvite quando as pontas estão na rede
local, e não permite reinvite quando existir NAT"
* canreinvite = update; "usa o método UPDATE em vez do INVITE"
* canreinvite = update,nonat; "usa o UPDATE quando as pontas estão na rede local,
e não permite o UPDATE quando existir NAT"


Observações:

• reinvite=yes/no é exemplificado de forma errada, mesmo que você veja mencionado no exemplo dos arquivos .conf. A sintaxe correta é canreinvite=yes/no;

• Conectando os caminhos da media diretamente a uma ponta que está atrás de NAT não seria de bom grado. Especialmente se ambos os dispositivos estão atrás de NAT. Você pode querer tentar usar o módulo nathelper do SER em conjunto, já que o nathelper.so pode reescrever o SDP, de sorte que os endereços IP privados não serão incluídos no re-invite.


Uma Longa Explanação

Explicação baseada na seguinte postagem da lista asterisk-users

Eu tenho definido canreinvite=no no canal para a operadora SIP e isso funcionou imediatamente. Tudo beleza, eu estou feliz com isso! Mas, Eu quero *entender* o que está acontecendo aqui.
Minha instalação é:

O Asterisk está conectado em um lado via eth1 ao "mundo externo" (endereço IP
81.223.xxx.xxx) e no outro lado via eth0 na LAN interna
(eth0 tem endereço IP 192.168.1.200, o telefone SNOM tem 192.168.1.201, ...).

Uma boa questão para a qual é difícil dar uma resposta curta. Primeiramente, você necessita entender como o SIP por si mesmo foi projetado para estabelecer chamadas entre dispositivos.

A mensagem 'INVITE' do SIP diz "Eu quero estabelecer uma chamada". No corpo dessa mensagem tem um bloco do SDP (Session Description Protocol) que diz "minha ponta de áudio está no endereço IP x.x.x.x porta x, e Eu posso usar os codecs A, B e C".

Na arquitetura pensada do SIP, a mensagem INVITE é encaminhada via uma series de proxies até que ela alcance o destino requisitado. A ponta remota responde com uma mensagem 200 dizendo "OK, minha ponta de áudio está no endereço IP y.y.y.y porta y, e Eu escolho o codec B", que é retornada ao primeiro telefone. Neste ponto, o primeiro telefone inicia o envio dos pacotes RTP de áudio de x.x.x.x:x para y.y.y.y:y, e o segundo telefone os envia de y.y.y.y:y para x.x.x.x:x. Isto é, o caminho do áudio é direto, enquanto que as mensagens SIP atravessam os proxies envolvidos nas trocas de mensagens.

A seguir está uma explicação simplificada, mas é suficiente para esclarecer o assunto.

Agora a segunda coisa a entender, o Asterisk não é um proxy SIP e seu comportamento padrão é estabelecer duas pernas com duas streams de áudio separada: Do telefone X para o Asterisk e do Asterisk para o telefone Y. A forma de isso funcionar é a seguinte:

• O Telefone X envia o INVITE dizendo "Eu estou no endereço IP x.x.x.x:x, Eu posso usar os codecs A,B,C";

• O Asterisk decide onde está a próxima perna. Se for outro dispositivo SIP, ele envia um novo INVITE SIP (com um diferente Call-Id) para o segundo telefone, telefone Y, dizendo "Eu estou no endereço IP z.z.z.z:z1, Eu posso usar os codecs C e D". Onde z.z.z.z é o próprio endereço IP do Asterisk e :z1 é uma porta que ele escolheu;

• Esse INVITE chega ao segundo telefone, o Y, que diz ao Asterisk "OK, Eu estou no endereço IP y.y.y.y:y, Eu escolho o codec C", e o envia de volta ao Asterisk;

• O Asterisk fica contente, assim ele estabelece a primeira perna substituindo o primeiro telefone, o X, e retorna uma mensagem 200 "OK, Eu estou no endereço IP z.z.z.z:z2, Eu escolho o codec C" para o primeiro telefone, o telefone X.

Portanto agora o primeiro telefone, o telefone X, está enviando pacotes entre x.x.x.x:x e z.z.z.z:z2, e o segundo telefone, o telefone Y, está enviando pacotes entre y.y.y.y:y e z.z.z.z:z1.

Isso significa que o Asterisk está no caminho da media – cada pacote RTP tem sido recebido e re-enviado, em ambas as direções. O lado negativo disso, essa situação significa mais carga nos ombros do servidor Asterisk. O lado positivo, ele estando no meio da stream de media significa que o Asterisk pode executar um conjunto completo de funcionalidades úteis de voz - gravação, conferência, estacionamento de chamada, espera, até mesmo a tradução de codec´s (ou seja, a stream vinda do telefone X para o Asterisk pode estar usando um codec, e o telefone Y para o Asterisk usando outro codec diferente).

A terceira coisa que se deve esclarecer é que o Asterisk pode otimizar esse comportamento fazendo com que ele saia, conseqüentemente, do caminho da media para que o fluxo de media seja estabelecido diretamente entre as pontas. Isso é o que quer dizer a mensagem "native bridging" que aparece na console do Asterisk – ou seja, fazendo a conexão direta das duas pontas que são compatíveis entre si, em vez de fazer que o áudio seja transmitido passando pelo Asterisk.

Assim, sob certas condições, as mensagens SIP enviadas pelo Asterisk ao segundo telefone vão conter o endereço IP do primeiro telefone, e vice-versa. Isso quer dizer que ele verifica as mensagens SIP e se comporta como um proxy SIP.

Obs.: Neste caso, o Asterisk ainda não é de fato um proxy SIP. As duas pernas da chamada têm call-Ids diferentes, e, portanto, são chamadas SIP diferentes. Contudo, os descritores SDP para o áudio das duas pernas da chamadas apontam-se recíprocamente. Essa forma mais simples quando do estabelecimento da chamada foi introduzida no Asterisk 1.4; para as versões mais antigas, eu acredito que a chamada seja estabelecida inicialmente com as duas pernas, e depois o Asterisk re-conecta as pontas diretamente usando um re-INVITE.

Ainda neste ponto, vejamos o que diz os comentários vindos no arquivo sip.conf do braço estável 1.4 a cerca de como o Asterisk vai manipular a stream de media entre duas pontas remotas quando do estabelecimento de uma chamada entre dois dispositivos SIP:

;------------------------------- TRATAMENTO DA MEDIA -----------------------------
; Por padrão, o Asterisk tenta fazer re-invite do áudio através de um caminho ótimo.
; Se não existir nenhuma razão para o Asterisk ficar no meio do caminho da media, a ; media será redirecionada. Isso realmente não vai funcionar no caso quando o Asterisk
; está no lado de fora e tem clientes atrás de um NAT. Neste caso, você vai desejar
; configurar o canreinvite=nonat.
;
;canreinvite=yes ; o Asterisk, por padrão, tenta redirecionar a stream de media
; RTP (áudio) diretamente através do originador para o ponto chamado. Alguns
; dispositivos não suportam isso (especialmente se um deles estiver atrás de um NAT).
; A definição padrão é YES. Se você tem todos os clientes atrás de um NAT, ou por
; alguma outra razão deseja que o Asterisk fique no caminho do áudio, você pode desejar
; desativar esse comportamento.
;
; Essa configuração também afeta o direcionamento de media RTP quando do
; estabelecimento da chamada (uma nova funcionalidade na versão 1.4 do Asterisk–
; estabelece a chamada diretamente entre as pontas em vez de enviar um re-INVITE).
;
;directrtpsetup=yes ; Ativa quando do estabelecimento da chamada, um novo experimental
; direcionamento de media RTP.
; Isso estabelece a chamada diretamente com a media passando de peer-a-peer sem
; precisar fazer re-invites.
; Não vai funcionar para vídeo e nos casos onde as pontas chamadas enviam payloads RTP e
; headers fmtp na mensagem 200 OK que não batem com os INVITE’s dos originadores.
; Isso também vai falhar se o canreinvite estiver ativado quando o dispositivo estiver
; naturalmente atrás de NAT.
;
;canreinvite=nonat ; Uma opção adicional é permitir a redirecionamento do caminho
; da media (reinvite), mas somente quando a media está sendo
; enviada ao peer que é sabido não estar atrás de um NAT (uma vez que o núcleo RTP pode
; determinar isso baseado no endereço IP aparente a partir do qual a media chega).
;
;canreinvite=update ; Ainda uma terceira opção... Use UPDATE para o redirecionamento
; do caminho de media, em vez de fazer INVITE. Essa pode ser combinada com 'nonat',
; como 'canreinvite=update,nonat'. Isso vai implicar em 'yes'.



O que eu quero dizer por "sob certas condições"? Bem, não estou certo qual seja a definição completa, mas algumas dessas condições é que ambos os canais SIP precisem estar marcados com o parâmetro "canreinvite=yes". Se qualquer um dos canais estiver com o parâmetro "canreinvite=no", então o Asterisk retorna ao comportamento padrão estabelecendo então a ligação das duas pernas em separado.

No seu caso, você necessita do comportamento padrão quando chamando o provedor, porque o telefone SIP está em um endereço IP 192.168.1.201 privado, enquanto que o provedor está em um endereço IP P.P.P.P público. Se as mensagens SIP eram para tentar estabelecer um caminho de media direto entre os dois isso não iria funcionar [*]; em particular, não existe nenhum ponto do provedor público SIP tentando enviar um pacote RTP para o endereço IP 192.168.1.201, porque ele não é capaz de rotear até esse número.

[*] Para ser preciso, se você tem um NAT firewall entre sua rede interna e a Internet, então alguns pacotes serão capazes de atravessar diretamente entre a sua rede e o mundo externo, com o firewall modificando o endereço IP de origem e/ou a porta no processo. Existe um conjunto completo de truques indecentes que podem ser feitos, tanto no telefone quanto no provedor, o que significa que se você for realmente sortudo você pode fazer que a conexão VoIP funcione dessa forma. No entanto, eu recomendo a você evitar fazer isso. Você está em uma situação cômoda porque seu servidor Asterisk já tem um endereço IP público real, portanto faça uso dele.

A última coisa que tomou um tempo de mim para compreender foi, por que a opção que quer dizer "Eu prefiro usar um caminho direto para a media RTP", é chamado "canreinvite=yes"?

Mesmo que o caminho normal de áudio para uma chamada possa ser estabelecido fazendo-se uma ponte nativa (native bridging) entre os dispositivos, o Asterisk às vezes necessita ser capaz de se re-inserir no caminho da media em meio a uma chamada – para fornecer serviços tais como Espera, Transferência, Estacionamento e assim por diante quando são requisitados.

O mecanismo SIP para isso é chamado re-INVITE. Dois telefones que estão se comunicando fluentemente entre si podem ter a stream de media alterada para que ele fique no meio da chamada usando esse mecanismo, portanto o Asterisk pode interromper o link direto e re-conectar as duas pernas da ligação a si.

Entretanto, nem todos os telefones suportam esse mecanismo. Se você define o canreinvite=no em um canal SIP, isso está dizendo "esse telefone não suporta o mecanismo do re-INVITE para re-conexão do áudio no meio de uma chamada". Conseqüentemente, o Asterisk decide que ele precisa se inserir na stream de media durante toda a chamada, de sorte que ele já permanece no caminho se depois alguma das partes requisitar alguma daquelas funcionalidades em meio à chamada.

Felizmente isso é suficiente para responder a sua questão. A melhor forma de ver o que está acontecendo é olhar os seus pacotes SIP/SDP, os quais você pode analisar usando tanto o comando 'sip debug' na console do Asterisk, ou usando o programa tcpdump:


# tcpdump -i eth0 -n -s0 -v udp port 5060
# tcpdump -i eth1 -n -s0 -v udp port 5060



Com uma versão mais recente do tcpdump, a opção -v vai mostrar a você a informação útil do SIP/SDP. Se isso não funcionar, use -x não é o (X maiúsculo) que vai mostrar a você em hexa e ASCII. -s0 significa capturar o pacote inteiro, e -n significa não tentar fazer pesquisas ao DNS inverso para todos os endereços IP´s dos pacotes.

Veja também


Asterisk SIP media path: Mais informação sobre quando e por que o Asterisk fica no caminho da media
Asterisk SIP Channels
Asterisk config sip.conf
SIP method invite re-invite: O que é um re-invite SIP?
Asterisk SIP NAT Solutions


Obs.: Eu publiquei esse tutorial em Português inicialmente no Portal Asteriskbrasil.

Um comentário:

Anônimo disse...

Perfeito! Tecnico e objetivo! Agora tenho uma luz para seguir na solucao! Abracos! Parabens tb pela traducao/interpretacao! F. Romeu!




Creative Commons License
Admirável Mundo Novo: Tudo Sobre Asterisk, OpenSER, Linux e Tecnologias de Voz sobre IP
by Cléviton Mendes de Araújo is licensed under a Creative Commons Atribuição 2.5 Brasil License.