Спустя некоторе время функция GrdFind() перестает обнаруживать ключ

Здравствуйте у нас имеется приложение, работающее на ОС Linux ROSA. Приложение многопоточное. Защита организована на ключах Guardant Code Time. Приложение периодически проверяет наличие ключа и лицензию, функциями GrdCheck() и GrdCodeRun(). Если функция GrdCheck() возвращает ошибку, выполняется повторный поиск ключа функцией GrdFind(), а затем снова GrdCheck() и GrdCodeRun(). Так вот возникает следующая проблема: функция GrdCheck() иногда возвращает ошибку 71 («Guardant API Must be initialized») после чего выполняется GrdFind() ключ снова обнаруживается и дальше все прекрасно работает, а иногда функция GrdCheck() возвращает ошибку 1 («Dongle with specified search conditions not found») после чего функция GrdFind() начинает выполнятся по 10 секунд и возвращает ошибку 36 («All dongles found») и больше не может обнаружить ключ даже после перезапуска приложения. Для решения проблемы помогает только вынимание ключа из USB порта и подключение его снова.  Подскажите в чем может быть проблема.

Re: Спустя некоторе время функция GrdFind() перестает обнаруживать ключ

Здравствуйте. Пришлите полный отчет утилиты диагностики и тестовый пример кода на hotline@guardant.ru

Re: Спустя некоторе время функция GrdFind() перестает обнаруживать ключ

Здравствуйте, утилита диагностики как я понял работает только на ОС Windows, а у нас используется Linux. По поводу примера, код достаточно емкий использующий множество сторонних библиотек к тому же политика организации не позволяет передавать исходные коды. Вы можете хотя бы направление дать в каких случаях функия GrdFind() не обнаруживает подключенный ключ и замирает при этом на 10 секунд. Утилита lsusb при возникновении данной проблемы отображает наличие ключа Guardant.

Re: Спустя некоторе время функция GrdFind() перестает обнаруживать ключ

Если совсем нет возможности получить отчет диагностики на Windows, то можно собрать консольную утилиту из исходников под нужный дистрибутив Linux. Скачать ее можно на нашем форуме.

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

1. Если используется один handle на все потоки, то можно попробовать лочить его мьютексом пока выполняется GrdCodeRun. Либо в каждом потоке создавать отдельный хэндл
2. Если в каждом потоке отдельный handle, то надо наоборот попробовать держать один хэндл на все потоки

Есть вероятность что в одном из этих кейсов проблема уйдет.

ОБРАТИТЬ ВНИМАНИЕ

- Надо убедиться, что GrdFind и GrdLogin ищут только локальные ключи
- Нет смысла в рабочем приложении использовать GrdFind, т.к. он больше нужен чтобы перебрать все ключи в системе и составить список, причем не требует указания кодов доступа. Нужно использовать GrdLogin, поскольку эта функция уже будет искать конкретный ключ по параметрам, заданным для GrdSetFindMode и логиниться к нему, если найдет
- Как раз вы не описали в какой момент выполняется GrdLogin? В случае сбоя до ее вызова, видимо, дело не доходит
- Еще интересно в каком режиме используете ключи, USB или HID?

Re: Спустя некоторе время функция GrdFind() перестает обнаруживать ключ

Собрали утилиту chknsk, вот ее вывод на работающем ключе (поля ID и Public Code изменены):

Welcome to Guardant Diagnostic Tool! (v1.0001)       

Detecting Guardant dongles ...

------------- Guardant Code Time Dongle ---------------------------------------
  Produce Date (dd.mm.yy):                      21.05.2019 (ID=0xXXXXXXXX)     
  Versions (Hrw,MCUF,Type,PrtSup,Std,Cl,DSt):   0.1,00,5F0,00,00,0.0,0         
  Supports:                                     PI,TRU,RTC,AES,ECC,CODE       
  Global Flags:                                 PTIME,HID                     
  Public Code:                                  XXX_XXX (0xXXXXXXXX)           
-------------------------------------------------------------------------------
Firmware  ProgNum  Version  SerialN GPcounter  Mask   NetRes RealRes  Index   
-------------------------------------------------------------------------------
1.0.2.21        0        1      104         0  0000h       0       0 00000000
-------------------------------------------------------------------------------
Result: 1 dongle(s) found. Press Enter...

Подождем когда ключ зависнет вновь и снова попытаемся ее выполнить.

По поводу хендлов. У нас используется первый описанный вами вариант. Над библиотекой grdapi написана дополнительная библиотека, которая работает непосредственно с ключем, в ней используется однин хендл. Перед выполнением любой функции GrdAPI происходит блокировка семафором, а вызовы фунукций GrdCodeRun дополнительно огорожены функциями GrdLock, GrdUnlock. Так же хотелось бы отметить, что обращение к ключу идет из нескольких процессов, в некоторых из них и из разных потоков.

Функции GrdFind и GrdLogin обращаются только к локальным ключам, так как перед их вызовом выполняется функция:
GrdSetFindMode(keyHandle, GrdFMR_Local, GrdFM_Type, 0, 0, 0, 0, 0, GrdDT_RTC, GrdFMM_CodeUSB, GrdFMI_USB);
Для поиска ключа мы действительно используем функцию GrdFind, а GrdLogin уже выполняется после успешного выполнения GrdFind. Учтем ваше предложение по поводу удаления функции GrdFind из кода, спасибо.
Мы провели эксперимент: после того как ключ уже находился в "зависшем" состоянии, было написано тестове приложение, в котором вместо вызова функции GrdFind была использована функция GrdLogin, но ее  выполнение так же происходит с ошибкой до тех пор пока не передернешь физически ключ.

Еще провели небольшой эксперимент на предмет того, что зависает ключ или драйвер. При "зависшем" ключе перезагрузили ПК, при этом с помощью осциллографа убедились, что питание на USB в момент перезагрузки не обрывалось. Так вот после перезагрузки ключ прекрасно начал работать, т.о. предположительно что-то в драйвере ключа происходит.

Ключи у нас работают в HID режиме.

Re: Спустя некоторе время функция GrdFind() перестает обнаруживать ключ

Вчера вечером ключ завис вот лог утилиты с зависшим ключем:

Welcome to Guardant Diagnostic Tool! (v1.0001)       

Detecting Guardant dongles ...

Result: 0 dongle(s) found. Press Enter...

Причем функция Detecting Guardant dongles ... длилась около 23 секунд

Все время было запущено тестовое приложение которое обращалось к ключу и вот сейчас когда я решил снова замерить время работы утилиты chknsk и она вдруг обнаружила ключ. Посмотрел логи работы нашей тестовой утилиты, после многих неудачных попыток функция GrdLogin вдруг снова стала работать. Зависание продлилось с 20:03 вчерашнего дня по 10:45 сегодняшнего дня т.е. около 15 часов. Ключ вроде бы не трогали. Первыий раз такое "отвисание" произошло.

Re: Спустя некоторе время функция GrdFind() перестает обнаруживать ключ

Большое спасибо за предоставляемые данные ваших тестов!
Сейчас первое, что еще нужно проверить, это работа ключа в драйверном режиме!

Для пользователя защищенного приложения, с точки зрения трудозатрат на настройку ключа в Linux, разницы не будет абсолютно, т.е. также нужно установить правило для udev и подключить ключ.

Переведите, пожалуйста, ключ в драйверный режим и также потестируйте.

Re: Спустя некоторе время функция GrdFind() перестает обнаруживать ключ

Перепрошили ключ в драйверном режиме вот лог утилиты chknsk:

Welcome to Guardant Diagnostic Tool! (v1.0001)       

Detecting Guardant dongles ...

------------- Guardant Code Time Dongle ---------------------------------------
  Produce Date (dd.mm.yy):                      21.05.2019 (ID=0xXXXXXXXX)     
  Versions (Hrw,MCUF,Type,PrtSup,Std,Cl,DSt):   0.1,00,5F0,00,00,0.0,0         
  Supports:                                     PI,TRU,RTC,AES,ECC,CODE       
  Global Flags:                                 PTIME                         
  Public Code:                                  XXXXXXX (0xXXXXXXXX)           
-------------------------------------------------------------------------------
Firmware  ProgNum  Version  SerialN GPcounter  Mask   NetRes RealRes  Index   
-------------------------------------------------------------------------------
1.0.2.21        0        1      109         0  0000h       0       0 00000000
-------------------------------------------------------------------------------
Result: 1 dongle(s) found. Press Enter...

C 31.01.2020 по сегодняшний день 04.02.2020 ключ работает без зависаний, в логах тестовой утилиты не было ни одного сбоя функций GrdCheck и GrdLogin. Понаблюдаем еще.

Re: Спустя некоторе время функция GrdFind() перестает обнаруживать ключ

Здравствуйте. Сообщите нам пожалуйста результаты наблюдения.

Re: Спустя некоторе время функция GrdFind() перестает обнаруживать ключ

Отработало почти неделю без единого сбоя, тогда как в HID режиме работало максимум 2 дня и то с множеством сбоев, которые в конечном итоге приводили к "зависанию" ключа. Делаем вывод, что с HID режимом в ОС Linux есть какие-то проблемы. Будем прошивать ключи в драйверном режиме. Ваши разработчики могут, что-нибудь сказать по этому поводу? Производились тесты многопоточного доступа к ключу в HID режиме на ОС Linux?

Re: Спустя некоторе время функция GrdFind() перестает обнаруживать ключ

Здравствуйте. Мы провели тестирование, но нам не удалось воспроизвести такое поведение. На данный момент мы подозреваем, что проблема из-за GrdLock/GrdUnlock в HID-режиме под Linux, пытаемся подтвердить эту гипотезу.