Skip to content

Commit 5729410

Browse files
committed
docs: update README.md style
1 parent 9d23c3c commit 5729410

File tree

1 file changed

+13
-15
lines changed

1 file changed

+13
-15
lines changed

Diff for: README.md

+13-15
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
# README.md
1+
# PortForward
22

3-
------------------------------
4-
5-
### 0x00 前言
3+
## 0x00 前言
64
`PortForward` 是使用 Golang 进行开发的端口转发工具,解决在某些场景下 `内外网无法互通`的问题。
75

86
`PortForward` 的功能如下:
@@ -29,7 +27,7 @@
2927
10. issue
3028
11. contributions
3129

32-
### 0x01 使用说明
30+
## 0x01 使用说明
3331
**1.使用**
3432

3533
Usage:
@@ -54,7 +52,7 @@
5452
./build.sh
5553

5654

57-
### 0x02 工作场景
55+
## 0x02 工作场景
5856
这里列举了一些 `PortForward` 的工作场景,如下:
5957

6058
**2.1 简单模式**
@@ -76,7 +74,7 @@
7674
</div>
7775

7876

79-
### 0x03 源码结构
77+
## 0x03 源码结构
8078

8179
.
8280
├── CHANGELOG
@@ -91,23 +89,23 @@
9189
└── udp.go // udp layer
9290

9391

94-
### 0x04 逻辑结构
92+
## 0x04 逻辑结构
9593
`PortForward` 支持 `TCP` , `UDP` 协议层的端口转发,代码抽象后逻辑结构框架如下:
9694
<div align="center">
9795
<img src="./Images/portforward_framework.png" width="500">
9896
</br>[图4.整体框架]
9997
</div>
10098

10199

102-
### 0x05 端口转发的实现
100+
## 0x05 端口转发的实现
103101
端口转发程序作为网络传输的中间人,无非就是将两端的 socket 对象进行联通,数据就可以通过这条「链路」进行传输了。
104102

105103
按照这样的思路,我们从需求开始分析和抽象,可以这么认为:无论是作为 `tcp` 还是 `udp` 运行,无论是作为 `connect` 还是 `listen` 运行,最终都将获得两个 socket,其中一个连向原服务,另一个与客户端连接;最终将这两端的 socket 联通即可实现端口转发。
106104

107105
在 Golang 中我们采用了 `io.Copy()` 来联通两个 socket,但是 `io.Copy` 必须要求对象实现了 `io.Reader/io.Writer` 接口,`tcp` 的 socket 可以直接支持,而 `udp` 的 socket 需要我们进行封装。
108106

109107

110-
### 0x06 udp的knock报文
108+
## 0x06 udp的knock报文
111109
`udp``connect` 模式下,我们在连接服务器成功后,立即发送了一个 `knock` 报文,如下:
112110

113111
conn, err := net.DialTimeout("udp", ...
@@ -116,21 +114,21 @@
116114
其作用是通知远程 `udp` 服务器我们已经连上了(`udp` 创建连接后,仅在本地操作系统层进行了注册,只有当发送一个报文到对端后,远程服务器才能感知到新连接),当我们在 `udp``conn-conn` 模式下运行时,这个报文是必须的。
117115

118116

119-
### 0x07 udp的超时设置
117+
## 0x07 udp的超时设置
120118
`udp` 的实现中,我们为所有的 `udp` 连接 socket 对象都设置了超时时间(`tcp` 中不需要),这是因为在 `udp` 中,socket 对象无法感知对端退出,如果不设置超时时间,将会一直在 `conn.Read()` 阻塞下去。
121119

122120
我们设置了 `udp` 超时时间为 60 秒,当 60 秒无数据传输,本次建立的虚拟通信链路将销毁,端口转发程序将重新创建新的通信链路。
123121

124122

125-
### 0x08 listen-listen的超时设置
123+
## 0x08 listen-listen的超时设置
126124
对于 `listen-listen` 模式,需要等待两端的客户端都连上端口转发程序后,才能将两个 socket 进行联通。
127125

128126
为此我们在此处设置了 120 秒的超时时间,也就是说当其中一端有客户端连接后,另一端在 120 秒内没有连接,我们就销毁这个未成功建立的通信链路;用户重新连接即可。
129127

130128
>如果没有这个超时,可能某些场景遗留了某个连接,将造成后续的通信链路错位。
131129
132130

133-
### 0x09 多通路的实现
131+
## 0x09 多通路的实现
134132
多通路可以支持同时发起多个连接,这里我们以 `tcp` 作为例子来说明。为了处理这种情况,我们的处理方式是:
135133

136134
1. `listen-conn`: 每当 listen 服务器接收到新连接后,与远端创建新的连接,并将两个 socket 进行联通。
@@ -140,7 +138,7 @@
140138
>我们在 `udp` 中也加入了多通路的支持,和 `tcp` 基本类似,但由于 `udp` 是无连接的,我们不能像 `tcp` 直接联通两个 socket 对象。我们在 `udp listen` 服务器中维护了一个临时表,使用 `ip:port` 作为标志,以描述各个通信链路的联通情况,依据此进行流量的分发。
141139
142140

143-
### 0x0A issue
141+
## 0x0A issue
144142
**1.udp的映射表未清空**
145143
udp多通路中的映射表没有对无效数据进行清理,长时间运行可能造成内存占用
146144

@@ -162,7 +160,7 @@ udp多通路中的映射表没有对无效数据进行清理,长时间运行
162160
这种多端口通信我们也是无法处理的,因为在目前多通路的实现下,上述流程中第 2 步过后,对于端口转发程序来说,后续的报文无法确定转发给 69 端口还是 61234 端口。
163161

164162

165-
### 0x0B contributions
163+
## 0x0B contributions
166164

167165
[r0oike@knownsec 404](https://github.com/r0oike)
168166
[fenix@knownsec 404](https://github.com/13ph03nix)

0 commit comments

Comments
 (0)