Ошибка неверного аргумента в клиенте httptunnel
Я пытаюсь использовать httptunnel
для туннеля соединение вот так:
на сервере:
sudo hts -F localhost:10000 81
nc -l -p 10000
На клиенте:
sudo htc -F 7777 server_ip_address:81
telnet 127.0.0.1 7777
но телнет не работает:
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Connection closed by foreign host.
системный журнал говорит:
Nov 6 01:41:37 r1y4n-PC htc[1695]: htc (httptunnel) 3.3 started with arguments:
Nov 6 01:41:37 r1y4n-PC htc[1695]: me = htc
Nov 6 01:41:37 r1y4n-PC htc[1695]: device = (null)
Nov 6 01:41:37 r1y4n-PC htc[1695]: host_name = server_ip_address
Nov 6 01:41:37 r1y4n-PC htc[1695]: host_port = 81
Nov 6 01:41:37 r1y4n-PC htc[1695]: proxy_name = (null)
Nov 6 01:41:37 r1y4n-PC htc[1695]: proxy_port = 8080
Nov 6 01:41:37 r1y4n-PC htc[1695]: proxy_buffer_size = 0
Nov 6 01:41:37 r1y4n-PC htc[1695]: proxy_buffer_timeout = -1
Nov 6 01:41:37 r1y4n-PC htc[1695]: content_length = 102400
Nov 6 01:41:37 r1y4n-PC htc[1695]: forward_port = 7777
Nov 6 01:41:37 r1y4n-PC htc[1695]: max_connection_age = 300
Nov 6 01:41:37 r1y4n-PC htc[1695]: use_std = 0
Nov 6 01:41:37 r1y4n-PC htc[1695]: strict_content_length = 0
Nov 6 01:41:37 r1y4n-PC htc[1695]: keep_alive = 5
Nov 6 01:41:37 r1y4n-PC htc[1695]: proxy_authorization = (null)
Nov 6 01:41:37 r1y4n-PC htc[1695]: user_agent = (null)
Nov 6 01:41:37 r1y4n-PC htc[1695]: debug_level = 0
Nov 6 01:41:49 r1y4n-PC htc[1695]: http_write_request: write error: Invalid argument
Nov 6 01:41:49 r1y4n-PC htc[1695]: couldn't open tunnel: Invalid argument
Nov 6 01:41:49 r1y4n-PC htc[1695]: exit with status = 1
Что вызывает http_write_request: write error: Invalid argument
?
Как правильно туннелировать соединение?
И сервер, и клиент Ubuntu 14.04
Спасибо
1 ответ
Как правильно туннелировать соединение?
Исправить httptunnel. Увидеть ниже.
Обратите внимание, что вы используете nc с ошибочными аргументами, но, похоже, все еще работает. От man nc
:
-l Используется для указания того, что nc должен прослушивать входящее соединение, а не инициировать соединение с удаленным хостом. Ошибочно использовать эту опцию в сочетании с опциями -p, -s или -z.
Что вызывает ошибку http_write_request: write: неверный аргумент?
Invalid argument
является строковой версией кода ошибки POSIX EINVAL.
Код ошибки был возвращен функцией write libc / syscall ядра, которая была косвенно вызвана функцией http_write_request клиента httptunnel. EINVAL означает:
fd привязан к объекту, который не подходит для записи; или файл был открыт с флагом O_DIRECT, и либо адрес, указанный в buf, либо значение, указанное в count, либо текущее смещение файла не выровнены соответствующим образом.
Перед вызовом write() сокет настраивается с различными параметрами с помощью функции setsockopt libc / системного вызова ядра. Один из этих вариантов - SO_SNDLOWAT. Вы можете прочитать о том, что это должно делать здесь. Обратите внимание, что:
SO_SNDLOWAT не изменяется в Linux (setsockopt(2) завершается с ошибкой ENOPROTOOPT)
таким образом, это бесполезный вызов для Linux, по крайней мере, с 2015 года.
После запуска htc с помощью strace я заметил несоответствие между кодом и аргументами системного вызова, о которых сообщает strace. Код в tunnel_out_setsockopts
функция пытается установить опцию SO_SNDLOWAT, но создает отчеты setsockopt(5, SOL_TCP, TCP_REPAIR, [1], 4) = 0
, Внимательно посмотрите на страницу руководства по сокетам, где SO_SNDLOWAT указан в качестве опции, и обратите внимание на следующее:
Перечисленные ниже параметры сокетов могут быть установлены с помощью setsockopt (2) и считаны с помощью getsockopt(2) с уровнем сокетов, равным SOL_SOCKET для всех сокетов.
tunnel_out_setsockopts
не использует SOL_SOCKET для опции SO_SNDLOWAT; он использует результат другой функции (get_proto_number
) вместо Это ошибка. Это может быть связано с несовместимостью с предыдущими версиями ядра или libc API, но я подозреваю, что это маловероятно.
К сожалению, исправление этой ошибки путем замены аргумента уровня сокета на SOL_SOCKET не приводит к использованию туннеля. Вызов записи, который ранее был неудачным, теперь успешно завершается, но примерно через секунду происходит сбой программы с ETIMEDOUT при вызове чтения.
Есть другая функция tunnel_in_setsockopts
который пытается установить SO_RCVLOWAT с выводом get_proto_numer
вместо SOL_SOCKET. Это еще одна ошибка.
Исправление этих двух заставляет туннель работать должным образом.
сервер
нк-л 10000
sudo hts -F localhost: 10000 81
клиент
htc -F 7777 localhost:81
телнет localhost 7777
Об этой ошибке уже сообщалось в отношении Ubuntu 14.04 здесь. Я предлагаю вам пометить это как влияющее на вас. Я загрузил патч в качестве решения проблемы, но Ubuntu все равно должен его принять.