«Пурпурный» I2P — окно в мир C++ приложений

    Известно, что официальный I2P написан на Java, что само по себе отталкивает потенциальных пользователей, тем самым снижая полулярность сети, чем могла бы быть. Кроме того Java приложения достаточно требовательны к ресурсам, потому запуск I2P на слабых устройствах сопряжен с трудностями, а порой и невозможен. Также выяснилось что Java в Африке не та же самая Java, и поддержка стойкой криптографии зависит от страны, из-за чего пришлось отложить массовый переход на ECDSA.
    Поэтому реализация I2P на C++ всегда была актуальной задачей. Из множества попыток «пурпурный I2P» (Purple I2P) на настоящий момент является наиболее успешной и пригодной для практического использования. Название обусловлено цветом рубашки на иконке I2P, чтобы отличать от официального I2P, где цвет — красный и обозначает семейство приложений, использующих данную реализацию I2P. i2pd же представляет собой I2P маршрутизатор общего назначения.


    image

    Ранее мною были рассмотрены компоненты, необходимые для построения такой системы. Вкратце, для работы в сети I2P необходим маршрутизатор, реализующий следующие функции:
    • Транспорт, отвечающий за прямые соединения с другими узлами. Как правило через Интернет, но может быть и через другие сети, например, Тор
    • Построение и пересылка данных через тоннели
    • Поиск и поддержка списка других узлов в актуальном состоянии
    • Передача транзитного трафика других участников

    Если есть необходимость обмениваться собственными данными, то на маршрутизаторе необходимо размещать адреса, для работы которых нужны дополнительные протоколы, рассмотренные здесь. Однако для взаимодействия с клиентами одной передачи данных недостаточно — необходимо иметь возможность управлять локальным адресами и уметь обращаться к удаленным. В официальном I2P это реализовано в виде набора отдельных внешних приложений, в i2pd же эти службы встроенные. На данный момент реализованы:
    1. HTTP прокси
    2. I2P тоннели, представляющие собой отображения адресов на TCP порты локальной машины
    3. SAM — командный интерфейс. Рассмотрим его более подробно.


    Протокол SAM


    SAM(Simple Anonymous Messaging) в течении долгого времени был фактически единственным протоколом, пригодным для полноценного взаимодействия с I2P из C++ приложений. Точнее говоря, есть еще BOB, фактически реализующий ту же самую концепцию, но распространённый гораздо меньше чем SAM.
    Рекомендуемый официальным I2P протокол I2CP для этих целей малопригоден, поскольку является протоколом более низкого уровня, и использует внешнюю реализацию потоков, написанную тоже на Java. C++ -ой версии на данный момент нет. В дальнейшем планируется оформить реализацию потоков из i2pd в виде отдельной библиотеки, работающей через I2CP.
    Для SAM же существует готовая для использования C++-ая библиотека i2psam, активно используемая криптовалютами для сокрытия своего трафика.
    Несмотря на недостатки и критику, SAM является важнейшим протоколом в «пурпурном» I2P, поскольку связка существующего C++ приложения с использованием SAM и i2pd позволяет немедленно отказаться от использования Java без дополнительных переделок.
    Наиболее популярные из них:
    1. I2P-Messenger
    2. iMule
    3. Bitcoin-I2P

    В целом протокол вполне оправдывая свое названия, с точки зрения клиента представляя собой сокеты, работающие либо в командном режиме, либо в режиме передачи данных. Если клиент удаляет сокет, то соответствующая ему I2P конструкция удаляется. Работа начинается с создания локального адреса с заданными клиентом ключами, либо временного со сгенерированными случайным образом ключами. Затем либо может, используя этот адрес, установить соединение с удаленным адресом, либо ждать следующего входящего соединения от удаленного адреса. После этого сокет переходит в режим передачи данных.
    Подобный интерфейс может быть выполнен в виде API и использован прямо из приложения, без необходимости использовать внешний маршрутизатор, и распространяться в виде готового решения, не заставляя конечного пользователя в детали настроек I2P.

    Что планируется реализовать


    1. I2CP, чтобы Java приложения могли работать через i2pd
    2. Профилировщик узлов, чтобы строить более быстрые и надежные тоннели
    3. Обновляемую адресную книгу
    4. Дейтаграммы
    5. Режим floodfill-а


    Релиз 0.1.0


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

    Бинарники для Ubuntu:
    launchpad.net/~i2p.packages/+archive/ubuntu/i2p

    для Debian
    deb.i2p2.no

    Для все остальных платформ компилировать из исходников отсюда.
    Требуются библиотеки crypto++ и boost.
    Поделиться публикацией

    Похожие публикации

    Комментарии 25
      0
      Новость, безусловно, позитивная. Сам давно слежу за проектом и жду работоспособных версий…
        0
        Всё еще на OS X
        MacBook-Pro:i2pd Shift$ ./i2p 
        Segmentation fault: 11
        
          0
          У меня работает на 10.9 и 10.10. Попробуй удалить папку ~/.i2pd
            0
            Там реально какая то проблема со сборкой из-за последнего обновления от эпла.
            Потому релиз для OS X и не сделали. Разбираемся.
              0
              Не помогло
                0
                crypto++ у вас откуда?
          • НЛО прилетело и опубликовало эту надпись здесь
              +2
              Вот и прекрасно — возьмите и реализуйте «на обычных сях, без всяких плюсов, фреймворков и прочего хипстерства» протоколы, кстати на настоящий момент отлично документированные.
              Я попытался на плюсах как умел, у вас безусловно получится лучше.
              • НЛО прилетело и опубликовало эту надпись здесь
                  0
                  С использованием с++ проблем нет, а вот с бустом уже возникают напряги…
                  Захочет, например, кто-нибудь ваш проект адаптировать в дерево openwrt, но увидев в зависимостях буст быстро обломается.
                    +1
                    Буст уже в дереве/репах опенврт начиная с Chaos Calmer. Для Barrier Braker так же собирается.
                0
                А это у вас форк i2pcpp, или попытка ещё раз все реализовать?
                  0
                  Нет не форк. Работа над i2pcpp была начата гораздо позже и ничего сколько-нибудь работающего у них пока нет…
                    0
                    Нет, это полностью собственная реализация.
                    Как было сказано впоследствии, i2pcpp никогда не ставил целью создание пригодной для использования системы. В настоящий момент работа над ним прекращена.
                    0
                    А у вас нету таймлайна, когда оно наконец будет работать как полноценная замена Java-имплементации? :)
                    А то что-то, вот, собранный из сегодняшнего git HEAD уже полдня висит, и всё
                    LeaseSets: 0
                    , хотя роутеров и флудфилов уже набрал кучу :(
                    Ну и не заходит никуда :(
                      0
                      Вот, стоило написать, как он ВНЕЗАПНО нашёл лизсет :) Правда, пока всё ещё только один :(
                        0
                        LeaseSet и должен быть нуль если не флудфил.
                        Если там что то отличное от нуля значит поймал в транзитном трафике со старых версий когда LeaseSet-ы ходили нешифрованными.

                        Если никуда не заходит то давайте разбираться куда конкретно не получается.
                        Скорее всего адреса в адресной книге нет, а нет потому что надо нормальные источники прописывать в subscritptions.txt
                          0
                          1) а «нормальные источники» это какие? :)
                          У меня там i2p-projekt.i2p/hosts.txt ;)
                          2) Так не заходит именно по b32-адресам. Прокси выдаёт 500. А при попытке открыть localhost:7070/zmw2cyw2vj7f6obx3msmdvdepdhnw2ctc4okza2zjxlukkdfckhq.b32.i2p — говорит No LeaseSet Found.
                          3) А ещё он у меня пару раз за ночь уже покрошился. Но т.к. был запущен в качестве сервиса — бектрейса пока нету.
                            0
                            3. Платформа какая?
                              0
                              Linux (Gentoo ~amd64)
                              // кстати, полуоффтоп: пытаюсь ещё собрать для роутера, но из-за буста (?) ловлю фейл :(
                              Вот кусок билдлога
                              mips-openwrt-linux-uclibc-g++ -o i2p obj/CryptoConst.o obj/Datagram.o obj/Garlic.o obj/I2NPProtocol.o obj/LeaseSet.o obj/Log.o obj/NTCPSession.o obj/NetDb.o obj/Profiling.o obj/Reseed.o obj/RouterContext.o obj/RouterInfo.o obj/SSU.o obj/SSUSession.o obj/SSUData.o obj/Streaming.o obj/Identity.o obj/TransitTunnel.o obj/Transports.o obj/Tunnel.o obj/TunnelEndpoint.o obj/TunnelPool.o obj/TunnelGateway.o obj/Destination.o obj/UPnP.o obj/util.o obj/aes.o obj/base64.o obj/AddressBook.o obj/BOB.o obj/ClientContext.o obj/Daemon.o obj/I2PTunnel.o obj/I2PService.o obj/SAM.o obj/SOCKS.o obj/HTTPServer.o obj/HTTPProxy.o obj/I2PControl.o obj/i2p.o obj/DaemonLinux.o -lcrypto++ -lboost_system -lboost_date_time -lboost_filesystem -lboost_regex -lboost_program_options -lpthread -L/home/mva/.vcs_repos/openwrt/ar71xx/staging_dir/target-mips_34kc_uClibc-0.9.33.2/usr/lib -L/home/mva/.vcs_repos/openwrt/ar71xx/staging_dir/target-mips_34kc_uClibc-0.9.33.2/lib -L/home/mva/.vcs_repos/openwrt/ar71xx/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/usr/lib -L/home/mva/.vcs_repos/openwrt/ar71xx/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/lib -L/home/mva/.vcs_repos/openwrt/ar71xx/staging_dir/target-mips_34kc_uClibc-0.9.33.2/usr/lib
                              /home/mva/.vcs_repos/openwrt/ar71xx/staging_dir/target-mips_34kc_uClibc-0.9.33.2/usr/lib/libboost_filesystem.so: warning: the use of OBSOLESCENT `utime' is discouraged, use `utimes'
                              /home/mva/.vcs_repos/openwrt/ar71xx/staging_dir/target-mips_34kc_uClibc-0.9.33.2/usr/lib/libcrypto++.so: warning: gethostbyname is obsolescent, use getnameinfo() instead.
                              obj/NTCPSession.o: In function `i2p::transport::NTCPSession::HandleSent(boost::system::error_code const&, unsigned int, std::vector<i2p::I2NPMessage*, std::allocator<i2p::I2NPMessage*> >)':
                              NTCPSession.cpp:(.text+0x4ef4): undefined reference to `__atomic_fetch_add_8'
                              obj/NTCPSession.o: In function `i2p::transport::NTCPSession::HandleReceived(boost::system::error_code const&, unsigned int)':
                              NTCPSession.cpp:(.text+0x6c90): undefined reference to `__atomic_fetch_add_8'
                              obj/SSUSession.o: In function `i2p::transport::SSUSession::Send(unsigned char const*, unsigned int)':
                              SSUSession.cpp:(.text+0x3b4): undefined reference to `__atomic_fetch_add_8'
                              obj/SSUSession.o: In function `i2p::transport::SSUSession::ProcessNextMessage(unsigned char*, unsigned int, boost::asio::ip::basic_endpoint<boost::asio::ip::udp> const&)':
                              SSUSession.cpp:(.text+0x4938): undefined reference to `__atomic_fetch_add_8'
                              obj/Transports.o: In function `i2p::transport::Transports::UpdateBandwidth()':
                              Transports.cpp:(.text+0x2ec): undefined reference to `__atomic_load_8'
                              Transports.cpp:(.text+0x34c): undefined reference to `__atomic_load_8'
                              Transports.cpp:(.text+0x3a0): undefined reference to `__atomic_load_8'
                              Transports.cpp:(.text+0x3c4): undefined reference to `__atomic_load_8'
                              obj/HTTPServer.o: In function `i2p::util::HTTPConnection::FillContent(std::basic_stringstream<char, std::char_traits, std::allocator >&)':
                              HTTPServer.cpp:(.text+0x2cb4): undefined reference to `__atomic_load_8'
                              obj/HTTPServer.o:HTTPServer.cpp:(.text+0x2d74): more undefined references to `__atomic_load_8' follow
                              collect2: error: ld returned 1 exit status
                              Makefile:52: recipe for target 'i2p' failed


                                0
                                Добавьте в мэйкфайл i2pd -latomic
                                Про сборку под опеенврт — мэйкфайл и патчи можете найти тут:
                                github.com/PurpleI2P/i2pd/issues/345
                                0
                                У меня кстати на опенврт на свежих версиях подобная штука — роутер работает 6+ часов, но не ходит по адресам:
                                12:09:54/info — SOCKS: requested i2p-projekt.i2p:80
                                12:09:54/warn — Remote destination i2p-projekt.i2p not found
                                12:09:54/error — SOCKS: error when creating the stream, check the previous warnings for more info
                                12:09:54/warn — SOCKS: v5 request failed: 4
                                  0
                                  Ну, у меня оно даже на нормальном линуксе и уже очень давно, не только на свежих версиях :-/
                          0
                          А у вас, часом, нету realtime-чатика где-нибудь за пределами i2p? :) Пообщаться о настройках там, вот это всё… :)

                          Ну и чтобы два раза не вставать: А никакого способа ограничения количества создаваемых соединений кроме floodfill=1/0 и bandwidth=O/L нету?

                          А то с floodfill=0 и bandwith=L оно целый день у меня провисело и ни одного лизсета не поймало.
                          А с floodfill=1 и bandwidth=O — пользоваться и обычными-то интернетами как-то печально становится…
                            0
                            github.com/PurpleI2P/i2pd там создавайте issue
                            twitter.com/i2porignal
                            vk.com/i2porignal
                            на ваш выбор.
                            Ну и #i2pd-dev в ирке разумеется.

                            Попробуйте floodfill=0 и badwidth=O тогда такого количества соединений не будет.
                            Другие ограничения постепенно добавлю.

                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                          Самое читаемое