LINUX.ORG.RU

Проксирование сокетов?

 , ,


1

2

Стоит такая задача: есть 2 сокета и мне нужно их «соеденить»

т.е. если данные пришли с первого сокете - отправить их во второй, и наоборот.

Сейчас это сделано просто - читаем из сокета 1, пишем в сокет 2 (И так далее)

вопрос - можно ли это сделать не гоняя данные через userspace, т.е. средствами ядра/OS?

thx



Последнее исправление: Effect (всего исправлений: 1)

Маршруты дописать.

anonymous
()
Ответ на: комментарий от zerhud

netcat

только если по принципу «чего не видно, того нет», так как там внутри read/write

annulen ★★★★★
()

Не страдайте фигней, просто сделайте это на epoll/select - всё равно ваша сеть даже на 20% одно ядро не загрузит.

Nastishka ★★★★★
()

Посмотри на BPF сначала. Потом городи велосипеды.

untitl3d
()

Если пришли с первого сокета, то пришли куда? В третий сокет? И нужно отправить их во второй? По человечески опиши задачу, че за софт, где стоит и что решает, на одной машине крутится всё или по сети гоняешь между разными машинами?

menangen ★★★★★
()
Ответ на: комментарий от menangen

Если пришли с первого сокета, то пришли куда? В третий сокет?

Стоит такая задача: есть 2 сокета и мне нужно их «соеденить»

Чоткая аватарка, в точку.

filosofia
()

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

zerhud
()
Ответ на: комментарий от filosofia

Пусть грамотно пишет, что сокета три, а не два, и один из них у него выступает как прокси

Или упоминает тогда, что у него два tcp сокета в одной прокси проги

menangen ★★★★★
()
Последнее исправление: menangen (всего исправлений: 1)

Прежде чем лезть в ядерную часть, попробуй померять показатели, которые тебе нужны. Задержку, пропускную способность? Скорее всего userspace read/write/epoll хватит с головой. Там не так много выигрыша будет как тебе кажется.

filosofia
()
Ответ на: комментарий от menangen

Чего ты несёшь, болезный? Какое три сокета, какое тсп?

anonymous
()
Ответ на: комментарий от menangen

это просто ты тупой, а все остальные поняли, что сказал ТС

Harald ★★★★★
()

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

filosofia
()

вопрос - можно ли это сделать не гоняя данные через userspace, т.е. средствами ядра/OS?

Именно в такой постановке (пара сокетов смотрящая в разные стороны) без user space не получится. Вы уж определитесь - или контроль/модуляция трафика, или всё проходит мимо Вас.

bugfixer ★★★★★
()
Ответ на: комментарий от t184256

2 вызова splice позволяют перекинуть порцию данных из одного сокета в другой без копирования в юзерспейс

annulen ★★★★★
()
Ответ на: комментарий от annulen

2 вызова splice позволяют перекинуть порцию данных из одного сокета в другой без копирования в юзерспейс

Не хочу Вас расстраивать, но «splice() moves data between two file descriptors … one of the file descriptors must refer to a pipe.»

Вы считаете это будет дешевле чем read()+write()?

bugfixer ★★★★★
()
Ответ на: комментарий от bugfixer

pipe - это буфер памяти в пространстве ядра. Условие задачи было «не гоняя данные через userspace». Дешевле или нет - надо тестировать для конкретного случая.

annulen ★★★★★
()
Ответ на: комментарий от bugfixer

Но дороже быть не должно, так как системных вызовов в обоих случаях два

annulen ★★★★★
()

Не знаю, годится ли тебе такое решение: во FreeBSD есть такая подсистема — netgraph. Там такое делается ну чрезвычайно просто: man ng_tee, man ng_ksocket.

Это если ты не прибит гвоздями к линуксу.

anonymous
()
Ответ на: комментарий от annulen

Условие задачи было «не гоняя данные через userspace».

Очевидно с целью «сэкономить».

Дешевле или нет - надо тестировать для конкретного случая.

Но дороже быть не должно, так как системных вызовов в обоих случаях два

«Готов поставить существенную сумму» что гонять splice’ами через pipe будет заметно медленнее чем read()+write() через userspace, особенно под нагрузкой. Я сильно затрудняюсь представить что там даже в теории можно такого сделать чтобы эту копию отыграть, а вот отстрелить себе ногу - миллион способов, начиная с ограниченного (и относительно маленького) размера внутреннего буфера pipe.

bugfixer ★★★★★
()
Ответ на: комментарий от bugfixer

начиная с ограниченного (и относительно маленького) размера внутреннего буфера pipe

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

отстрелить себе ногу - миллион способов

Достаточно обработать ошибки, которые может вернуть splice. Но код будет сложнее, чем с read/write, спору нет

Очевидно с целью «сэкономить».

Вот пусть заимплементит и сравнит, получилось сэкономить или нет.

annulen ★★★★★
()
Ответ на: комментарий от annulen

Его можно настроить

Таки да, подкрутили. А я и пропустил:

Different implementations have different limits for the pipe capacity.

...

In Linux versions before 2.6.11, the capacity of a pipe was the same as the system page size (e.g., 4096 bytes on i386). Since Linux 2.6.11, the pipe capacity is 16 pages (i.e., 65,536 bytes in a system with a page size of 4096 bytes). Since Linux 2.6.35, the default pipe capacity is 16 pages, but the capacity can be queried and set using the fcntl(2) F_GETPIPE_SZ and F_SETPIPE_SZ operations.

С 4к, да даже и 64к, при современных сетевых скоростях Вы бы поросли однозначно. А самое главное - ну вот не позволяет оно от этой копии избавиться, от слова никак. Вопрос только между чем копируется.

bugfixer ★★★★★
()
Ответ на: комментарий от bugfixer

А самое главное - ну вот не позволяет оно от этой копии избавиться, от слова никак.

Есть такое

annulen ★★★★★
()
Ответ на: комментарий от bugfixer

Я вспомнил, где я сталкивался со сплайсом через пайп и это было выгодно. На устройстве с жестким диском нужно было копировать файлы с флешки на диск. Ядро было старое и sendfile тогда еще не умел писать из файла в файл, но копирование через splice ускоряло процесс по сравнению с read/write

annulen ★★★★★
()
Ответ на: комментарий от anonymous

Спасибо, кажется именно то, что нужно.

надо достать FreeBSD и посмотреть, а то с 4.4-4.5 не видел ее )

Effect
() автор топика
Ответ на: комментарий от Nastishka

спасибо, попробую тоже вариант этот, сделаю замеры.

Effect
() автор топика
Ответ на: комментарий от annulen

спасибо за идею, попробую, замерю.

Effect
() автор топика
Ответ на: комментарий от annulen

но копирование через splice ускоряло процесс по сравнению с read/write

Интересно было бы понять за счёт чего? Там реально zero-copy случался, или что-то ещё?

bugfixer ★★★★★
()
Ответ на: комментарий от annulen

а какая разница в какой памяти буфер находится в юзерской или в кернел, если так и так данные будут скопированы через pcie в память хоста, а потом заново из памяти хоста через pcie в буфер сетевой карты(потенциально другой). А ведь по сути надо-то всего навсего ip/tcp заголовки переписать

anonymous
()
Ответ на: комментарий от anonymous

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

Какой еще pcie, на кого ты свой энтерпрайз крошишь, сейчас у большинства сетевух в мире физическая часть в материнке, контроллер в CPU, а память в RAM

annulen ★★★★★
()
Последнее исправление: annulen (всего исправлений: 1)
Ответ на: комментарий от bugfixer

¯\_(ツ)_/¯

Но выигрыш был ощутимым и не требовал для регистрации фотофиниша и миллисекундных таймеров

annulen ★★★★★
()
Последнее исправление: annulen (всего исправлений: 2)
Ответ на: комментарий от bugfixer

Еще ОП нигде не упоминает, какие именно у него сокеты. Я подозреваю, что если один из сокетов не сетевой, а юниксовый, или если сетевой, но от локалхоста или виртуального интерфейса, то ситуация может отличаться от проксирования между двумя «настоящими» сетевыми сокетами.

annulen ★★★★★
()
Ответ на: комментарий от anonymous

А ведь по сути надо-то всего навсего ip/tcp заголовки переписать

Я не думаю что в общем случае это в принципе возможно: destination вовсе не обязан быть способным мгновенно потреблять всё что пришло из source, и тогда Вы точно захотите резать пакеты по-другому с целью максимизировать useful payload / headers overhead ratio. MTU может быть разный etc.

bugfixer ★★★★★
()
Последнее исправление: bugfixer (всего исправлений: 1)
Ответ на: комментарий от annulen

Еще ОП нигде не упоминает, какие именно у него сокеты.

Кстати, таки да. Но по любому было бы интересно если бы он отписался потом удалось что-нибудь splice’ами отыграть, или нет.

bugfixer ★★★★★
()
Ответ на: комментарий от Effect

Оба сокета TCP, оба смотрят наружу

А чем тогда не устраивают готовые высокопроизводительные решения для TCP-прокси?

annulen ★★★★★
()
Последнее исправление: annulen (всего исправлений: 1)
Ответ на: комментарий от Effect

Оба сокета TCP, оба смотрят наружу

А чем тогда не устраивают готовые высокопроизводительные решения для TCP-прокси?

И трафик какого плана - bursts раз в пятилетку, или что-то более-менее steady rate?

bugfixer ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.