Я работаю над проектом туннелирования Python с использованием TUNTAP. Данные, полученные через интерфейс TUNTAP, содержат исходный IP-пакет, включая все заголовки. Я могу сделать одно из двух.
На входящей стороне я слушаю Twisted. На исходящей стороне у меня будет сырой сокет, который выгружает IP-пакет. Перед сбросом пакета программа меняет местами адрес источника с адресом сервера. Он также пересчитывает контрольные суммы TCP и UDP. Он также меняет местами порты, используя один из следующих методов. Эта информация отслеживается в таблице NAT.
1) Используйте один порт для каждого пользователя, например
US.ER.01.IP:10000 ----> SE.RV.ER.IP:3000 ----> facebook.com:80
US.ER.01.IP:10001 ----> SE.RV.ER.IP:3000 ----> facebook.com:80
US.ER.02.IP:3000 ----> SE.RV.ER.IP:3001 ----> facebook.com:80
Может ли это вызвать проблемы, если второй с одновременными запросами пользователя на facebook? Как система узнает, как маршрутизировать ответ facebook. Он поступает на порт 3000, поэтому он принадлежит пользователю user1, но отображается ли он обратно на 10000 или 10001?
2) Используйте уникальный порт для каждого подключения, например
US.ER.01.IP:10000 ----> SE.RV.ER.IP:3000 ----> facebook.com:80
US.ER.01.IP:10001 ----> SE.RV.ER.IP:3001 ----> facebook.com:80
US.ER.02.IP:3000 ----> SE.RV.ER.IP:3002 ----> remoteHost.com:22
Как мне узнать, когда нужно удалить записи из таблицы NAT? Я мог видеть, как таблица NAT заполнялась очень быстро, используя этот метод. Решения для этого:
I could wit for FIN packets from the server. This will not work with UDP though.
I could age the NAT entry on each hit. I could then run garbage collection
every N seconds. I see this being an issue if garbage collection runs
and how would a server's delayed response get to the proper host if it gets
deleted from the table.
Также существует проблема чтения из сырого сокета. Я знаю, как отправлять по одному, но можно ли получать отдельные IP-пакеты. Может ли необработанный сокет получить один пакет на вызов sock.recieve (65535), возможно, получить более одного IP-пакета?
Какая реализация лучше? Есть ли другие советы или вещи, на которые мне следует обратить внимание?
РЕДАКТИРОВАТЬ:
Итак, у меня N много клиентов. Если вы меня неправильно поняли, между клиентом и им самим используется enitre / 30. Это просто абстракция, позволяющая создать туннель. Я также не думал, что это имеет значение, но на самом деле веб-сокет проходит через «прокси» в локальной сети (IP-данные просто переупаковываются в новый веб-сокет, однако сопоставления уникальны). Я не хотел, чтобы объяснение было таким запутанным. Я не вижу, как это что-то меняет.
Client PC CLIENT PC Client PC----->LAN INTERNET
Client 1: 10.1.1.2 ----> 10.1.1.1 ----> Websocket(IPdata) ----> Browser ---> newWebSocket(IPData) ----> SE.RV.ER.IP
Client 2: 10.1.1.4 ----> 10.1.1.3 ----> Websocket(IPdata) ----> Browser ---> newWebSocket(IPData) ----> SE.RV.ER.IP
Client 3: 10.1.1.6 ----> 10.1.1.5 ----> Websocket(IPdata) ----> Browser ---> newWebSocket(IPData) ----> SE.RV.ER.IP
Каждый клиент устанавливает свой маршрут по умолчанию как конечную точку туннеля (например, 10.1.1.1). Клиент получает IP-датаграмму, помещает ее в веб-сокет, отправляет веб-сокет в браузер в локальной сети, который затем отправляет его на сервер (или, возможно, другой прокси). Внутри веб-сокета содержится исходная IP-дейтаграмма (с источником 10.1.1.2 или каким-либо другим внутренним IP-адресом).
Важно отметить, что сервер получает сообщение веб-сокета из Интернета, СОДЕРЖАЩИЕ блага (с частным адресом источника). Как это будет использовать сервер Python? Создать новый туннель с самим собой, затем выгружать необработанный пакет в туннель и соответствующим образом маршрутизировать?
Или, может быть, я мог бы использовать отображение?
Как я смогу «отобразить» абстракцию туннеля по этой цепочке веб-сокетов? У клиента нет маршрута к Интернету, но он может подключиться к «Браузеру», который может подключиться к Интернету. Похоже, то же самое и с туннелями VPN. Абстракция будет такой:
Client 1: 10.1.1.2 ----> 10.1.1.1 ----> Websocket(IPdata) ----> Browser ---> newWebSocket(IPData) ----> SE.RV.ER.IP -> Internet
10.1.2.2------------------------------------------------------------------------------------> 10.1.2.1 ----> Internet
Если вы знаете какие-либо ресурсы, которые помогут мне встать на верный путь, это было бы здорово!