Ошибка неверного аргумента в клиенте 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 все равно должен его принять.

Другие вопросы по тегам