Перейти к публикации
Форум - ComputerCraft
Fingercomp

Неструктурированная децентрализованная сеть Zn

Рекомендованные сообщения

Вы же помните OpenNet? Сетка такая была для OpenComputers. Хорошая вещь, только непонятно, как она работает, как её обслуживать, а ещё она централизованная. И огромная. В общем, неудобно.

Поэтому предлагаем вам решение. Удобное и простое.

 

Вкратце


 

Zn (читать как "дзен") — это очень простая (код без комментов занимает меньше четырёх килобайт) децентрализованная (нет центрального сервера, все узлы сети равны) неструктурированная (отсутствует какая-либо структуризация клиентов) сетка для OpenComputers, созданная мною и @Totoro.

 

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

 

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

 

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

 

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

 

API


 

Функции

  • zn.connect(): boolean
    Подключиться к сети.

    Аргументы
    Нет.

    Возврат
    true, если всё ок.
    false, если клиент уже подключён.
     
  • zn.disconnect(): boolean
    Отключиться от сети.

    Аргументы
    Нет.

    Возврат
    true при успешном отключении.
    false, если уже отключён.
     
  • zn.send(address: string, message: string): boolean
    Отправить сообщение какому-либо узлу.

    Аргументы
    address — адрес модема конечного узла.
    message — сообщение для отправки.

    Возврат
    true — сообщение отправлено (не обязательно успешно доставлено).
     
  • zn.broadcast(message: string): boolean
    Послать сообщение для всех узлов сети.

    Аргументы
    message — сообщение для отправки.

    Возврат
    true.
     
  • zn.ping()
    Пингануть соседние узлы.

    Аргументы
    Нет.

    Возврат
    Нет.

 

События

  • zn_message(message: string, receiverAddr: string, senderAddr: string)
    Получено сообщения от узла сети.

    Аргументы
    message — сообщение.
    receiverAddr — адрес модема, поймавшего сообщение.
    senderAddr — адрес модема отправителя.
     
  • zn_ping(senderAddr: string, distance: number)
    Получен запрос на пинг.

    Аргументы
    senderAddr — адрес модема отправителя.
    distance — расстояние до узла.
     
  • zn_pong(senderAddr: string, distance: number)
    Получен ответ на пинг.

    Аргументы
    senderAddr — адрес модема отправителя.
    distance — расстояние до узла.

 

Пример кода

local event = require('event')
local zn = require('zn')
zn.connect()
zn.broadcast("Hello Zn members!")
while true do
  local _, message = event.pull("zn_message")
  if message == "bye" then
    break
  else
    print(message)
  end
end
zn.disconnect()

Установка


 

  1. Качаем hpm: http://computercraft.ru/topic/1855-repozitorii-programm-hel/?do=findComment&comment=27287
  2. Ставим пакет: hpm install zn.

Версия для EEPROM хранится в /usr/share/zn/eeprom.lua. Чтобы записать его, вставьте чистый EEPROM в комп и пропишите

$ flash -q /usr/share/zn/eeprom.lua "Zn node"

А затем вставьте EEPROM в дрона, µC или куда-либо ещё.

 

Ссылка на пакет.

Изменено пользователем Fingercomp
  • Like 7

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

Этакий расширенный модем, с плюшками.

 

Свой следущий проект я как раз планирую построить с использованием Zn.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

а нет ли опасности в "цинке", что это очередная волнообразная эхосендилка, такая как былла у сангара, а потом и у Монстрика на микроконтроллерах?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Сейчас эту сетку можно захацкерить очумелыми ручками. Требуется неисправный узел Дзена. Это мы решим, когда найдём нормальную хэшировалку. А вообще, сейчас циклов никаких быть не должно. Дубликаты отсеиваются.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Теперь можно писать IoT. То что нужно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

а нет ли опасности в "цинке", что это очередная волнообразная эхосендилка, такая как былла у сангара, а потом и у Монстрика на микроконтроллерах?

 

От самой сети опасности нет. Она убивает дубли и петли.

Кто-то может влезть и всунуть свою левую ноду в сеть и менять хеши сообщений постоянно.

Но тут и на обычных компах можно такой хрени понаписать. Это уже прямое злодеяние и попытка положить серв. Тут придётся обычными способами его выслеживать. Ну и можно поставить сниффер в сеть и отследить гада по адресу сетевой платы. =)

Изменено пользователем Totoro

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А если злодей отправит nil вместо хеша, это не убьет ближайшие узлы на строке hashes[hash] = computer.uptime()?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Хешировалка не помешает злодею слать невалидные значения.

Просто надо добавить защиту от дурака.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Хешировалка не помешает злодею слать невалидные значения

Да тут на самом деле каждый ответ порождает новый вопрос.

 

Ну, отбросим мы сообщения с nil в хеше. Так можно тупо заспамить сеть, крашнув узлы либо переполнением памяти, либо выпадением в TLWY при переборе хешей.

 

Сделать валидацию хешей? Но спамить можно и валидными хешами.

 

Добавить кулдаун для каждого соседа или счетчик хешей? Так и сам сосед может оказаться честным репитером и вообще, узлом собственной сети. Исходного адресата тоже не найти, т. к. его адрес легко подделывается.

 

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

 

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

 

Для дополнительной защиты можно даже использовать шифрование.

 

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

 

И что делать тогда? Выдать каждому устройству сертификаты? Но тогда на каждом устройстве придется хранить открытые ключи всех устройств сети и сверяться с ними при каждом удобном случае. Ретрансляторы на EEPROM могут выпасть из этой схемы.

 

И возникает главный вопрос: выдержит ли сервер всю эту криптографию?

  • Like 3

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

И возникает главный вопрос: выдержит ли сервер всю эту криптографию?

 

Нет, конечно. Потому что она нафиг не нужна.

Эта сеть - это просто длинные руки для модема. Нужно шифрование - делаешь шифрование. Нужен вайтлист - пилишь вайтлист. Всё просто.

Заддосить, взломать и положить можно всё что угодно. Это не значит, что сеть не нужна.

 

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

 

Да, можно сделать похожую фигню. Подключиться к сети с плашета например, на котором будет стоять спец. утилитка.

И проверить чистоту трафика. Например автоматом детектить и отмечать как "подозрительные" потоки однообразного спама, или одинаковые мессаги с разными хешами и т.п.

Изменено пользователем Totoro

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Это не значит, что сеть не нужна.

Опенеты и дата - центры очень пользовались популярностью. :giggle:

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Опенеты и дата - центры очень пользовались популярностью. :giggle:

 

Опеннеты на мой вкус были немного переусложнены.

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

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

 

Так и ОпенНет. Он работает, и в общем хорошо. Но он сложен. По нему нет внятных гайдов. Его исходники не вдруг модифицируешь.

У него централизованная структура, что само по себе имеет как плюсы так и минусы. Но мне кажется в атмосфере постоянных изменений p2p сети рулят.

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

 

Поставить ноду Zn-сети на компьютер сейчас можно двумя командами:

hpm install zn           -- ставим либу с терминала
require('zn').connect()  -- запускаем ноду с интерпретатора (или из программы-однострочника)

Она не обеспечивает никакой безопасности данных? Да, не обеспечивает.

Хакеры будут отдыхать в Zn-сети как на Гавайах? Я буду очень раз если так. Это будет значить, что есть ещё одно интересное программерское занятие на серве.

  • Like 3

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Эта сеть - это просто длинные руки для модема. Нужно шифрование - делаешь шифрование. Нужен вайтлист - пилишь вайтлист. Всё просто.

Я почему-то решил, что это Zn предлагается в качестве общественной сети на сервере, как было с OpenNet.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Я почему-то решил, что это Zn предлагается в качестве общественной сети на сервере, как было с OpenNet.

 

Ну, в каком-то смысле - да.

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

А если требуется что-то сложнее - то уже пилишь "надстройку". Добавляешь end2end шифрование, или ограничиваешь список доверенных узлов и т.п.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Я тут подумал, как раз антенна дальнего действия из ОТ хорошо поможет в организации p2p сетей. Хотя можно использовать связанные, но суть антенн в дальнем действии и в количестве не ограничено парой.

Изменено пользователем NEO

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

Либо, можно попросить админа надюпать жестких дисков с одинаковым адресом.

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

Либо, можно попросить админа надюпать жестких дисков с одинаковым адресом.

Как сказал Алекс, можно стандартному модему сделать 20к блоков расстояние и никакого геммора с сетями =)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

Либо, можно попросить админа надюпать жестких дисков с одинаковым адресом.

 

Это не интересно

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Всё это очень хорошие идеи, которые разбиваются об одно но - они не работают на рандомном серваке с нетвикнутым модом OC.

Ну и да, Лёха прав.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
они не работают на рандомном серваке с нетвикнутым модом OC.

ты так говоришь, как будто кто-то там где-то массово играет на "рандомных" серваках с ОС, да и при том еще в роутеры и сети цинковые :giggle:  Там кроме квантух, гравиков и покемонов никому ничего не интересно в подавляющей массе  :D  

  • Like 4

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

ты так говоришь, как будто кто-то там где-то массово играет на "рандомных" серваках с ОС, да и при том еще в роутеры и сети цинковые :giggle:  Там кроме квантух, гравиков и покемонов никому ничего не интересно в подавляющей массе  :D  

 

Тут я согласен, наш проект был и остаётся уникальным в этом плане.  :)

Всё что я хотел сказать - что моды и изменения конфига - это неинтересно и не спортивно.

 

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

 

Да, любой пакет обойдёт все узлы.

Что ты имеешь ввиду под облаками?

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

 

Это будет другая архитектура.

В сети Zn трафик передаётся всеми узлами текущего облака. И если оно слилось с другим облаком - оно будет получать весь трафик клиентов из первого облака и наоборот.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

 

 

zn.send(address: string, message: string[, timeout: boolean/string]): boolean Отправить сообщение какому-либо узлу. Аргументы address — адрес модема конечного узла. message — сообщение для отправки. timeout — таймаут ожидания подтверждения отправки, в секундах. false отключает подтверждение совсем. Возврат true — подтверждение не запрошено или получено. false — таймаут ожидания подтверждения.   zn.broadcast(message: string): boolean Послать сообщение для всех узлов сети. Аргументы message — сообщение для отправки. Возврат true.

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Нельзя, да; используйте сериализацию для этого. Zn позиционируется как не самая умная сетка, и вещи вроде ack, нескольких частей сообщений, длинных сообщений нужно реализовывать в специальном протоколе.

Это так и задумано, таков принцип.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

 

 

и для ее работы надо использовать костыли через serialization

Ну знаешь ли, сериализация не костыль) Вот попробуй написать клиент-серверное приложение на C++ или Java, как узришь передачу в байтах - поймешь о чем я)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Fingercomp, сделай, пожалуйста, в библиотеке время жизни кеша поменьше. При активном использовании вылетает на переполнении памяти(комп с 2мб)

Думаю, что 12часов все таки многовато.

 

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

Так же я добавил метод

zn.listen = function(mode)
  local _, message = event.pull("zn_message")
  if mode then
    message = serialization.unserialize(message)
  end
  return message
end

Ожидает сообщение и возвращает его.

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

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

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас

×