Giter VIP home page Giter VIP logo

Comments (159)

orignal avatar orignal commented on May 18, 2024

С падением известная проблема "netDb doesn't exist". Там надо директорию netDb из официального клиента скопировать туда, откуда запускаете. Я это еще не успел починить.

Насчет поддержки Windows мне трудно что либо сказать, посколько я под него никогда в жизни не писал.
Насколько я понимаю, вы упретесь там в условные переменные.

ssize_t убирать одну s не следует потому что переменная может принимать отрицательные значения.

endian.h действительно специифична для Линукса, даже для FreeBSD нужно писать #include <sys/endian.h>. Собираюсь сделать заголовчный файл содержаший в себе все платформо-зависимые вещи.

Вообще если есть желание адаптировать проект для Windows, добро пожаловать - всегда буду рад помощи.

from i2pd.

orignal avatar orignal commented on May 18, 2024

Кстати собирать с помощью mingw не пробовали?

from i2pd.

chertov avatar chertov commented on May 18, 2024

Условные переменные это что в < condition_variable >, < condition_variable_any >? vs2013 их вроде бы умеет...

с помощью mingw не собирал (думаю он соберет), но хотелось бы чтобы и студия умела собирать, там вроде бы кроме спецификаторов default ничего такого принципиального не мешает сборке.

Под Windows смогу периодически собирать/проверять...
Хотел еще под андройд попробовать собрать в виде библиотеки и запустить, но там, надеюсь, еще проще получится.

Пробовал собрать под linux mint 64, использовал QtCreator в качестве среды, собрал, но бинарник не запускался... там какая-то путаница с бустом и крипт++ версиями библиотек видимо разные под 32 и 64 битные платформы понаставил...
Какой средой вы пользуетесь и под каким линуксом собираете?

from i2pd.

orignal avatar orignal commented on May 18, 2024

Вопрос с условными переменными это не вопрос компилятора, а ядра ОС. В виндах насколько я знаю используется функция WaitForSingleObject. По сути своей задача сводится к тому чтобы уложить поток спать до тех пор пока кто то его не разбудит (например пришедшие данные). Возможно что уже тоже реализовано.

Под андроид естественно соберется, только какой в этом смысл пихать C++-ый код в среду, изначально рассчитанную под джаву?

Собираю в gcc как под x86_64, так и под raspberry. Убунту и дебиан.

from i2pd.

mikhail4021 avatar mikhail4021 commented on May 18, 2024

chertov, в NetDb.cpp найди строчку:

RouterInfo * r = new RouterInfo (it1->path ().c_str ());

там проблема одна, не знаю как решить. Раз ты сам собирал, то у тебя видимо есть решение.

from i2pd.

chertov avatar chertov commented on May 18, 2024

Да, сделал вот так)

//std::string path_str = it1->path().string();
//RouterInfo * r = new RouterInfo(path_str.data());
RouterInfo * r = new RouterInfo(it1->path().string().data());

orignal, мне кажется ваша реализация будет куда эффективнее реализации на яве
мой, далеко не первой свежести, мобильник предпочел бы ее)

from i2pd.

orignal avatar orignal commented on May 18, 2024

Господа, у вас наверное буст более свежий. Они с какого то релиза (50-ого вроде) поменяли filesystem

from i2pd.

chertov avatar chertov commented on May 18, 2024

я собирал последний 1.55... там у них было раньше несколько версий filesystem v2 v3... можно было девфайном выбрать какой использовать

from i2pd.

mikhail4021 avatar mikhail4021 commented on May 18, 2024

похоже на то, что свежий. Но это же не значит, что нам нужно ограничиться от 1_46 до 1_50 =)
просто придется чуть-чуть подумать

from i2pd.

chertov avatar chertov commented on May 18, 2024

где в проекте vs2013 переменные задать можно? $(BOOST), $(CRYPTOPP) их значения

from i2pd.

mikhail4021 avatar mikhail4021 commented on May 18, 2024

ну вообще я сделал по обычной практике. Определяешь переменные среды $(BOOST), $(CRYPTOPP) к соответствующим папочкам, и все работает.

from i2pd.

chertov avatar chertov commented on May 18, 2024

Это прямо в системе? Там есть user-defined macros в них смотрю пусто. Лучше тоже так сделаю... пишу в основном в 2008... там все по-другому)

from i2pd.

orignal avatar orignal commented on May 18, 2024

Но это же не значит, что нам нужно ограничиться от 1_46 до 1_50
У меня была лучшая идея его выкинуть нафик поскольку он там не особо нужен - только по директориям при чтении netDb ходить.

from i2pd.

mikhail4021 avatar mikhail4021 commented on May 18, 2024

Это прямо в системе?

да прямо в винде. я обычно "Переменные среды пользователя" определяю, но можно и системные переменные в принципе.

from i2pd.

mikhail4021 avatar mikhail4021 commented on May 18, 2024

ssize_t предлагаю заменить на int64_t

from i2pd.

orignal avatar orignal commented on May 18, 2024

Да можно просто на int. Это ж в одном месте где нужно от указателя идти в отрицательном направлении.

from i2pd.

mikhail4021 avatar mikhail4021 commented on May 18, 2024

ptrdiff_t там же разность указателей

from i2pd.

orignal avatar orignal commented on May 18, 2024

Кстати по поводу разных бустов. Можно использовать #ifdef BOOST_VERSION > 10500

from i2pd.

chertov avatar chertov commented on May 18, 2024

я бы еще вынес проект vs2013 в отдельную папку, а то она там создает "мусор"... в отдельную папку и .gitignore настроить

from i2pd.

orignal avatar orignal commented on May 18, 2024

Убедительная просьба не тащить буст без особой необходимости, а стараться использовать функции из std. Убрал зависимость от boost::thread

from i2pd.

orignal avatar orignal commented on May 18, 2024

Действительно файлы используемые только для компиляции под windows имеет смысл вынести в отдельную папку, а именно: файлы проекта, I2PEndian.cpp и LittleBigEndian.h

from i2pd.

mikhail4021 avatar mikhail4021 commented on May 18, 2024

про I2PEndian.cpp и LittleBigEndian.h не согласен. только неудобства
создавать. Остальное скоро вынесу.

2014/1/10 orignal [email protected]

Действительно файлы используемые только для компиляции под windows имеет
смысл вынести в отдельную папку, а именно: файлы проекта, I2PEndian.cpp и
LittleBigEndian.h

Reply to this email directly or view it on GitHubhttps://github.com//issues/5#issuecomment-32023800
.

from i2pd.

orignal avatar orignal commented on May 18, 2024

Я бы лично создал файл platform.h содежащий #include <endian.h> и #include <inttypes.h> для юниксов и I2PEndian.h и соотвествующий бустовской файл для windows и включал бы его вместо все платформо-зависимых хэдеров.Такой подход позволил бы с одной столроны легко добавлять новые платформы, а с другой стороны платформо-зависимые вещи.

Кстати нужели под windows нет Makefile-ов, т.е. зачем только чтобы скомпилировать нужно запускать IDE и открывать проект? А как тогда билд системы работают?

from i2pd.

chertov avatar chertov commented on May 18, 2024

Из более-менее удобного есть cmake... он сам сделает проект для разных версий IDE на разных платформах, скомпилит тем что найдет, но вообще достаточно часто вижу кросплатформенные либы, которые тащат за собой файл проекта студии в отдельной папке. Для меня это нормально... я привык всегда работать из IDE.
И, кстати, проект с cmake сейчас удобно вести в Qt Creator. Компилить он его сможет компилятором от vs2013, либо каким-то другим.
Собрать проект студией можно и не открывая ее. Для прогона тестов, например.

from i2pd.

mikhail4021 avatar mikhail4021 commented on May 18, 2024

это все здорово, но я, например, за cmake не возьмусь

2014/1/10 chertov [email protected]

Из более-менее удобного есть cmake... он сам сделает проект для разных
версий IDE на разных платформах, скомпилит тем что найдет, но вообще
достаточно часто вижу кросплатформенные либы, которые тащит за собой файл
проекта студии в отдельной папке. Для меня это нормально... я привык всегда
работать из IDE.
И. кстати, проект с cmake сейчас удобно вести в Qt Creator. Компилить он
его сможет компилятором от vs2013, либо каким-то другим.

Reply to this email directly or view it on GitHubhttps://github.com//issues/5#issuecomment-32042325
.

from i2pd.

orignal avatar orignal commented on May 18, 2024

Лично мне в этих всех IDE не нравится понятие проекта, в котором смешаны параметры для компиляции или линковки с настройками самой среды. А если завтра надумал использовать другую среду?

from i2pd.

mikhail4021 avatar mikhail4021 commented on May 18, 2024

кстати, по поводу надумывания. Может растащить это дело на статическую
библиотеку и сам роутер. или не нужно это?

2014/1/10 orignal [email protected]

Лично мне в этих всех IDE не нравится понятие проекта, в котором смешаны
параметры для компиляции или линковки с настройками самой среды. А если
завтра надумал использовать другую среду?

Reply to this email directly or view it on GitHubhttps://github.com//issues/5#issuecomment-32043528
.

from i2pd.

orignal avatar orignal commented on May 18, 2024

Статическую библиотеку чего именно? Вынести создание потоков куда то наружу или что?
Сейчас по сути своей роутера как такового еще нет, есть примитивый файл i2p.cpp который в дальнейшем будет запускать демона.

from i2pd.

mikhail4021 avatar mikhail4021 commented on May 18, 2024

я сам еще не до конца понял по коду, это может куда-то быть воткнуто еще
как клиент? Описания никакого нет, того что сделано.

2014/1/10 orignal [email protected]

Статическую библиотеку чего именно? Вынести создание потоков куда то
наружу или что?
Сейчас по сути своей роутера как такового еще нет, есть примитивый файл
i2p.cpp который в дальнейшем будет запускать демона.

Reply to this email directly or view it on GitHubhttps://github.com//issues/5#issuecomment-32046021
.

from i2pd.

orignal avatar orignal commented on May 18, 2024

Клиент на данный момент не планируется, планируется сделать обращение к I2P сайтам внутри класса HTTPServer, работающий по принципу анонимайзера. В дальнейшем возможно доступ через внешние сокеты.

from i2pd.

chertov avatar chertov commented on May 18, 2024

Мне нравится подход как сделали в cjdns. Там создается виртуальная сетевушка и ей присваивается ipv6 адрес, который является публичным ключом. Все что передается этому адресу внутри cjdns шифруется им, расшифровать может только обладатель приватного ключа, который сгенерировал этот ipv6 адрес.

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

Такой сетевой интерфейс можно вытащить на физический порт роутера и получится физическая сеть работающая исключительно в i2p.

from i2pd.

orignal avatar orignal commented on May 18, 2024

У I2P размер хэша 32-байта, а у ipv6 всего 16. Так что не получится.
Вот добавить свой протокол прямо в ядро лиункса это можно, я над этим уже думал.
Вообще суть вопроса тут такая. Сейчас есть два файла Streaming и NetDb, фактически являющиеся "точками входа" для всех клиентских задач. Класс Stream это логически аналог сокета, в который можно писать и читать передаваемые данные. Для его создания нужен LeaseSet той стороны, который берется из NetDb: либо он там уже есть либо его следует запросить.

from i2pd.

chertov avatar chertov commented on May 18, 2024

да, в это и уперся) делал демку под виндой, которая поднимала сетевой интерфейс и могла писать/читать из него пакеты. Но чтобы сопоставить однозначно ipv6 с i2p хэшем нужно как-то хитрить... рассматривал некоторое варианты, но если бы размеры адресов совпадали было бы практически идеально) В вики может страничку сделаю со своими идеями. В любом случае если будет удобная либа с "сокетами" i2p, то такую штуку можно реализовать отдельным проектом.

from i2pd.

orignal avatar orignal commented on May 18, 2024

Подскажите как сделать демона под windows, т.е. процесс работающий в фоновом режиме баз всякого интерфейса.
Собираюсь наконец сделать приложение демоном, но под windows вряд ли системный вызов fork есть.

from i2pd.

mikhail4021 avatar mikhail4021 commented on May 18, 2024

ну вообще это как-то так делается
http://code.msdn.microsoft.com/windowsdesktop/CppWindowsService-cacf4948

2014/1/19 orignal [email protected]

Подскажите как сделать демона под windows, т.е. процесс работающий в
фоновом режиме баз всякого интерфейса.
Собираюсь наконец сделать приложение демоном, но под windows вряд ли
системный вызов fork есть.

Reply to this email directly or view it on GitHubhttps://github.com//issues/5#issuecomment-32695380
.

from i2pd.

orignal avatar orignal commented on May 18, 2024

А можно как то попроще используя std там или boost?
Или может я сделаю для юникса, оставив место под #ifdef WIN32?

from i2pd.

mikhail4021 avatar mikhail4021 commented on May 18, 2024

на самом деле это самое простое, что есть. тут винапишные функции уже в
класс обернуты
проще только просто win32 приложение консольное сделать, но у него будет
окно.
если будет простой интерфейс типа run()/pause()/stop , то под винду я
наверное смогу доделать в #ifdef'е

2014/1/19 orignal [email protected]

А можно как то попроще используя std там или boost?
Или может я сделаю для юникса, оставив место под #ifdef WIN32?

Reply to this email directly or view it on GitHubhttps://github.com//issues/5#issuecomment-32695532
.

from i2pd.

orignal avatar orignal commented on May 18, 2024

А как официальный клиент выглядит? Как консольное приложение или как сервис?

from i2pd.

mikhail4021 avatar mikhail4021 commented on May 18, 2024

точно НЕ как консольное приложение. да и там же под джавамашиной все
работает, так что технология другая, и сравнивать не совсем правильно

2014/1/19 orignal [email protected]

А как официальный клиент выглядит? Как консольное приложение или как
сервис?

Reply to this email directly or view it on GitHubhttps://github.com//issues/5#issuecomment-32699481
.

from i2pd.

orignal avatar orignal commented on May 18, 2024

Кстати вы не пробовали запускать? На данный момент у меня весьма стабильно получает главную страницу Флибусты.
Надо:

  1. Скопировать директорию netDb из официального клиента туда откуда запускается.
  2. Доступ извне, потому что будут приходить входящие соединения. Добавить в функцию main первой строчкой i2p::context.OverrideNTCPAddress (<внешний IP>, <порт>); Потом сделаю чтение из конфиг файла.
  3. Смотреть браузером 127.0.0.1:7070. Если все правильно то там достаточно быстро будут появляться новые тоннели.
  4. Как только создадутся несколько входящих и несколько исходящих тоннелей нажать на ссылку Flibusta

Возможно придется сделать несколько попыток потому что скорее всего сначала будет сообщение "LeaseSet not found" но вскоре она его найдет и загрузить страницу.

from i2pd.

chertov avatar chertov commented on May 18, 2024

orignal, уууууу! Поздравляю!!!) Руки чешутся проверить под виндой, но пока не могу, к сожалению...

from i2pd.

chertov avatar chertov commented on May 18, 2024

По-быстрому скомпилил... вываливается в некоторых местах

При первом запуске

// Выдает когда читает что-то из netDb
// Unhandled exception at 0x75D0C41F in i2pd.exe: Microsoft C++ exception:
// CryptoPP::CryptoMaterial::InvalidMaterial at memory location 0x002EEFBC.

// из cryptlib.h
//  //! throws InvalidMaterial if this object fails Validate() test
//  virtual void ThrowIfInvalid(RandomNumberGenerator &rng, unsigned int level) const
//==>   {if (!Validate(rng, level)) throw InvalidMaterial("CryptoMaterial: this object contains invalid values");}

    void RouterInfo::ReadFromBuffer ()
    {
        std::stringstream str (std::string (m_Buffer, m_BufferLen));
        ReadFromStream (str);
        // verify signature
        CryptoPP::DSA::PublicKey pubKey;
        pubKey.Initialize (i2p::crypto::dsap, i2p::crypto::dsaq, i2p::crypto::dsag, CryptoPP::Integer (m_RouterIdentity.signingKey, 128));
        CryptoPP::DSA::Verifier verifier (pubKey);
        int l = m_BufferLen - 40;
 ====>  if (!verifier.VerifyMessage ((uint8_t *)m_Buffer, l, (uint8_t *)m_Buffer + l, 40))
        {   
            LogPrint ("signature verification failed");
        }   
    }   

еще при последующих запусках

// когда читает router.info  в   void RouterInfo::ReadFromFile (const char * filename)
// выкидывает 
/// Run-Time Check Failure #2 - Stack around the variable 'value' was corrupted.
void RouterInfo::ReadFromStream (std::istream& s)
{
...
// тут в конце 
===>  }

from i2pd.

mikhail4021 avatar mikhail4021 commented on May 18, 2024

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

from i2pd.

chertov avatar chertov commented on May 18, 2024

У меня тут "C:\Users\user\AppData\Roaming\I2P\netDb" лежит, отсюда ее кидал в рабочую папку где бинарник сохраняет router.info

from i2pd.

mikhail4021 avatar mikhail4021 commented on May 18, 2024

äÏÂÁ×ÉÔØ × ÆÕÎËÃÉÀ main ÐÅÒ×ÏÊ ÓÔÒÏÞËÏÊ i2p::context.

OverrideNTCPAddress (<×ÎÅÛÎÉÊ IP>, <ÐÏÒÔ>);

ÞÔÏ ÅÓÔØ "×ÎÅÛÎÉÊ IP"? ÎÅ ÐÏÎÑÌ × ËÁËÏÍ ËÏÎÔÅËÓÔÅ

2014/1/21 chertov [email protected]

õ ÍÅÎÑ ÔÕÔ C:\Users\user\AppData\Roaming\I2P\netDb ÌÅÖÉÔ, ÏÔÓÀÄÁ ÅÅ ËÉÄÁÌ
× ÒÁÂÏÞÕÀ ÐÁÐËÕ ÇÄÅ ÂÉÎÁÒÎÉË ÓÏÈÒÁÎÑÅÔ router.info

Reply to this email directly or view it on GitHubhttps://github.com//issues/5#issuecomment-32845696
.

from i2pd.

orignal avatar orignal commented on May 18, 2024

chertov, этот кусок с VerifyMessage можно временно закомментировать без ущерба для функциональности.
А вообще неплохо бы узнать чему равно значение переменной m_BufferLen в этот момент, возможно из-за ipv6 они стали слишком длинные и уже не влазят в 2K.
mikhail4021, в последнем сообщении вижу только крякозябры

from i2pd.

mikhail4021 avatar mikhail4021 commented on May 18, 2024

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

Добавить в функцию main первой строчкой i2p::context.OverrideNTCPAddress (<внешний IP>, <порт>);

чей внешний IP, я что-то не понимаю. мой?

from i2pd.

orignal avatar orignal commented on May 18, 2024

Да. Ваш. Я не знаю где у вас он - на вашем компе или где то на маршутизаторе. Если на маршутизаторе то надо пробросить какой нибудь порт к вам, если такой возможности нет то остается только ipv6.
Если маршутизатор поддерживает UPnP то будет работать по UDP по протоколу SSU, который я правда еще не сделал

from i2pd.

mikhail4021 avatar mikhail4021 commented on May 18, 2024

std::cout << m_BufferLen << "\n";
if (!verifier.VerifyMessage ((uint8_t *)m_Buffer, l, (uint8_t *)m_Buffer + l, 40))
{
LogPrint ("signature verification failed");
}

733 выводит, так что должно влазить

from i2pd.

orignal avatar orignal commented on May 18, 2024

И после этого сразу грохается?

from i2pd.

mikhail4021 avatar mikhail4021 commented on May 18, 2024
bool DL_GroupParameters_IntegerBased::ValidateElement(unsigned int level, const Integer &g, const DL_FixedBasePrecomputation<Integer> *gpc) const
{

const Integer &p = GetModulus(), &q = GetSubgroupOrder();

bool pass = true;
 ===> pass = pass && GetFieldType() == 1 ? g.IsPositive() : g.NotNegative();
pass = pass && g < p && !IsIdentity(g);

это кусок из CRYPT, после которого все падает. Вызывается в class DL_PublicKeyImpl:

bool Validate(RandomNumberGenerator &rng, unsigned int level) const
{
    bool pass = GetAbstractGroupParameters().Validate(rng, level);
    pass = pass && GetAbstractGroupParameters().ValidateElement(level, this->GetPublicElement(), &GetPublicPrecomputation());
    return pass;
}

почему так, пока не понял

from i2pd.

mikhail4021 avatar mikhail4021 commented on May 18, 2024

===> pass = pass && GetFieldType() == 1 ? g.IsPositive() : g.NotNegative();

в этот момент pass становится false

from i2pd.

orignal avatar orignal commented on May 18, 2024

Похоже я знаю в чем дело: скорее всего коструктор переменной i2p::data::context вызывается раньше чем инициализируются константы из CryptoConst.h

UPD: Починил

from i2pd.

chertov avatar chertov commented on May 18, 2024

сейчас попробую пересобрать...

from i2pd.

chertov avatar chertov commented on May 18, 2024

В консоль пишет signature verification failed, вылетает тут

    //! throws InvalidMaterial if this object fails Validate() test
    virtual void ThrowIfInvalid(RandomNumberGenerator &rng, unsigned int level) const
===>    {if (!Validate(rng, level)) throw InvalidMaterial("CryptoMaterial: this object contains invalid values");}

при чтении netDb\r0\routerInfo-0HRiZlDcB2eegk6sA0oreq3xQJSpoJacLmb141ROwfE=.dat

и как и раньше при последующих запусках

// когда читает router.info  в   void RouterInfo::ReadFromFile (const char * filename)
// выкидывает 
/// Run-Time Check Failure #2 - Stack around the variable 'value' was corrupted.
void RouterInfo::ReadFromStream (std::istream& s)
{
...
// тут в конце 
===>  }

from i2pd.

orignal avatar orignal commented on May 18, 2024

Удалите router.info и router.keys и запустите по новой. Это по поводу неверной подписи.

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

from i2pd.

chertov avatar chertov commented on May 18, 2024

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

from i2pd.

chertov avatar chertov commented on May 18, 2024

кажется нашел... ноут правда повис)

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

в RouterInfo.cpp, 44 строка

std::ifstream s(filename);
std::ifstream s(filename, std::ios::binary);

from i2pd.

orignal avatar orignal commented on May 18, 2024

Да конечно так оно и есть, в юниксах же нет этого дурацкого \r\n.
pull request сделайте

from i2pd.

chertov avatar chertov commented on May 18, 2024

у меня скомпилился, запустился, повис и даже процесс не убивается) ушел на ребут

сейчас подготовлю

from i2pd.

orignal avatar orignal commented on May 18, 2024

Я ж говорю наверное на условных переменных как надо не засыпает. Это смотреть и разбираться надо какой именно поток такую гадость делает.

from i2pd.

chertov avatar chertov commented on May 18, 2024

перезапускал, когда грузит файлы из netDb, то вываливается Stack around the variable 'value' was corrupted и еще какой-то переменной...

попробуй в main все закомментить и смотреть что не так по проядку...
как ловить эти условные переменные сейчас смутно представляю)

from i2pd.

chertov avatar chertov commented on May 18, 2024

есть кусок кода в void RouterInfo::ReadFromStream (std::istream& s)

char key[50], value[50];
r += ReadString (key, s);
s.seekg (1, std::ios_base::cur); r++; // =
r += ReadString (value, s); 
s.seekg (1, std::ios_base::cur); r++; // ;

использует функцию ReadString

    size_t RouterInfo::ReadString (char * str, std::istream& s)
    {
        uint8_t len;
        s.read ((char *)&len, 1);
        s.read (str, len);
        str[len] = 0;
        return len+1;
    }   

значение переменной len в дебаггере бывает достигает 86, какой-то длинный идентификатор версии, номера билда/сборки что ли...

from i2pd.

orignal avatar orignal commented on May 18, 2024

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

from i2pd.

chertov avatar chertov commented on May 18, 2024

странно выглядит... файл router.info
str получается "�caps=�LR;�coreVersion=�0.9.8.1;�netId=�2;�router.version=�0.9.8.1; start_uptime=�90m;"
значение len=86

также проскакивают в этом же файле значения len 204... строка аналогичного вида

from i2pd.

chertov avatar chertov commented on May 18, 2024

тупо увеличил везде буфферы до 500 вместо 50-ти...

//char key[50], value[50];
char key[500], value[500];

и оно начало работать)

248 routers loaded
Start listening port 17007
Creating zero hops inbound tunnel...
I2NP msg received len=545, type=23, msgID=0
VariableTunnelBuild
VariableTunnelBuild 1 records
Record 0 is ours
TransitTunnel gateway: 3700403565 created
I2NP msg received len=4370, type=23, msgID=555
VariableTunnelBuild
VariableTunnelBuild 1 records
VariableTunnelBuild reply for tunnel 575107807
TunnelBuildResponse 1 records.
Ret code=0
Inbound tunnel 575107807 has been created
I2NP msg received len=545, type=23, msgID=16777216
VariableTunnelBuild
VariableTunnelBuild 1 records
Record 0 is ours
TransitTunnel endpoint: 3807760356 created
TunnelGateway
TunnelGateway of 4625 bytes for tunnel 1840091100
Tunnel 1840091100 not found
Creating one hop outbound tunnel...
Connecting to 78.201.20.194:27989
Connected
Phase 1 sent: 288
Phase 2 received: 304
Phase 3 sent: 448
Phase 4 received: 48
NTCP session connected
Msg sent: 16
Msg sent: 656
Msg sent: 560
Pending tunnel build request 555 has not been responded. Deleted

на этом вылетело... вот тут:

            ~TunnelConfig ()
            {
                TunnelHopConfig * hop = m_FirstHop;

                while (hop)
                {
                    delete hop;
    ====>           hop = hop->next;
                }   
            }

from i2pd.

orignal avatar orignal commented on May 18, 2024

По поводу строки в RouterInfo: там вообще то перед каждым полем идет 1 байт с длиной строки, который и чиатается в переменную len.
86 это код символа 'V' - явно где то все съехало, возможно из-за как раз лишнего символа конца строки в windows.
На самом деле там сначала идут 2 байта длины всех эти свойств, а далеше уже поля, и похоже они где то потерялись.

from i2pd.

chertov avatar chertov commented on May 18, 2024

да, чувствуется... там в дебаггере в строке видны квадратики, сразу показалось что он их разбить не смог
перед этим 86 len было равно 0... ищу нестыковки...

                     delete hop;
====>           hop = hop->next;

стабильно падает... а так уже видел в браузере 7070 сервер, циферки и адрес флибусты!
хотелось бы ее сегодня увидеть)

from i2pd.

orignal avatar orignal commented on May 18, 2024

Там где падает это явная "детская" ошибка :) Уже починил. Перекомпилируйте.

from i2pd.

chertov avatar chertov commented on May 18, 2024

Ну и отлично! Работает не падает)
набирает на 7070 какие-то айпишники, на флибусте пока пишет LeaseSet not found
также пишет ошибки Read error: и Connect error:, текст квакозябрами... как вернуть нормальный кажется знаю

Долго он по времени может флибусту не открывать?

from i2pd.

orignal avatar orignal commented on May 18, 2024

Вы свой внешний IP прописали? А то у вас тоннели не будут создаваться по причине того что соседи не будут знать как до вас достучаться.
Смотрите что в консоли пишет - должно быть много "New RouterInfo added" потому что у вас сейчас сетевая база маленькая и будут постоянно обнаруживаться неизвестные узлы.
Флибусту он откроет когда найдет ее LeaseSet, а найдет он ее тогда когда обратится к floodfill-у, который про нее знает. Вообщем надо терпеливо запрашивать эту страницу. Когда найдет LeaseSet, то станет посылать запрос в тоннели, через несколько попыток дело закончится успехом и придет страница.
У меня примерно минуты через две после старта все получается, но у меня узлов много в базе.

from i2pd.

chertov avatar chertov commented on May 18, 2024

В консоль пишет иногда
Phase 1 sent: 288
Phase 2 read error: End of file. Wrong ident assumed

NTCP session terminated

3 routers deleted

А куда и как ip правильно прописать нужно и какой порт указать? Пробросить через роутер смогу...

Только что упало вот тут:

        while (hop)
        {
            EncryptBuildRequestRecord (*hop->router,
                CreateBuildRequestRecord (hop->router->GetIdentHash (), 
                    hop->tunnelID,
                    hop->nextRouter->GetIdentHash (), 
                    hop->nextTunnelID,
                    hop->layerKey, hop->ivKey,                  
                    hop->replyKey, hop->replyIV,
                    hop->next ? rnd.GenerateWord32 () : replyMsgID, // we set replyMsgID for last hop only
                    hop->isGateway, hop->isEndpoint), 
        ===>        records[i]);
            i++;
            hop = hop->next;
        }   

сообщение прочесть не успел...

from i2pd.

orignal avatar orignal commented on May 18, 2024

То что та сторона дает отлуп после первого сообщения скорее всего означает что этот узел устарел и на том IP уже сидит другой I2P адрес.Я такие узлы удаляю из базы - со временем все приходит в норму и большинство узлов становятся живыми.
Надо в main первой строчкой написать
i2p::context.OverrideNTCPAddress (<внешний IP>, <порт>);
IP адрес который у вас на роутере снаружи, порт можете выбрать любой, естественно пробрасываете его.

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

from i2pd.

chertov avatar chertov commented on May 18, 2024

Так, порты пробрасывал, но все равно не подключалось... зато нашел баги с загрузкой файлов

m_Timestamp = be64toh (m_Timestamp);

be64toh не преобразовывала нормально, версию endian.h с хабра заменил на ту что нашел (в первом сообщении топика ссылка)

from i2pd.

chertov avatar chertov commented on May 18, 2024

Также после долгой работы вылетела в NetDb.cpp, void NetDb::HandleDatabaseSearchReplyMsg (I2NPMessage * msg) вот тут:

            else
            {
                // no more requests for detination possible. delete it
                m_RequestedDestinations.erase (it);
    ===>        delete it->second;
            }   

from i2pd.

orignal avatar orignal commented on May 18, 2024

Что значит не подключилась?
С другими узлами соединяется? Тоннели создаются? Сообщения какие нибудь приходят?

from i2pd.

chertov avatar chertov commented on May 18, 2024

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

from i2pd.

orignal avatar orignal commented on May 18, 2024

Так на флибусту сразу зайти и не получится.
Сначала посмотрите насколько у вас увеличилось количество узлов в директории netDb.
Когда их станет достаточно много после очередной попытки зайти на флибусту вы увидите сообщение вроде этого LesetSet num=5. Потом уже будет быстро.

from i2pd.

chertov avatar chertov commented on May 18, 2024

под линуксом скомпилил на сервере... пришлось добавить в Makefile -lpthread в LDFLAGS, пробросил порт на винду и смотрел что там на 7070... флибуста открылась!
под линуксом падает (выкидывает Segmentation fault), запустил под дебагером, но под дебагером падать не хочет)

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

from i2pd.

orignal avatar orignal commented on May 18, 2024

Насчет Segmentation fault разершите создание core файлов командой ulimit -c unlimited. Когда грохнется снова то создастся файл core, потом его gdb i2p core и внутри команда where и будет понятно где. Я знаю что иногда грохается - не было времени посмотреть.

С серым IP в приниципе это не помеха, вы можете завести себе ipv6 адрес через тоннель, разумеется придется в нескольких местах поправить но принципиально ничего не поменяется. Сам этим еще не занимался потому что есть белый IP.

from i2pd.

chertov avatar chertov commented on May 18, 2024

Пробросил порт, работает! находит новые роутеры и добавляет, но есть две проблемы:

  1. видимо он сохраняет в netDb новые файлы... и сохраняются они криво, скорее всего опять с std::ios::binary что-то связано. При повторном запуске он не может их прочитать, пишет signature verification failed. Постараюсь пофиксить.

  2. Во время работы с чистой netDb находит роутеры, подключается, но падает в нескольких местах...
    в NetDb.cpp

        if (it != m_RequestedDestinations.end ())
        {   
            m_RequestedDestinations.erase (it);
478 ===>    delete it->second;
        }   

и в Garlic.cpp

        if (it != m_Sessions.end ())
        {
            m_Sessions.erase (it);
240 ===>        delete it->second;
        }
        GarlicRoutingSession * session = new GarlicRoutingSession (destination, 0); // not follow-on messages expected

from i2pd.

orignal avatar orignal commented on May 18, 2024
  1. Да он сохранят новые и удаляет недоступные/устаревшие раз в минуту
  2. Действительно так делать нельзя, после вызова erase итератор может показывать на что угодно, в линуксе видимо std::map реализован иначе. Поправлю.

from i2pd.

chertov avatar chertov commented on May 18, 2024

Флибуста открылась под виндой!) orignal, спасибо за прекрасную работу!

Починил баг с сохранением файлов в NetDB, там std::ofstream::binary мешал. Добавил вывод в консоли русских символов. Ошибки на русском теперь нормально пишет.
Работает уже минут 30, не падает! Загрузка процессора очень маленькая, памяти есть 5.5мб.
Заметил что при обновлении 127.0.0.1:7070 страничка обновляется с существенной задержкой. Главная страница со статистикой подвисает секунд на 5, иногда обновляется мгновенно. При этом в консоли активно выводится лог, нет ощущения что приложение тормозит, может отдельный поток чего-то ждет...

from i2pd.

orignal avatar orignal commented on May 18, 2024

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

P.S: Понял в чем дело: у вас там скорее всего еще где то запрос к Флибусте висит, там в запросе надо не подвешивать весь поток, а ждать асинхронно.

from i2pd.

chertov avatar chertov commented on May 18, 2024

после нескольких часов работы вылетел... вот колл стек:

    i2pd.exe!boost::asio::detail::win_iocp_socket_service_base::interlocked_compare_exchange_pointer(void * * dest, void * exch, void * cmp) Line 632
    i2pd.exe!boost::asio::detail::win_iocp_socket_service_base::close(boost::asio::detail::win_iocp_socket_service_base::base_implementation_type & impl, boost::system::error_code & ec) Line 176
    i2pd.exe!boost::asio::stream_socket_service<boost::asio::ip::tcp>::close(boost::asio::detail::win_iocp_socket_service<boost::asio::ip::tcp>::implementation_type & impl, boost::system::error_code & ec) Line 170
    i2pd.exe!boost::asio::basic_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >::close() Line 357
    i2pd.exe!i2p::ntcp::NTCPSession::Terminate() Line 53
    i2pd.exe!i2p::ntcp::NTCPSession::HandleReceived(const boost::system::error_code & ecode, unsigned int bytes_transferred) Line 370
    i2pd.exe!boost::_mfi::mf2<void,i2p::ntcp::NTCPSession,boost::system::error_code const &,unsigned int>::operator()(i2p::ntcp::NTCPSession * p, const boost::system::error_code & a1, unsigned int a2) Line 280
    i2pd.exe!boost::_bi::list3<boost::_bi::value<i2p::ntcp::NTCPSession *>,boost::arg<1>,boost::arg<2> >::operator()<boost::_mfi::mf2<void,i2p::ntcp::NTCPSession,boost::system::error_code const &,unsigned int>,boost::_bi::list2<boost::system::error_code const &,unsigned int const &> >(boost::_bi::type<void> __formal, boost::_mfi::mf2<void,i2p::ntcp::NTCPSession,boost::system::error_code const &,unsigned int> & f, boost::_bi::list2<boost::system::error_code const &,unsigned int const &> & a, int __formal) Line 393
    i2pd.exe!boost::_bi::bind_t<void,boost::_mfi::mf2<void,i2p::ntcp::NTCPSession,boost::system::error_code const &,unsigned int>,boost::_bi::list3<boost::_bi::value<i2p::ntcp::NTCPSession *>,boost::arg<1>,boost::arg<2> > >::operator()<boost::system::error_code,unsigned int>(const boost::system::error_code & a1, const unsigned int & a2) Line 103
    i2pd.exe!boost::asio::detail::binder2<boost::_bi::bind_t<void,boost::_mfi::mf2<void,i2p::ntcp::NTCPSession,boost::system::error_code const &,unsigned int>,boost::_bi::list3<boost::_bi::value<i2p::ntcp::NTCPSession *>,boost::arg<1>,boost::arg<2> > >,boost::system::error_code,unsigned int>::operator()() Line 129
    i2pd.exe!boost::asio::asio_handler_invoke<boost::asio::detail::binder2<boost::_bi::bind_t<void,boost::_mfi::mf2<void,i2p::ntcp::NTCPSession,boost::system::error_code const &,unsigned int>,boost::_bi::list3<boost::_bi::value<i2p::ntcp::NTCPSession *>,boost::arg<1>,boost::arg<2> > >,boost::system::error_code,unsigned int> >(boost::asio::detail::binder2<boost::_bi::bind_t<void,boost::_mfi::mf2<void,i2p::ntcp::NTCPSession,boost::system::error_code const &,unsigned int>,boost::_bi::list3<boost::_bi::value<i2p::ntcp::NTCPSession *>,boost::arg<1>,boost::arg<2> > >,boost::system::error_code,unsigned int> & function, ...) Line 70
    i2pd.exe!boost_asio_handler_invoke_helpers::invoke<boost::asio::detail::binder2<boost::_bi::bind_t<void,boost::_mfi::mf2<void,i2p::ntcp::NTCPSession,boost::system::error_code const &,unsigned int>,boost::_bi::list3<boost::_bi::value<i2p::ntcp::NTCPSession *>,boost::arg<1>,boost::arg<2> > >,boost::system::error_code,unsigned int>,boost::_bi::bind_t<void,boost::_mfi::mf2<void,i2p::ntcp::NTCPSession,boost::system::error_code const &,unsigned int>,boost::_bi::list3<boost::_bi::value<i2p::ntcp::NTCPSession *>,boost::arg<1>,boost::arg<2> > > >(boost::asio::detail::binder2<boost::_bi::bind_t<void,boost::_mfi::mf2<void,i2p::ntcp::NTCPSession,boost::system::error_code const &,unsigned int>,boost::_bi::list3<boost::_bi::value<i2p::ntcp::NTCPSession *>,boost::arg<1>,boost::arg<2> > >,boost::system::error_code,unsigned int> & function, boost::_bi::bind_t<void,boost::_mfi::mf2<void,i2p::ntcp::NTCPSession,boost::system::error_code const &,unsigned int>,boost::_bi::list3<boost::_bi::value<i2p::ntcp::NTCPSession *>,boost::arg<1>,boost::arg<2> > > & context) Line 37
    i2pd.exe!boost::asio::detail::win_iocp_socket_recv_op<boost::asio::mutable_buffers_1,boost::_bi::bind_t<void,boost::_mfi::mf2<void,i2p::ntcp::NTCPSession,boost::system::error_code const &,unsigned int>,boost::_bi::list3<boost::_bi::value<i2p::ntcp::NTCPSession *>,boost::arg<1>,boost::arg<2> > > >::do_complete(boost::asio::detail::win_iocp_io_service * owner, boost::asio::detail::win_iocp_operation * base, const boost::system::error_code & result_ec, unsigned int bytes_transferred) Line 97
    i2pd.exe!boost::asio::detail::win_iocp_operation::complete(boost::asio::detail::win_iocp_io_service & owner, const boost::system::error_code & ec, unsigned int bytes_transferred) Line 46
    i2pd.exe!boost::asio::detail::win_iocp_io_service::do_one(bool block, boost::system::error_code & ec) Line 404
    i2pd.exe!boost::asio::detail::win_iocp_io_service::run(boost::system::error_code & ec) Line 162
    i2pd.exe!boost::asio::io_service::run() Line 59
    i2pd.exe!i2p::Transports::Run() Line 86

from i2pd.

orignal avatar orignal commented on May 18, 2024

Понятно, там race condition, когда с одной стороны соединение закрывается и удаляется, а с другой стороны кто то пытается к нему обратиться.

from i2pd.

mikhail4021 avatar mikhail4021 commented on May 18, 2024

c:\users\mikhail\documents\github\i2pd\streaming.cpp(381): error C3861: 'htonll': identifier not found

вот что словил при компиляции

http://msdn.microsoft.com/en-us/library/windows/desktop/jj710199%28v=vs.85%29.aspx

а вот почему) там Minimum supported client Windows 8 [desktop apps only]
chertov, у вас там виндовс 8 чтоли? на 7ке не работает, там же в I2PEndian ровно это закомментировано было. Надо как-то чинить реализацию с хабра.

be64toh не преобразовывала нормально,

это прям точно?

from i2pd.

mikhail4021 avatar mikhail4021 commented on May 18, 2024

ладно, с бигиндиан я разобрался. но теперь тоже эта фигня

#5 (comment)

как понять что там мне из базы удалить, чтобы заработало?

from i2pd.

orignal avatar orignal commented on May 18, 2024

Ничего не надо удалять - сам догадается что те маршутизаторы неправильные и выкинет их.
Если ничего не находит то надо снова официальный клиент погонять некоторое время чтобы он перечитал базу и скопировать. Meeh начал заниматься тем чтобы и здесь это работало также.

from i2pd.

chertov avatar chertov commented on May 18, 2024

mikhail4021, работает и на семерке и на восьмерке! тут же от компилятора зависит скорее, а не от версии винды... версия с хабра мне самому больше нравилась, просто функция получала число и не преобразовывала... в деббагере это было явно видно, разбираться было некогда, поэтому и схватил старую версию... она работала

from i2pd.

chertov avatar chertov commented on May 18, 2024

собрал последнюю версию... ip серый, но роутеры находит и флибуста открылась! я так понимаю i2pd теперь может и на серых ip работать? Это благодаря реализации SSU?

from i2pd.

orignal avatar orignal commented on May 18, 2024

SSU еще не реализован полностью. Почему у вас работает с серым IP честно говоря не знаю, не должен.
Посмотрите на главной странице как обстоят дела со входящими тоннелями и печатаются ли сообщения вида "Connected from".

from i2pd.

chertov avatar chertov commented on May 18, 2024

Connected from не вижу... а на страничке статистики есть строки вида:
-->3681576963:ZWzj-->4115847519:Uefo-->2786370774:me 72918
-->2155486015:YCXT-->1662340038:Uefo-->3818465328:me 60752
New RouterInfo added постоянно строчит, сохраняет
подключался через йоту, причем ета к роутеру, а он в сеть раздает локальные ip... и вроде у еты сейчас адреса все серые, внешние только для юрлиц
флибуста открывалась, постараюсь все проверить...

пытаюсь реализовать простенький прокси сервер, с помощью https://github.com/joyent/http-parser парсю запросы от браузера и получаю хост, путь нечто вроде flibusta.i2p и /index.php
Сейчас можно как-нибудь сконвертить flibusta.i2p в base32 адрес?
пока что железно забиваю... типа как в hosts
"наброски" в моем форке в ветке proxy если интересно https://github.com/chertov/i2pd/tree/proxy

Если я из другого потока буду работать с i2pd аналогично тому как это происходит в HTTPServer ничего страшного не произойдет?) функции i2p::stream::CreateStream, i2p::data::netdb.FindLeaseSet, i2p::data::Base32ToByteStream должны адекватно работать?

from i2pd.

chertov avatar chertov commented on May 18, 2024

извиняюсь что в топике про поддержку Windows... работает вроде бы прокси флибусту открыло!

все жутко тормозит, но даже по ссылкам удалось немного походить... изменения пока буду коммитить в свою ветку: https://github.com/chertov/i2pd/tree/proxy там каша не хочется в основной репозиторий ее заливать

минут по 3-10 загружает страничку (основу - html), потом пишет Leases expired, если обновлять, то через какое-то время находит новый leaseSet и все снова, но работает!

from i2pd.

orignal avatar orignal commented on May 18, 2024

Сейчас можно как-нибудь сконвертить flibusta.i2p в base32 адрес?

Он на главной странице флибусты есть.
Было бы неплохо также реализовать разыменование адресов. Это работа с фалума hosts.txt и hostsdb.blockfile

from i2pd.

orignal avatar orignal commented on May 18, 2024

Connected from не вижу... а на страничке статистики есть строки вида:
-->3681576963:ZWzj-->4115847519:Uefo-->2786370774:me 72918
-->2155486015:YCXT-->1662340038:Uefo-->3818465328:me 60752

Скорее всего дело вот в этом 1662340038:Uefo -у вас к этому узлу есть исходящее соединение где то.

from i2pd.

orignal avatar orignal commented on May 18, 2024

все жутко тормозит, но даже по ссылкам удалось немного походить... изменения пока буду коммитить в свою ветку: https://github.com/chertov/i2pd/tree/proxy там каша не хочется в основной репозиторий ее заливать

Посмотрел ваш код: тормозит все из-за этого
std::this_thread::sleep_for (std::chrono::seconds(10)); // wait for 10 seconds
не следует этого делать внутри асинхронных операций. Я это сделал чисто для отладки. Вообще LeaseSet следует запрашивать независимо, более того я бы делал это по таймеру - как только появился интерес к какому ту адресу то запросить его первый раз, а потом бы заводит таймер на время истечения первого тоннеля.
Другая беда но это уже у меня что еще пока нету асинхронной версии Receive в Stream.
Еще не понял зачем вам понадобился Cи-шный функтор, сделайте его методом класса, а потом bind-ом.

from i2pd.

chertov avatar chertov commented on May 18, 2024

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

На мой взгляд страничка не должна писать "LeaseSet not found" или "Leases expired", "Not responding"... клиент i2p должен делать все возможное для установки соединения и если уж за некоторое время (допустим 5 минут) не смог, то вернуть ошибку прокси-сервера... вроде бы есть такие стандартные. Но пока для отладки эти сообщения очень удобны.

Про таймер тоже подумал, т.к. часто ловил "Leases expired".

from i2pd.

orignal avatar orignal commented on May 18, 2024

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

У меня ничего такого не наблюдается - если уж он получил первое сообщение то остальные приходят в течении нескольких секунд. Возможно у вас дело во входящих тоннелях, то есть тоннели как бы есть но реально они нерабочие, потому что последний перед вами узел не может до вас достучаться. Если хотите это проверить то можете попробовать убрать таймаут в NTCPSession.cpp чтобы не закрывать соединение принудительно после минуты неактивности. Правда потом другая сторона закроет правда не знаю через какое время.

from i2pd.

orignal avatar orignal commented on May 18, 2024

На мой взгляд страничка не должна писать "LeaseSet not found" или "Leases expired", "Not responding"... клиент i2p должен делать все возможное для установки соединения и если уж за некоторое время (допустим 5 минут) не смог, то вернуть ошибку прокси-сервера... вроде бы есть такие стандартные. Но пока для отладки эти сообщения очень удобны.

Естественно не должна. Надо как в официальном клиенте выдавать страницу что не получается и объяснять почему. Эти сообщения я сделал именно для отладки чтобы смотреть в чем проблема.

from i2pd.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.