Проверяем доступность SIP провайдера

  • Tutorial
В это статье хочу поделиться одним интересным на мой взгляд способом проверки доступности sip провайдера, или другого устройства, особенно он актуален когда по какой-либо причине нельзя проверить сторону icmp запросами, и основывается на OPTIONS запросах протокола SIP. Кого заинтересовала данная тема прошу под кат.И так, протокол SIP, который описан в RFC 3261, имеет замечательный тип запроса OPTIONS, данный тип запроса используется для проверки совместимости сторон, он позволяет клиенту получить информацию о том, какие методы поддерживает удаленная сторона, и что самое главное, нет необходимости совершать вызов удаленной стороны(нет необходимости в отправке INVITE запроса). Пример OPTIONS запроса из RFC:
OPTIONS sip:carol@chicago.com SIP/2.0
      Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKhjhs8ass877
      Max-Forwards: 70
      To: <sip:carol@chicago.com>
      From: Alice <sip:alice@atlanta.com>;tag=1928301774
      Call-ID: a84b4c76e66710
      CSeq: 63104 OPTIONS
      Contact: <sip:alice@pc33.atlanta.com>
      Accept: application/sdp
      Content-Length: 0
Ответ на такой запрос должен быть таким же, как если мы отправили запрос INVITE, например это может быть ответ 200(OK), означающий что удаленная сторона готова принять звонок.Приступим к практической части, она сводиться к тому, что нам необходимо подготовить ip пакет с соответствующими данными и отправить его удаленной стороне и получить на него ответ. Для этого можем написать простой скрипт, например на Perl'е:
#!/usr/bin/perl
use IO::Socket;
use POSIX 'strftime';

sub SipPing {
        my ($msg,$remotehost,$callid,$socket,$date,$branch,$localip,$dest);
        $remotehost = shift;
        $localip = shift;
        $socket = IO::Socket::INET->new (
                PeerAddr => $remotehost,
                PeerPort => 5060,
                LocalPort => 5060,
                LocalAddr => $localip,
                Reuse => 1, 
                Proto => 'udp',
        );
        $callid .= ('0'..'9', "a".."f")[int(rand(16))] for 1 .. 32;
        $date = strftime('%a, %e %B %Y %I:%M:%S %Z',localtime());
        $branch="z9hG4bk" . time();
        my $packet = qq(
            OPTIONS sip:$remotehost SIP/2.0
               Via: SIP/2.0/UDP $localip:5060;branch=z9hG4bK39aaa111;rport
               Max-Forwards: 70
               From: "UA" <sip:ua\@$localip>;tag=as54192a85
               To: <sip:$remotehost>
               Contact: <sip:asterisk\@$localip:5060>
               Call-ID: 7706430b46622c057aeaa5ec057a0b59\@$localip:5060
               CSeq: 102 OPTIONS
               User-Agent: UA
               Date: Wed, 21 Dec 2013 00:00:01 GMT
               Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH
               Supported: replaces, timer
               Content-Length: 0
         );
        print $socket $packet;
        eval {
                local $SIG{ALRM} = sub { die };
                alarm 1;
                my $sock_addr = recv($socket,$msg,190,0);
                alarm 0;
                1;
        } or die "Failed";
        if ($msg) {
                print "Response: $msg\n";
        } else {
                print "Failed";
        }
        close($socket);
}

$remoteHost = '192.168.0.3';
$localIp = '192.168.0.2';
&SipPing($remoteHost, $localIp);

С помощью такого нехитрого скрипта можно проверить доступность SIP агента, без необходимости регистрации или звонка. Стоит отметить, что некоторые провайдеры разрешают получение OPTIONS запросов только с порта 5060 на порт 5060, для этого указываем локальный порт, а в случае если порт занят, например Asterisk'ом, то пригодиться параметр Reuse => 1.На этом всё.
Share post

Similar posts

AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 13

    0
    Спасибо за статью.
    А если взять готовые модули из cpan?
      0
      Сначала думал о нём, первым попался не глаза Net::SIP::Simple, а он насколько я понял не позволяет отправлять OPTIONS запросы…
      0
      Так все нормальные IP PBX сами умеют отслеживать падение пиров. А если это нужно для мониторинга, то есть куда как более информативные средства.
        0
        Возьмем Asterisk, asterisk -rx «sip show peers» покажет доступны ли пиры в данный момент, пишем скрипт, который будет парсить данные, завязываем к системе мониторинга, в таком случае согласен, но такой подход узко направлен и зависит от работы Asterisk'а, а если кто-то не пропишет qualify в настройках пира? нюансов много, в данном случае имеем скрипт который сам опросит сип пир и передаст данные в систему мониторинга без привязки к работе IP PBX.
          0
          Автоматизируйте настройку пиров и тогда не будет никакого «если кто-то не пропишет».
            0
            Asterisk, был приведен как пример.
        0
        особенно он актуален когда по какой-либо причине нельзя проверить сторону icmp запросами

        Я думал, что наоборот — пингами проверяют, только когда полноценную проверку нельзя организовать. Ведь пинги показывают лишь присутствие машины в сети, но никак не работу сервиса.
          0
          Есть в нагиосе check_sip используя достаточно клевую утилиту sipsak (в дебиане есть пакет), так же есть модуль (тоже использует sipsak) для smokeping для отслеживания задержек в sip стеке.
          Используя sipsak можно не изобретать велосипед из своих скриптов. Можно даже трасировку через сип делать (да это фича SIPа есть в стандарте)
            0
            Спасибо, буду иметь в виду, но использую zabbix.
              0
              Я думаю обертку sipsak для забикса вы точно осилите :)
                0
                У нас есть строгие правила по заведению всего и вся в забиксе, так что сделать скрипт и раскидать по серверам было самым лучшим решением:)
                  0
                  Да я лишь о том что sipsak не зря называеться (SIP Swiss army knife). Достаточно клевая утилита в том числе и для тестирования сип стеков. А то что им можно и мониторить это уже как сопуствующие возможности :)
                    0
                    Понял:)

          Only users with full accounts can post comments. Log in, please.