25.07.2014

Load Balancing SIP

UAC – > LB -> (PROXY1 | PROXY2 | … ) -> UAS

Задача: раскидать звонки между sip proxy, сначала на PROXY1, в случае его недоступности на PROXY2.

В идеале если хочется распределять нагрузку между несколькими прокси серверами, то нужно делать LB  в режиме stateless (использовать функцию forward() совместо с модулем dispatcher) однако в таком случае нет возможности сделать failover в случае падения одного из проксей, т.к. response нельзя поймать в отдельный блок. (хотя возможно разместив код в разделе onreply_route… надо будет проверить).

Сначала учтем ситуацию что в сообщении уже содержится route и вызовем функцию loose_route. без нее вы рискуете на некоторых звонках, это зависит от вашего окружения, получить зацикливание сообщений ACK. Нужно обязательно проверить, чтобы loose вызывался для ACK сообщений и участвующих в диалоге, а не для первых сообщений в диалоге, т.к. это может привести к пробеганию через ваш прокси трафика на чужие сервера, либо на поставщиков услуг, что страшнее, т.к. это сразу минус бабки.

Ниже представлен конфиг:

request_route {
if (loose_route()) {                                                #Если сообщение содержит Route: то функция выдаст 1. Если его там нет, то 0. Здесь мы проверяем, есть ли в сообщении Route и если да, то…
xlog(“L_INFO”,”ACK TRansported…”);   #Выводим в лог любую хрень полезную для понимания
t_relay();                                                                 #Оправляем сообщение согласно этому заголовку Route. 
exit;                                                                            #Завершаем выполнение скрипта, т.к. больше LB делать ничего не надо. 
}

if (!ds_select_domain(“1”, “8”))                   # Здест мы пользуемся функцией которая выберет для нас адрес прокси (proxy1) и подставит его в URI (первая строчка в SIP сообщении)
{
xlog(“L_ALERT”,”404 No route $ru”); # ВЫводим в лог сообщение елси ни один из проксей не доступен.
send_reply(“404″,”No route”);                  #Посылаем “клиенту” 404 сообщение, мол, нет возможности отправить вызов.
exit;                                                                          # Завершаем скрипт
} else {
t_on_failure(“RTF_DISPATCH”);            # Если таки прокси для сообщения определен, то привязываем ответ к разделу “RTF_DISPATH”, там мы поймаем ответ, и если он говорит о проблеме с прокси, то                                                                                             отправим сообщение на другой прокси.
 xlog(“L_ALERT”,”Passed dispatcher $ru via $du $rm”);   # Запишем в лог информацию о том, что сообщение будет отправленно на $ru.(при вызове функции ds_select_domain $ru меняется на новый
route(RELAY);                                                      # собственно отправляем сообщение в раздел где оно отправится к $ru.
}
}

 

 

10.06.2014

call_control cdrtool maxsessiontime

При работе функции Maxsessiontime система упорно не подгружает указанный лимит для пользователя

Причина кроета в код rating.php район строчки 8577:

if (!preg_match(“/^0/”,$CDR->CanonicalURINormalized)) {
$log=sprintf (“MaxSessionTime=unlimited Type=prepaid CallId=%s BillingParty=%s  DestId=None”,$NetFields[‘callid’],$CDR->BillingPartyId);
syslog(LOG_NOTICE, $log);
$this->logRuntime();
$ret=”none”.”\n”.”type=prepaid”;
return $ret; }

Если Зачем искать в номере начало на 0 – решительно не понятно…. иметь ввиду.

9.06.2014

call_control opensips application

При установке call_control возникает error: ‘Request’ object has no attribute ‘application’

Понятно, что где-то не передается свойства application. Исправляется таким способом:

заходим в sip.py из дистрибутивов

и self.application = “audio”

это конечно решение как говорится “влоб”, понятно что хорошо бы настроить передачу этого свойства от радиуса но мы этого делать не будем.

29.05.2014

Ubuntu SYSLOG LOCAL0

При настройке на Ubuntu вывода syslog0  в отдельный файлик, например opensips.log, что является очень удобным никак не удававалось перенаправить собственно поток по FACILITY LOCAL0 в opensips.log.

а) не работает рестарт службы rsyslog

б) в отдельный файл конфиг не выливается

Успех случился, только после того как скопировал файл syslog в opensips.log и служба перезапускалась вот таким вот варварским способом

ps ax | grep syslog

kill XXX

где XXX Id процесса rsyslogd.

ну понятно строка конфига стандартная: local0.*      -/var/log/opensips.log

1.08.2013

Номера в городах России

Получили таблицу стоимости городских номеров.

Появился список городов в которых можно приобрести номер для рекламных целей. Подключение номера 5-7 дней. Переадресация выставляется на любой Ваш номер.

Для заказа 100@yooxy.ru или по телефону +7 351 7502213.

Город Стоимость Аб. плата
Архангельск 950 590
Астрахань 950 590
Барнаул 950 590
Владивосток 2850 590
Волгоград 950 590
Воронеж 1900 590
Екатеринбург 950 590
Ижевск 950 590
Иркутск 950 590
Казань 950 590
Калининград 950 590
Кемерово 950 590
Краснодар 950 590
Красноярск 950 590
Минеральные Воды 950 590
Москва 950 590
Мурманск 950 590
Нижний Новгород 950 590
Нижний Тагил 950 590
Новосибирск 950 590
Омск 950 590
Оренбург 950 590
Пермь 950 590
Петропавловск-Камчатский 2850 590
Ростов-на-Дону 950 590
Рязань 1900 590
Самара 950 590
Санкт-Петербург 950 590
Саратов 950 590
Сочи 950 590
Ставрополь 950 590
Сургут 1140 590
Тверь 1900 590
Тольятти 950 590
Томск 950 590
Тула 1900 590
Тюмень 1140 590
Ульяновск 950 590
Уфа 950 590
Хабаровск 2850 590
Челябинск 950 590
Южно-Сахалинск 2850 590
Якутск 2850 590
Ярославль 1900 590

29.07.2013

Multifon, мультифон не работает… входящих нет

не работает мультифон

Сегодня после 9 утра по Московскому времени перестал работать Мультифон. Не принимает входящие вызовы, исодящие делает. Всё, что смог сделать оформить заявку в технической поддержке, в которой мне сообщили что обращения с подобными проблемами уже были специалистам заявка будет передана.

Всем кто столкнулся – терпения.

52274924

2.07.2013

Грязный хак

Возникла необходимость по времени делать переадресацию с одного номера на другой. В рамках opensips эта прямо скажем не его задача. Но как оказалось в рамках нескольких десятков клиентов эта задача вполне под силу и opensips.

Заводим в крон скрипт который модифицирует таблицу dialplan так как нам нужно. просто прямым запросом. Естественно это придется делать для каждого клиента.

Привет.

21.04.2013

Переезд на 1.9 с 1.7.2

Из-за частых проблем с памятью и не желанием с ними бороться переехал на версию 1.9. Не скажу что задача сложная, несколько часов времени. большое желание переписать конфиг с его логикой.

Но в итоге все базы обновил, заполнил, все вертится на новье.

Большой минус в новой панели у модуля dialplan у меня web не заработал – скопировал со старой версии и удалил в некоторых частях ссылки на match_len – этого столбца в новой таблице диалплана – нет.

Привет.

2.04.2013

Userblacklist / GlobalBlack list

Реализация Чернго и белого списка на opensips.

Достаточно триавиальная задача, но есть несколько ньюансов,прежде всего нужно понять по какой схеме мыбудемблокировать польователя, они могут быть разными. Мне нужно было реализовывать черные и белые списки относительно входящих звонков на номера,поэтому логика такая:

1) проверка набранного номера на наличие в глобальном блэклисте, Если есть то смерть, если нет,то далее….

2) проверим пользовательский черный список, если набранный номер есть, то проведем сверку с колонкой prefix поля from, и в зависимости от значения whitelist либо дадим звонку идти дальше либо выставим запрет.

сам код:

### Глобальный Черный список
if (!check_blacklist(“globalblacklist”)) {
xlog(“For $ru globalblack list Active…”);
$avp(is_in_blacklist) = “1”;
sl_send_reply(“403”, “Forbidden BlackListed”);
exit;
}

if (!check_user_blacklist(“$rU”, “$fd”, “$fU”)) {
sl_send_reply(“403”, “Forbidden BlackListed”);
xlog(“User Black listed $fu -> $ru”);
exit;
} else {
xlog(“User white list active for $fu to $rU”);
}

Обратите внимание на параметры к функции check_user_blacklist . Изменен порядок, так чтобы пользователем являлся набранный номер, а префикс применялся к АОНу т.е. номеру звонящего или проще говоря полю FROM.

Для понимания ссылка на то как выгядит сам список.

11.09.2012

Аналитика занятости линий для БД

Скриптик для анализа одновременного занятия линий.

Суть простая выбираем промежуток когда считаываем кол-во звонков, например каждые 5 минут начиная с 2012-09-01. И смотрим какие звонки к какому промежутку относятся. на выходе пара: время – кол-во линий.

Играя SQL запросами можно получить статистику по каналу или по префиксу, вообщем инструмент нужный, но данная реализация крайне медленная. Времени на разработку совсем нет, а решение принимать хочется на основании конкретных данных.

#!/usr/bin/perl

use strict;
use DBI;
use Time::Local;
use Date::Parse;

my $dbh = DBI->connect(‘dbi:Pg:database=yooxy’, ‘pavel’,”) or die $DBI::errstr;

#get all calls
my $date_start = ‘2012-09-09 00:00:00’;

my $leg = 300; #in seconds
my $calls_query = ‘select time,duration from acc where time > \”.$date_start.’\’;’;
my $sth = $dbh->prepare($calls_query);
$sth->execute;
my $ary_ref = $sth->fetchall_arrayref;

my $start_time = str2time($date_start);
my $a;
my $i,my $i2;
my %values;
$dbh->disconnect;
foreach ($a=$start_time;$a = $a + $leg;) {
$i2++;
foreach (@$ary_ref) {
$i++;
my $date1 = $_->[0];
my $duration = 60;# $_->[1];
my $line = $a;

my $start = str2time($date1);
my $end = str2time($date1) + $duration;

if (($line > $start) and ($line < $end)) { print “o$start < $line < $end\n”; $values{$a}++};

}

if ($values{$a} > 0) {print scalar(localtime($a)),”;”,$values{$a},”\n”;} else {print scalar(localtime($a)),”;”,0,”\n”;

};

last if $a > time();
}
print “\ncalls $i2; iter $i;”;