Русский
Русский
English
Статистика
Реклама

Network programming

Из песочницы Как я делал Telegram-бота для работы с сетью

12.08.2020 06:16:44 | Автор: admin
Добрый день! image Я поделюсь с Вами интересным опытом по созданию мобильного инструмента для работы с сетью.

Предисловие

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

2013 год. У меня есть товарищ, который так же работал в одном из федералов, подключая клиентов и была история, когда он мне дал в руки телефон и полез на чердак что-то там делать с коммутатором. Я снизу стоял с телефоном на котором была открыта веб страничка с разными интересными скриптами. Скрипты эти выполняли проверку порта на коммутаторе, чистку ошибок и прочего.

То есть, инженер придя на адрес не беспокоил администратора по глупостям, т.к. у него самого был инструмент для работы с сетью.

На дворе июнь 2018 года, и я мучался с мыслями о том что А почему бы не написать бота который бы проверял оборудование разного уровня(ядро, агрегация, доступ)?. Проблема была в том что избавится от рутины хотел только я один, остальные жили сегодняшним днём.

Выбор языка программирования и платформы

Ребят, ну конечно же Python. На момент задумок я уже имел кое-какие навыки и небольшой опыт написания скриптов. Платформа была выбрана дружелюбная Telegram т.к. все IT-шники там и обитают.

Выбор библиотек для написания бота

1. Библиотека для работы с Telegram. pyTelegramBotAPI угасал, тем более во времена блокировок хотелось быстро дружиться с прокси и прочими вещами. Я выбрал python-telegram-bot, и за основу взял Conversation.

2. Библиотека для работы с оборудованием. Из-за простоты работы, мой выбор пал на python3-netsnmp.
Основа положена, пришло время писать.

Погнали

Сеть была зоопарком железа и пришлось брать отдельно вендора определенного и работать с ним. Так же важное условие было, наличие MIB-ов для выполнения задач.

Одна из задач была проверка длины кабеля и состояние пар, проверка состояния портов и наличия ошибок на портах.

Сейчас многие напишут мол Ну а что без SNMP обойтись было нельзя?. Отвечу, что Да, нельзя, если вы хотите снимать данные нормальным человеческим образом то только SNMP.
Сейчас кого-то уже подгорает пукан и он пишет что только NETCONF.

Пройдя оборудование доступа и реализовав с ним работу в боте, я столкнулся с тем что иногда действительно для специфичных задач, который протокол SNMP не решит, придётся заходить на оборудование.

На помощь мне пришла библиотека netmiko и я по-прежнему остаюсь ей доволен. Она решила очень много задач даже не связанных с ботом. Количество поддерживаемого оборудования просто огонь.

Так же для проверки IP-адресов мне очень пригодилась библиотека ipaddress

image

image

image

В целом, при программировании я учел много нюансов начиная от авторизации пользователя в боте до выдачи ему разных прав.

Функционал рос

Да, функционал действительно рос, а с ним и росла поддержка определенного оборудования. Я добавлял оборудование радио доступа, оптические приемники КТВ.

Как-то ко мне пришли люди и говорят вот мы будем ставить домофоны. Я головой своей понимаю что настройка так же ляжет на мои плечи и плечи коллег.

Я начал щупать, смотреть. Читал API, которое благо там было. Выбрал самую простую библиотеку для работы с HTTP и HTTPS requests.
Накрутив уже работу с домофонами появились потребности в базе, но как обычно ленивой *опе сильно напрягаться не хотелось. Поэтому выбор пал на sqlite3. Библиотека так же была выбрана максимально простая это dataset.

Тучи сгущаются

В какой-то момент работы становилось безумно много и моё детище по факту жило самостоятельно. Работы много, денег мало ну вы думаю улавливаете нотку. Я решил покинуть это заведение. Отработав несколько лет в федерале я неплохо прокачал skill по работе с языком программирования. Остался очень этим доволен.

Эпилог

Пожалуй, это толи большая, толи не очень история подошла к завершению. Сетевик на мой взгляд без программирования никуда, особенно с зоопарком железа. В итоге парк поддерживаемого оборудования был такой:
23 модели коммутаторов доступа
3 модели оптических приемников КТВ
4 модели шассийных коммутаторов
1 модель шассийного маршрутизатора
3 модели оборудования радио доступа
Подробнее..

Знакомство с exsc (EXtensible Server Core). Часть 1

06.03.2021 22:12:47 | Автор: admin
ПРИВЕТСТВИЕ
image
Всем привет! Хочу поделиться с общественностью библиотекой, на основе которой в данный момент множество серверов, обслуживают тысячи клиентов в различных серверных системах. exsc (EXtensible Server Core) это библиотека, написанная на языке C и позволяет в рамках одного приложения, иметь один или несколько серверных потоков. Каждый серверный поток способен обслужить большое количество клиентов. Хотя библиотеку, можно использовать в модели типа запрос-ответ, в первую очередь она была рассчитана на поддержание постоянного соединения с большим количеством клиентов и обменом сообщений в реальном времени. Поскольку я и сам люблю взять готовый HelloWorld проект, скомпилировать его и посмотреть как всё работает, то в конце статьи я выложу ссылку на такой проект.

ДОКУМЕНТАЦИЯ

Многие операции делаются для определённого соединения. В рамках данной библиотеки за соединение отвечает структура exsc_excon. У этой структуры есть следующие поля:

ix индекс соединения. Это порядковый номер соединения, которое было свободно в момент подключения клиента.
id идентификатор соединения. Это уникальный номер соединения. В отличие от индекса он не повторяется.
addr IP адрес клиента
name имя соединения. Несколько соединений можно назвать одним именем и затем отослать какое-либо сообщение всем соединениям с одинаковым именем (смотрите функцию exsc_sendbyname).

Инициализация ядра

Для того, чтобы работать с ядром, нам необходимо его инициализировать с помощью функции
void exsc_init(int maxsrvcnt);
Параметр maxsrvcnt сообщает ядру, сколько серверных потоков мы будем использовать в рамках нашего приложения.

Запуск серверного потока

Далее нам нужно запустить серверный поток с помощью функции
int exsc_start(uint16_t port, int timeout, int timeframe, int recvbufsize, int concnt,
void newcon(struct exsc_excon excon),
void closecon(struct exsc_excon excon),
void recv(struct exsc_excon excon, char *buf, int bufsize),
void ext());


port порт который будет прослушивать серверный поток.

timeout указывает сколько времени серверный поток будет ожидать какой-либо активности от клиента. Если в течении этого времени клиент не прислал ни одного сообщения, то серверный поток закрывает такое соединение. Поэтому если мы хотим держать постоянную связь и выставили этот параметр на пример 30 секунд, то необходимо раз в 10-15 секунд присылать какое-либо сообщение типа ping.

timeframe временные рамки, за которое мы позволяем выполнить запрос.Так на пример, если это значение выставлено на 100 миллисекунд и серверный поток обработал все текущие запросы от пользователей за 10 секунд, то он оставшиеся 90 миллисекунд оставит процессору для выполнения других задач. Таким образом, чем меньше это значение, тем быстрее серверный поток будет обрабатывать запросы, но тем больше он нагрузит процессор.

recvbufsize размер буфера который серверный поток будет вычитывать за один раз.

concnt максимальное количество соединений с которым серверный поток работает одновременно.

newcon сallback функция, которая будет отрабатывать каждый раз когда будет подключаться новый клиент. В параметры этой функции будет передаваться соединение клиента который подключился.

closecon сallback функция, которая будет отрабатывать каждый раз когда будет закрываться неактивное подключение. В параметры этой функции будет передаваться соединение клиента который отключился.

recv сallback функция, которая будет вызываться когда клиент будет присылать пакеты. В параметры этой функции будет передаваться соединение клиента от которого пришли данные, указатель на данные и размер буфера с данными.

ext сallback функция, которая будет вызываться каждый проход цикла серверного потока. Эта функция сделана для расширения функционала ядра. На пример сюда можно подвязать обработку таймеров.

Функция exsc_start возвращает дескриптор серверного потока, который понадобится для вызова некоторых функций.

Отправка сообщений
За отправку сообщений отвечает функция
void exsc_send(int des, struct exsc_excon *excon, char *buf, int bufsize);
Эта функция потокобезопасная (её можно вызывать её из любого потока). В качестве параметров необходимо передать ей дескриптор серверного потока (который мы получили как возвращаемое значение функции exsc_start), соединение на которое мы хотим отправить сообщение, указатель на буфер с сообщением и размер буфера.

Так же мы имеем возможность отправить сообщение группе клиентов. Для этого есть функция
void exsc_sendbyname(int des, char *conname, char *buf, int bufsize);
Она аналогична функции exsc_send, за исключением второго параметра, в который передаётся имя подключений которым будет отправлено сообщение.

Задание имени подключения
Для тог, чтобы в будущем как то дополнительно идентифицировать подключение, либо хранить вместе с подключением некоторую информацию о нём, либо отправлять сообщения группе клиентов, используется функция
void exsc_setconname(int des, struct exsc_excon *excon, char *name);
Эта функция потокобезопасная. В качестве первого параметра передаётся дескриптор серверного потока, вторым параметром передаём само подключение и третьим параметром передаём имя этого подключения.

Подключение серверного потока к другому серверу
Иногда, серверная логика требует того, чтобы подключиться к другому серверу, для того чтобы запросить или передать какие либо данные. Для таких задач была введена функция, которая создаёт такое подключение.
void exsc_connect(int des, const char *addr, uint16_t port, struct exsc_excon *excon);
Эта функция потокобезопасная. В качестве параметров нам необходимо передать дескриптор серверного потока, адресс сервера к которому нам необходимо подключиться, потр сервера к которому нам необходимо подключиться и последним параметром мы передаём указатель на соединение с помощью которого мы в дальнейшем сможем вызывать другие функции библиотеки. Стоит отметить что нам нет необходимости дожидаться, пока подключение состоится. Мы можем вызвать функции exsc_connect и exsc_send одну за другой и система сама проследит за тем, чтобы сообщение было отослано сразу после того как сможет подключиться к удалённому серверу.

ПРИМЕР СЕРВЕРА С КОММЕНТАРИЯМИ

#include <stdio.h>  // fgets#include <string.h> // strcmp#include "../exnetwork/exsc.h" // подключаем исходники ядраint g_des; // дескриптор серверного потока// ловим новое подключениеvoid exsc_newcon(struct exsc_excon con){    printf("the connection was open  %s\n", con.addr);}// подключение закрываетсяvoid exsc_closecon(struct exsc_excon con){    printf("the connection was closed  %s\n", con.addr);}// принимаем сообщение от клиентаvoid exsc_recv(struct exsc_excon con, char *buf, int bufsize){    char msg[512] = { 0 };    memcpy(msg, buf, bufsize);    printf("receive data from %s\n%s\n", con.addr, msg);    if (strcmp(msg, "say hello") == 0)    {        strcpy(msg, "hello");        exsc_send(g_des, &con, msg, strlen(msg));    }}void exsc_ext(){}int main(){    printf("server_test_0 is started\n");    exsc_init(2); // инициализируем ядро с расчётом на два серверных потока    // запускаем серверный поток на порту 7777    // он будет держать неактивные соединения 30 секунд    // будет обрабатывать входящие сообщения в рамках 10 миллисекунд    // размер буфера для приёма задаём 1024 байта    // максимальное количество подключений ограничиваем до 10000    g_des = exsc_start(7777, 30, 10, 1024, 10000, exsc_newcon, exsc_closecon, exsc_recv, exsc_ext);    // тормозим главный поток, чтобы программа не завершилась раньше времени    // программа завершится когда мы введём команду exit и нажмём клавишу ENTER    while (1)    {        const int cmdmaxlen = 256;        char cmd[cmdmaxlen];        fgets(cmd, cmdmaxlen, stdin);        if (strcmp(cmd, "exit\n") == 0)        {            break;        }    }    return 0;}


ЗАКЛЮЧЕНИЕ
Ядро exsc осуществляет только низкий уровень взоимодействия с клиентами. Хоть это и самый важный элемент серверной системы, основа на которой всё строится, помимо него нужно строить более верхние уровни, которые будут отвечать за управление подключений, генерирование сообщений, сборку сообщений (которые вероятно будут приходить за несколько этапов). Если статья будет иметь положительный отклик то я напишу вторую чать, в которой разовью тему более верхнего уровня этой библиотеки написанной с использованием Qt, а именно про класс ExServer.

Ссылка на библиотеку github.com/extenup/exnetwork

Пример расположен в архиве exsc_test_0.zip
Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru