воскресенье, 21 декабря 2014 г.

Ошибка обновлений + кэширующий прокси

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







 



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

http://update.fly-server.ru/update/5xx/beta/FlylinkDC_x64.exe.bz2
меркер версии хранится в файле рядом
 
http://update.fly-server.ru/update/5xx/beta/Update5_beta.xml
но этот файл был отдан уже от новой версии

Детальнее проблема описана на одном из форумов провайдера
http://help.unet.by/question/details/id/361926
В чем может быть причина?
может у меня что-то не так?
или это проблема локальная и исключительно на стороне провайдера.

Может кэшу нужна привилегия на сканирования каталога

http://update.fly-server.ru/update/5xx/beta/
которую я отключил - т.к. флайлинк сам знает какие файлы качать и их прямые урлы
после чтения файла конфигурации обновки

http://update.fly-server.ru/update/5xx/beta/Update5_beta.xml

суббота, 20 декабря 2014 г.

Сохраняем историю обмена файлами в базе sqlite

Несколько раз меня пользователи просили приделать эту функцию
т.к. искать по логам не удобно.
С билда 18034 на бета-канале в автообновлении
или тут http://www.fly-server.ru/install/r5xx/beta/
доступна новая версия.
Пользователям с большой нагрузкой по трафику прошу протестировать
насколько эта операция окажется ресурсоемкой (зависания и т.д.)
Об ошибках пишите на почту pavel.pimenov@gmail.com
или анонимно в чат поддержки dchub://dc.fly-server.ru











Вся информация хранится в базе данных FlylinkDC_transfers.sqlite
в виде одной не нормализованной таблицы (рис 2)
Этот файл всегда можно безболезненно удалить
потеряется только история закачек/отдач











В планах добавить
- Поиск по атрибутам
- Настройку ротации файла для удаления старых записей
- Сохранение статистики от кого получены сегменты файла (возможно оно не нужно)
- Экспорт в Эксель
- Что-то еще.... предлагаете.


пятница, 19 декабря 2014 г.

FlylinkDC++ и Doctor Dump

Всем привет.
Успешно обновился на новую версию сбора и анализа дампов падения.
Фалйлинк за 2 года использования сервиса https://drdump.com стал стабильнее и было 
исправлено львиная доля ошибок не повторяющаяся на конфигурации разработчика
Приведу два последних примера быстрой локализации проблемы с помощью "доктора-дампа"
1. После перехода на VC++2013 я не знал, что он по умолчанию включает
опцию использования инструкций SSE2 и этом привело к тому, что пользователи 
на старых процессорах типа Athlon XP после получения обновлений
сразу начали падать при инициализации openssl
я успел это заметить после получения 23 дамп 
(вероятно эти 23 человека сразу снесли глючный флайлинк и больше никогда его не поставят) 
без доктора - эта цифра была-бы больше:-(
Программой пользуются в отдаленных уголках СНГ где такой старый 
процессор еще считается нормальным... я думаю быстрым фиксом я спас остальных 
обладателей этого процессора
https://drdump.com/Problem.aspx?ProblemID=102637

















2.  Ошибка в реализации функции pow при использовании компилятора VC++2013 старых версий винды
https://drdump.com/Problem.aspx?ProblemID=102616

В данном случае задето меньше пользователей
т.к. она возникла только у тех у кого виста или 7-ка без SP1
падало при хешировании новых медиа-файлов в mediainfo-lib
Ошибка оказалась известная и способ обхода описан в инете.
Быстро пофкисил во флайлинке падение и выпустил обновление
 + послал патч автору библиотеки medainfo
http://sourceforge.net/p/mediainfo/code/6567/
и даже получил за это спасибки в его ченж-логе :)






суббота, 13 декабря 2014 г.

sqlite + levelDB

Всем привет.
Для нормальной работы серверной части флайлинка я смог подобрать только один хостинг- digitalocean
т.к. он единственный кто выдает хорошие iops-ы и позволяет держать текущую нагрузку
(возможно у меня кривые руки - я ищу способы их сровнять :)

но возникла проблема с дисковым пространством т.к. база постоянно пополняется 
а SSD пока не очень дешевые и когда размер sqlite базы добрался до 12 гб я 
пересмотрел алгоритм работы флай-сервера и унес редко-используемые данные в LevelDB 
с прозрачной компрессии  snappy

В итоге получилась следующая картинка по диску: 
  • 2.7GiB [##########] /media-db-compress.leveldb 
  • 1.7GiB [######    ]  fly-server-db.sqlite
Вся серверная часть написана на С++ с использованием https://github.com/cesanta/mongoose

Подробности миграции обсуждал тут
http://www.sql.ru/forum/1118531/vybor-bd-dlya-optimalnogo-hraneniya-musorki-json-ov



пятница, 21 ноября 2014 г.

Проблемка DC++ если шарятся очень большие коллекции файлов

Всем привет!
Недавно мне показали в DC++ сети пользователя с шарой 350 Tb! (рис 1) 
6.5 миллиона файлов 259 тыс каталогов - 
Файл лист в сжатом bz2 виде занимает 197 мб - после декомпрессии получается  xml в 733 мб
Флалинк парсит этот список на моем i7 компе 60 сек!












Теперь рассмотрим алгоритм обслуживания поисковых запросов в DC++
для случае если такой жирный пользователь сидит на большом кол-ве хабов.
Если открыть окно CMD отладчика то можно увидеть, что клиент ежесекундно
получает пачку поисковых запросов
(на моем компе активно около 30 хабов случае это около 40-80 штук)

Запросы делятся на 2 вида:
1. Точный запрос поиска по TTH вида
  $Search Hub:Indie F?T?0?9?TTH:KEWX74O4YGFIT3WGE3LYK43QXMVYORJPWVLUWUA
2. Поиск по подстроке(клиенты ищут файлы без учета регистра)
  $Search Hub:UserDDD_1313 F?T?0?7?Unforgettable
Первый вид запросов практически не напрягает программу т.к. вся шара пользователя загружена в оперативную память в хеш таблицу (std::unordered_map) где ключом является TTHValue - 24 байта
если пренебрегать возможными коллизиями хеш-функции поиск идет мгновенно вот в этом месте:
https://github.com/pavel-pimenov/flylinkdc-r5xx/blob/e92a7f560a19bb3122106efe6d25721ee00fb770/client/ShareManager.cpp#L2144

Второй запрос немного сложнее и тут выполняется 2 шага.
2.1 Полученную подстроку подают на вход bloom-фильтра который быстро отвечает на вопрос - стоит ли искать ее в шаре или нет.
2.2 Если bloom сказал, что вероятно объект с таким именем у вас в шаре имеется то стартует самая последняя и тяжелая ветка алгоритма - рекурсивный обход всего дерева каталогов и файлов шары:
https://github.com/pavel-pimenov/flylinkdc-r5xx/blob/e92a7f560a19bb3122106efe6d25721ee00fb770/client/ShareManager.cpp#L2205
В результате обхода собирается ответ из 5 или 10 первых совпадений и возвращает результат назад запросившему пользователю.
 - Если запросивший пользователь активный, то ему посылается UDP пакет на указанный порт (собственно поэтому если юзер думает что он активный и UDP порт закрыт - не работает поиск)
 - Если запросивший юзер пассивный, то ответ идет по TCP на хаб с указанием ника кому форварднуть ответ о том, что по его запросу найдены файлы.

Проблема не эффективного потребления CPU в DC++ клиентах возникает когда владелец толстой шары сидит на более чем 1 хабе.

Возьмем наш лог из CMD отладчика (FlylinkDC++ недавно научился его сохранять в файл по галке в настройках)
и выберем строки где идет поиск по подстроке Unforgettable
Обратите внимание на временные метки и адреса хабов с которых приходили запросы.
Получается что за секунду прилетело 7 одинаковых(!) запросов от одного юзера
совместно с вами сидящем на разных хабах (рис 2)
По текущему алгоритм клиент получив эти запросы в разных потоках обслуживающих эти хабы
по очереди обращается к менеджеру шары и постоянно ищет одно и то-же.
Если bloom фильтр не отрубает эту подстроку на входе, то затраты на поиск возрастают пропорционально кол-ву файлов и каталогов в шаре.
 










я внес мелкое исправление https://code.google.com/p/flylinkdc/source/detail?r=17886#
в менеджер шары флайлинка где попытался убрать эту лишнюю нагрузку
с помощью заведение дополнительной хеш-таблицы.

Алгоритм работы такой:
1. Получаем запрос на поиск подстроки от клиента-1 и выполняем рекурсивный поиск. Если не находим ее в шаре сохраняем строку  в хеш-таблице.
2. С большой вероятностью в течении секунды к нам в менеджер шары прилетает еще таких-же запросов от клиентов 2-N
перед тяжелым рекурсивным обходом дерева - мы смотрим в нашу промежуточную табличку по ключу - подстрока поиска если находим ее там - сразу уходим т.к. в нашей шаре такого объекта не нашлось и мы это определили на шаге (1)
3. Если в вашу шару добавляются файлы - деваться некуда чистим эту временную мапу
4. На минутном таймере смотрим размер этой таблицы и если он больше 1000 - тоже чистим
    число 1000 выбрал с потолка - на выходных потестю подробнее но лимит нужен чтобы не утекала память при большом кол-ве разных запросов.

Новой бетки с этими изменениями пока нет - появится вечером.
Желающие могут покритиковать-улучшить алгоритм т.к. возможно я что-то не учел.
не хочется сломать ключевую функцию клиента - поиск который и так из за NAT-работает не очень :-)

 

воскресенье, 16 ноября 2014 г.

FlylinkDC++ и Visual C++ 2013

Планирую перейти на VC++2013
в автообновление пока не помещал - просьба протестировать новый билд и отписать о результатах
http://www.fly-server.ru/install/r5xx/src-bin/r503-vc2013
в Favorites.xml 483 - хаба  - ввизуально стартует быстрее и памяти немного меньше кушает

Размер FlylinkDC_x64.exe 12407968 (VC++2010)

RAM - 333 Mb











Размер FlylinkDC_x64.exe 11805856 (VC++2013)
RAM -  318 Mb

 

пятница, 7 ноября 2014 г.

Автоматический переход в пассивный режим.

Привет.
В последней бетке реализован автоматический _временный_ переход в пассивный режим если не смогли скачать в активном.
для теста можете авто обновиться или забрать бинарники 
тут http://www.fly-server.ru/install/r5xx/src-bin/

Алгоритм работы:
* Если клиент настроен как "активный" а по факту порты закрыты (мешает NAT, программный фаервол) 
   при попытке подключиться к пользователю по команде $ConnectToMe - клиент бесконечно висел в ожидании.
   неподготовленный пользователь в этом случае - сносил FlylinkDC++ :)
* Сейчас после 60 секунд ожидания клиент переходит в пассивный режим и повторяет попытку подключения 
  через команду $RevConnectToMe
* Если попытка удалась - происходит скачка контента при этом в прогрессе рисуется "кирпичная стенка"
* После завершения операции клиент возвращается в активный режим.
Кто разбирается в протоколе - подскажите какие проблемы вы видите в этом случае.
Пока пришлось выполнять посылку команды $MyINFO сообщающей хабу
что мы перешли в пассив - это сделано для Verlihub хотя другие хабы 
в частности PtokaX не требуют этой посылки и принимают команду $RevConnectToMe 
даже если клиент ранее сообщил что он активный.
мне это не совсем нравится т.к .приводит к лишнему спаму MyINFO туда-сюда...
что может привести к блокировке юзера на хабе напичканы хитрыми скриптами...
обычно нельзя часто слать MyINFO - от спама даже в клиенте есть защита на 2 минут.
пишите в комментарии или подрубайтесь к хабу dchub://dc.fly-server.ru
там можно анонимно пообщаться :)

суббота, 11 октября 2014 г.

DDoS атака на сервера флайлинка

Всем привет.
9-10 числа были перебои с обновлением FlylinkDC++
а также не работал DHT bootstrap сервер.
Причина: атака анонимных "хакеров" они положили сразу два VPS сервера
на третий media.fly-server.ru или сил не хватило, или в digitalocean
есть встроенная защита от DDoS
http://www.fly-server.ru/munin/www/localdomain/localhost.localdomain/fw_conntrack.html
http://109.120.164.244/munin/localdomain/localhost.localdomain/fw_conntrack.html




























Почти все сервисы, которые сломали атакой перевел на другой сервер
если заметите баги или тормоза пишите на почту pavel.pimenov@gmail.com

Новый сервер не использует виртуализацию
он не очень мощный, но думаю для авто обновления ресурсов хватит
http://37.187.111.84/munin/localdomain/localhost.localdomain/index.html



четверг, 2 октября 2014 г.

Вирусы - подсказываем зараженный каталог

Добрый вечер!
Начиная с билда 17658 у FlylinkDC++ ветки r5xx 
добавлена визуализация зараженного каталога
у подозрительного пользователя:










новая версия доступна на канале авто обновления (beta)
или портабельные сборки тут  http://www.fly-server.ru/install/r5xx/src-bin
FlylinkDC-r503-x64-beta95-build-17658-2014.10.02-23.30.54.7z
FlylinkDC-r503-src-beta95-build-17658-2014.10.02-23.18.57.7z
FlylinkDC-r503-x86-beta95-build-17658-2014.10.02-23.18.11.7z

вторник, 9 сентября 2014 г.

FlylinkDC++ интеграция c Antivirus DB

Всем привет.
Начиная с build 17552 добавлена экспериментальная поддержка детектирования
пользователей-ботов  потенциальных распространителей вирусов (рис 1)
базу данных "носителей" пополняют в автомате крупные хабы использующие verlihub 
пока флайлинк только отмечает подобных юзеров в списке.
после тестирования планирую предупреждать о потенциальной опасности и запрещать:
1. Скачку файл-листов с таких пользователей
2. Скачку файла из поиска если файл находится в шаре такого пользователя.

Детект подозрительных пользователей осуществляется по 3-критериям
1. Совпал ник
2. Совпал IP
3. Совпал размер шары

Пишите замечания/предложения.
новая версии доступна через авто-обновление 
или тут http://www.fly-server.ru/install/r5xx/src-bin


 
 

среда, 30 июля 2014 г.

sqlite 3.8.5 некорректная работа distinct

Недавно в FlylinkDC++ r5xx я немного изменил структуру таблицы для хранения дерева TTH
требовалось добавлени дополнительного поля + уникальность.
натолкнулся на странное поведение CREATE UNIQUE INDEX если в таблице уже есть данные.
  • Уникальный индекс почему-то построился если есть дубликаты.
  • Не корректно работает distinct
Минмальный тест:
sqlite3 --version
3.8.5 2014-06-04 14:06:34 b1ed4f2a34ba66c29b130f8d13e9092758019212

sqlite3.exe FlylinkDC.sqlite < test-uniq-3.sql
CREATE TABLE fly_hash_block(tth_id integer PRIMARY KEY NOT NULL, tth number NOT NULL);
INSERT INTO fly_hash_block VALUES(1,1);
INSERT INTO fly_hash_block VALUES(2,2);
INSERT INTO fly_hash_block VALUES(3,2);
CREATE UNIQUE INDEX iu_fly_hash_block_tth ON fly_hash_block(tth);
select * from fly_hash_block;
1|1
2|2
3|2
select distinct tth from fly_hash_block;
1
2
2
select tth,count(*) from fly_hash_block group by tth;
1|1
2|2

в sqlite пришел после Oracle - возможно что-то не учел...
по-моему Oracle в данном случае ведет себя адекватнее:

SQL>
SQL> CREATE TABLE fly_hash_block(tth_id integer PRIMARY KEY NOT NULL, tth number NOT NULL);
Table created
SQL> INSERT INTO fly_hash_block VALUES(1,1);
1 row inserted
SQL> INSERT INTO fly_hash_block VALUES(2,2);
1 row inserted
SQL> INSERT INTO fly_hash_block VALUES(3,2);
1 row inserted
SQL> CREATE UNIQUE INDEX iu_fly_hash_block_tth ON fly_hash_block(tth);
CREATE UNIQUE INDEX iu_fly_hash_block_tth ON fly_hash_block(tth)
ORA-01452: CREATE UNIQUE INDEX невозможно; найдены дублирующиеся ключи
SQL> select * from fly_hash_block;
                                 TTH_ID        TTH
--------------------------------------- ----------
                                      1          1
                                      2          2
                                      3          2
SQL> select distinct tth from fly_hash_block;
       TTH
----------
         1
         2
SQL> select tth,count(*) from fly_hash_block group by tth;
       TTH   COUNT(*)
---------- ----------
         1          1
         2          2

Если индекс построить на пустой таблице, то все хорошо - он запрещает попытку нарушения уникальности при вставке:

CREATE TABLE fly_hash_block(tth_id integer PRIMARY KEY NOT NULL, tth number NOT NULL);
CREATE UNIQUE INDEX iu_fly_hash_block_tth ON fly_hash_block(tth);
INSERT INTO fly_hash_block VALUES(1,1);
INSERT INTO fly_hash_block VALUES(2,2);
INSERT INTO fly_hash_block VALUES(3,2);
Error: near line 6: UNIQUE constraint failed: fly_hash_block.tth
select * from fly_hash_block;
1|1
2|2
select distinct tth from fly_hash_block;
1
2
select tth,count(*) from fly_hash_block group by tth;
1|1
2|1


Кто знает причину такого поведения?
может какой прагмы не хватает...
хотя с distinct 100% явный баг в движке - отписал разработчикам sqlite пример.

UPD: разработчики sqlite приняли баг у себя в треккере:
 http://www.sqlite.org/src/info/9a6daf340df99

пятница, 18 июля 2014 г.

SQLite - ручной ремонт базы данных

Всем привет.
Иногда в результате сбоя (обычно по питанию) "ломается" база данных и как правило ломается
центральный файл FlylinkDC.sqllite и программа FlylinkDC++ падает с сообщением
об ошибке вида - SQLIte database disk image is malformed 

Автоматического ремонта у меня пока нет.
расскажу как можно сделать это руками 

1. Закрываете флайлинк
2. Качаете консольную утилиту sqlite3.exe последней версии тут http://sqlite.org/download.html (Precompiled Binaries for Windows)

    на сегодня это вот такая версия: http://sqlite.org/2014/sqlite-shell-win32-x86-3080500.zip
3. Раскрываете архив рядом с FlylinkDC.sqllite (там должен появиться файл sqlite3.exe)

4. Создаете резервный архив файлов *.sqlite
5. Cоздаете рядом бат-файл repair-sqlite.bat с содержимым

echo PRAGMA integrity_check; | sqlite3.exe FlylinkDC.sqlite
sqlite3.exe FlylinkDC.sqlite .dump > FlylinkDC.sql
sqlite3.exe FlylinkDC-new.sqlite < FlylinkDC.sql
echo PRAGMA integrity_check; | sqlite3.exe FlylinkDC-new.sqlite
ren FlylinkDC.sqlite FlylinkDC-old.sqlite
ren FlylinkDC-new.sqlite FlylinkDC.sqlite
del FlylinkDC.sql
pause


6. Запускаете repair-sqlite.bat он попытается починить базу данных.
7. После завершения батника запускаете флайлинк.
8. Сообщаете об успешном/не успешном лечении.
 
У меня на битом файле прошло вот так:

C:\!dc-db\db-sqlite-corrupt\db-bug-3>echo PRAGMA integrity_check;  | sqlite3.exe FlylinkDC.sqlite
*** in database main ***
On tree page 55555 cell 56: Rowid 8246430 out of order (max larger than parent max of 8246390)
On tree page 67284 cell 69: Rowid 8246524 out of order (max larger than parent max of 8246478)
Page 67283: btreeInitPage() returns error code 11
Error: near line 1: database disk image is malformed
C:\!dc-db\db-sqlite-corrupt\db-bug-3>sqlite3.exe FlylinkDC.sqlite .dump  1>FlylinkDC.sql
C:\!dc-db\db-sqlite-corrupt\db-bug-3>sqlite3.exe FlylinkDC-new.sqlite  0C:\!dc-db\db-sqlite-corrupt\db-bug-3>echo PRAGMA integrity_check;  | sqlite3.exe FlylinkDC-new.sqlite
ok
C:\!dc-db\db-sqlite-corrupt\db-bug-3>ren FlylinkDC.sqlite FlylinkDC-old.sqlite
C:\!dc-db\db-sqlite-corrupt\db-bug-3>ren FlylinkDC-new.sqlite FlylinkDC.sqlite
C:\!dc-db\db-sqlite-corrupt\db-bug-3>del FlylinkDC.sql
C:\!dc-db\db-sqlite-corrupt\db-bug-3>pause
 


Если ругается на другой файл БД - в батнике ставим его имя по аналогии.
  • FlylinkDC_user.sqlite
  • FlylinkDC_stat.sqlite
  • FlylinkDC_mediainfo.sqlite
  • FlylinkDC_log.sqlite
  • FlylinkDC_locations.sqlite
  • FlylinkDC_dht.sqlite

суббота, 28 июня 2014 г.

SQLite - оптимизация выборки страны по IP (GeoIP)

Всем привет.
Нашел статью проверил на sqlite, действительно быстрее.
c ревизии  r17333 в ветке r5xx ускорена выборка флага страны
данный запрос выполняется при первой отрисовке флага страны в колонке "расположение"
а также выполняется для всех записей если по этой колонке делают сортировку.








Тестовая база данных и запросы тут https://yadi.sk/d/l6ovbUUDV4iKQ
Изменения (было - стало)



Результат:
 

четверг, 19 июня 2014 г.

Обновите FlylinkDC++ 2011-2014 года выпуска

Всем привет.
Приношу извинения  пользователям программы FlylinkDC++
Рекомендую обновиться до последней версии. 
Сделать это можно следубщими способами:
1. Через автообновление (Меню-Помощь-Проверка обновлений) (рис 1)
2. Скачать инсталлятор http://www.fly-server.ru/install/r5xx/release и выполнить установку "поверх"
3. Скачать бинарник и заменить FlylinkDC*.exe руками
    http://www.fly-server.ru/install/r5xx/src-bin


 





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











Падала программа  при условиях
  • Версия FlylinkDC++ r5xx находится между r8581 (Ноябрь 2011 год) и r17307  
  • Открыты окна "завершенных скачиваний" или "завершенных отдач"
  • При своей работе программа отдала или скачала больше 1000 файлов
   Для ускорения падения можно уменьшить это значение тут

среда, 11 июня 2014 г.

FlylinkDC++ и DHT


Новые версии доступны по авто обновлениях или тут
http://www.fly-server.ru/install/r5xx/src-bin
* Обновление OpenSSL 1.0.1h
* Добавлена кнопочка слева от окна загрузок "Спасательный круг" для включения пассивного режима
  так будет проще советовать что нажать когда у юзера ничего не качает.














* Исправлен алгоритм запроса к DHT серверу - не выполняем его чаще чем раз в 60 cек
* Добавлено логирование DHT - запросов на стороне клиента
  планирую детальнее разобраться как это работает и сделать лучше :)
  кто найдет в логах клиента косяки - пишите.
  текущая версия серверной части вяло обсуждается тут 
  http://dchublist.ru/forum/viewtopic.php?f=10&t=1109&start=25








* Возможно исправил падения 
 

среда, 21 мая 2014 г.

Эротика размером 8 589 934 592 Гб

Всем привет.
Прислали глючную базу данных с очередью закачек FlylinkDC.sqlite
в которой один файл никогда не мог скачаться
по названию это видео с TTH - LATTKRBYGFCTQNZRGA4DKNKFGA4DENJSIZBEMOA
интересным названием и размером 9223372036854776000! байт 
на своих хабах я такого TTH не смог найти...










Версии
 Ошибка во флайлинке и он где-то портит размер файла.
 поле TempTarget - пустое... это означает, что флай не смог создать временный файл такого размера.
 Возможно кто-то создал фейковый файл-лист и заставил юзера скачать такой файлик (повторить еще не пробовал)
Думаю для начала нужно наложить ограничение на размер файла в 16Tb? (лимит размера тома NTFS)
какие еще будут предложения по защите от подобного, или может есть более точные версии как такое могло произойти?