У меня следующая среда: 2 хоста, каждый с 2 интерфейсами Ethernet, подключенными друг к другу (как на диаграмме ниже):
+---------+ +---------+
| (1)+---------------+(2) |
| host1 | | host2 |
| | | |
| (3)+---------------+(4) |
+---------+ +---------+
Я хотел бы написать клиент / сервер инструмент socket, который откроет как клиентские, так и серверные сокеты на host1. Я хотел бы, чтобы клиент отправлял TCP-пакеты через интерфейс (1), а сервер прослушивал интерфейс (3), эти пакеты будут проходить через host2.
Обычно стек Linux маршрутизирует эти пакеты через локальный стек TCP / IP, не отправляя их на host2.
Я попытался использовать параметр SO_BINDTODEVICE как для сервера, так и для клиента, и мне кажется, что сервер действительно привязан к интерфейсу (3) и не прослушивает трафик localhost. Я проверил, что клиент с хоста 1 не может быть принят, тогда как клиент с хоста 2 принимает.
К сожалению, клиентские пакеты не отправляются (даже tcpdump на интерфейсе (1) не видит пакетов) через интерфейс (1) на интерфейс (2). Конечно, маршрутизация правильная (я могу пинговать (2) из (1), (4) из (1), (4) из (3) и так далее).
У меня вопрос, можно ли это реализовать без использования настраиваемого стека TCP / IP?
Может быть, мне стоит попробовать изменить IP-адрес назначения (от клиента) так, чтобы он был из внешней сети (а затем будет отправлен с использованием по умолчанию шлюз из интерфейса (1) - интерфейс (2)), а затем при постмаршрутизации снова изменить их на исходные? Возможно ли такое решение работать?
Я пишу свое приложение на C под Debian.
Добавление дополнительных деталей и пояснений:
Основная проблема, похоже, заключается в локальной доставке. Когда я открываю сокет на host1 и хочу подключиться к сокету, он прослушивает другой адрес того же хоста, ядро просто использует локальный стек для доставки пакетов. См. Диаграмму netfilter ниже:
--->[1]--->[ROUTE]--->[3]--->[4]--->
| ^
| |
| [ROUTE]
v |
[2] [5]
| ^
| |
v |
Пакеты проходят через [5] NF_IP_LOCAL_OUT и [2] NF_IP_LOCAL_IN, тогда как я хочу заставить их пройти через [4].