Socat 如何将两个套接字链接在一起以创建端口转发连接?

how does socat work to link two sockets together to create a port forwarded connection?

提问人:shawnixer 提问时间:11/4/2023 更新时间:11/4/2023 访问量:56

问:

我正在尝试编写一个简单的端口转发器。假设我有一个服务正在 9999 上侦听 localhost。无法从本地系统外部访问它。但是,我可以使用以下命令将其转发到端口 192.168.1.10 上的 9999:

socat -d TCP4:本地主机:9999 TCP4:192.168.1.10:9999

然后我就可以监听 192.168.1.10 并访问内部服务器。当然,我也可以使用 ssh 隧道,但为了学习,我想编写自己的非 ssh 版本。

我的代码不是通过连接到侦听器的简单 c 程序,然后我打开与远程 ip 的连接。我尝试使用 recv 和 send,但这并没有多大作用。我试图理解我如何将它们链接在一起以创建此循环并处理 EOF。这里到底发生了什么?


2023/11/03 19:59:58 socat[1164] I socat by Gerhard Rieger and contributors - see www.dest-unreach.org
2023/11/03 19:59:58 socat[1164] I This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit. (http://www.openssl.org/)
2023/11/03 19:59:58 socat[1164] I This product includes software written by Tim Hudson ([email protected])
2023/11/03 19:59:58 socat[1164] N opening connection to AF=2 127.0.0.1:9999
2023/11/03 19:59:58 socat[1164] I starting connect loop
2023/11/03 19:59:58 socat[1164] I socket(2, 1, 6) -> 5
2023/11/03 19:59:58 socat[1164] N successfully connected from local address AF=2 127.0.0.1:52769
2023/11/03 19:59:58 socat[1164] N opening connection to AF=2 192.168.1.10:9999
2023/11/03 19:59:58 socat[1164] I starting connect loop
2023/11/03 19:59:58 socat[1164] I socket(2, 1, 6) -> 6
2023/11/03 19:59:58 socat[1164] N successfully connected from local address AF=2 192.168.1.20:52770
2023/11/03 19:59:58 socat[1164] I resolved and opened all sock addresses
2023/11/03 19:59:58 socat[1164] N starting data transfer loop with FDs [5,5] and [6,6]
2023/11/03 19:59:58 socat[1164] I transferred 123 bytes from 5 to 6
2023/11/03 20:00:28 socat[1164] I transferred 4 bytes from 6 to 5
2023/11/03 20:35:01 socat[1164] I transferred 29 bytes from 5 to 6
2023/11/03 20:35:03 socat[1164] N socket 2 (fd 6) is at EOF
2023/11/03 20:35:03 socat[1164] I shutdown(5, 1)
2023/11/03 20:35:03 socat[1164] I transferred 29 bytes from 5 to 6
2023/11/03 20:35:03 socat[1164] E write(6, 0xa00020000, 29): Broken pipe
2023/11/03 20:35:03 socat[1164] N exit(1)
2023/11/03 20:35:03 socat[1164] I shutdown(5, 2)
2023/11/03 20:35:03 socat[1164] I shutdown(6, 2)

我尝试阅读它的源代码,但是当我遇到这样的事情时:

#define XIO_GETRDFD(s) (((s)->tag==XIO_TAG_DUAL)?(s)->dual.stream[0]->fd:(s)->stream.fd)
#define XIO_GETWRFD(s) (((s)->tag==XIO_TAG_DUAL)?(s)->dual.stream[1]->fd:(((s)->stream.dtype&XIODATA_WRITEMASK)==XIOWRITE_2PIPE)?(s)->stream.para.exec.fdout:(((s)->stream.dtype&XIODATA_WRITEMASK)==XIOWRITE_PIPE)?(s)->stream.para.bipipe.fdout:(s)->stream.fd)

我以前从未见过并迷路了,我需要一些帮助来了解发生了什么。我以前读过一些复杂的东西,但不是那样的。所以我宁愿在高层次上问这个问题,这个过程是如何运作的。如何创建流,是否需要分叉任何类型的子进程?这就是我有兴趣发现的。

尝试了解 socat 工具的作用。

C 套接字 网络

评论

1赞 dimich 11/4/2023
简而言之,socat 执行多路复用 I/O:它等待两个描述符上的事件。当其中一个变得可读时,socat 会读取数据并将其写入另一个描述符。所有的东西都是模块化和可移植性的包装器。xio
0赞 shawnixer 11/5/2023
谢谢。我做了额外的调试,并注意到有一个字符串正在使用,我做了一些阅读。但是,我将如何处理在客户端按下回车键无法通过或挂起的 EOF 问题?我遇到了一个 linux 多路复用服务器/客户端,除了我之前没有按回车键之外,其他所有服务器/客户端都可以正常工作,它会导致它无限期挂起。select
0赞 dimich 11/5/2023
select()仍然有效,但我建议使用更方便的(POSIX)或(特定于 Linux)的界面。我不明白你的EOF问题是什么。当一个对等体关闭连接时,将描述符标记为可读并返回 0,就像在通常的流套接字通信中一样。您的转发器应关闭其与另一个对等方的连接。/ 还指示 POLLHUP/EPOLLHUP 事件。pollepollselect()recv()poll()epoll_wait()

答: 暂无答案