как избежать маршрутизации через локальный стек в Linux

У меня следующая среда: 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.

Добавление дополнительных деталей и пояснений:

  1. Конечно, обе пары (1) - (2) и (3) - (4) - разные подсети
  2. , я хочу достичь (1) - -> (2) -> (4) -> (3)
  3. host2 - это черный ящик, поэтому я не могу установить там перенаправитель пакетов (который откроет прослушивающий сокет на интерфейсе (2) и перенаправит их на (3) через (4)) - именно этого я хочу избежать

Основная проблема, похоже, заключается в локальной доставке. Когда я открываю сокет на host1 и хочу подключиться к сокету, он прослушивает другой адрес того же хоста, ядро ​​просто использует локальный стек для доставки пакетов. См. Диаграмму netfilter ниже:

 --->[1]--->[ROUTE]--->[3]--->[4]--->
             |            ^
             |            |
             |         [ROUTE]
             v            |
            [2]          [5]
             |            ^
             |            |
             v            |

Пакеты проходят через [5] NF_IP_LOCAL_OUT и [2] NF_IP_LOCAL_IN, тогда как я хочу заставить их пройти через [4].

5
задан codewarrior 16 December 2011 в 20:37
поделиться