mirror of
https://github.com/e1732a364fed/v2ray_simple.git
synced 2025-12-24 13:27:56 +08:00
更新代码,文档; 令tproxy支持sniffing以及分流; 令tproxy在关闭时不卡住
关联 #98 中 下面的评论中 ctermiii 所反映的两个问题
This commit is contained in:
@@ -92,11 +92,15 @@ func cleanup() {
|
||||
}
|
||||
}
|
||||
|
||||
for _, tm := range tproxyList {
|
||||
if tm != nil {
|
||||
tm.Stop()
|
||||
if len(tproxyList) > 0 {
|
||||
log.Println("closing tproxies")
|
||||
for _, tm := range tproxyList {
|
||||
if tm != nil {
|
||||
tm.Stop()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func main() {
|
||||
@@ -393,18 +397,27 @@ func mainFunc() (result int) {
|
||||
}
|
||||
|
||||
for _, thisConf := range tproxyConfs {
|
||||
tm := vs.ListenTproxy(thisConf.GetAddrStrForListenOrDial(), defaultOutClient, routingEnv.RoutePolicy)
|
||||
enableSniff := false
|
||||
if thisConf.SniffConf != nil {
|
||||
enableSniff = thisConf.SniffConf.Enable
|
||||
}
|
||||
lc := proxy.LesserConf{
|
||||
Addr: thisConf.GetAddrStrForListenOrDial(),
|
||||
Tag: thisConf.Tag,
|
||||
UseSniffing: enableSniff,
|
||||
}
|
||||
tm := vs.ListenTproxy(lc, defaultOutClient, routingEnv.RoutePolicy)
|
||||
if tm != nil {
|
||||
tproxyList = append(tproxyList, tm)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
} //if len(tproxyConfs) > 0 {
|
||||
|
||||
}
|
||||
} //if mode == proxy.SimpleMode {
|
||||
|
||||
}
|
||||
} //if (defaultOutClient != nil) && (defaultInServer != nil || len(allServers) > 0 || len(tproxyConfs) > 0) {
|
||||
|
||||
//没可用的listen/dial,而且还无法动态更改配置
|
||||
if noFuture() {
|
||||
|
||||
6
doc.go
6
doc.go
@@ -13,6 +13,12 @@ utils -> netLayer-> tlsLayer -> httpLayer -> advLayer -> proxy -> v2ray_simple -
|
||||
|
||||
ListenSer函数用于主要 代理的转发,ListenTproxy函数用于转发透明代理。内置了 lazy的转发逻辑。
|
||||
|
||||
Tproxy
|
||||
|
||||
tproxy没有 TLS层 以及更上层的所有参数,只包含网络层和传输层的参数,网络层只包含 ip和端口这两个参数,传输层只包含 "是否开启sniffing" 这一个参数; 然后还有一个 tag参数,然后就没了。
|
||||
|
||||
所以tproxy不能算是一个完整的 proxy.Server. 所以要用单独的函数启动转发。
|
||||
|
||||
|
||||
Chain
|
||||
|
||||
|
||||
3
iics.go
3
iics.go
@@ -64,6 +64,9 @@ type incomingInserverConnState struct {
|
||||
inServer proxy.Server //可为 nil
|
||||
defaultClient proxy.Client
|
||||
|
||||
inTag string //在inServer为nil时,可用此项确定 inTag
|
||||
useSniffing bool //在inServer为nil时,可用此项确定 是否使用sniffing
|
||||
|
||||
cachedRemoteAddr string
|
||||
|
||||
inServerTlsConn *tlsLayer.Conn
|
||||
|
||||
16
main.go
16
main.go
@@ -516,8 +516,8 @@ func handshakeInserver_and_passToOutClient(iics incomingInserverConnState) {
|
||||
|
||||
}
|
||||
|
||||
//被 handshakeInserver_and_passToOutClient 和 handshakeInserver 的innerMux部分 调用。 iics.inServer可能为nil。
|
||||
// 本函数可能是本文件中 最长的函数。分别处理 回落,firstpayload,sniff,dns解析,分流,以及lazy。
|
||||
//被 handshakeInserver_and_passToOutClient 和 handshakeInserver 的innerMux部分 以及 tproxy 调用。 iics.inServer可能为nil。
|
||||
// 本函数可能是本文件中 最长的函数。分别处理 回落,firstpayload,sniff,dns解析,分流,以及lazy,最终转发到 某个 outClient。
|
||||
//
|
||||
// 会调用 dialClient_andRelay. 若isfallback为true,传入的 wlc 和 udp_wlc 必须为nil,targetAddr必须为空值。
|
||||
func passToOutClient(iics incomingInserverConnState, isfallback bool, wlc net.Conn, udp_wlc netLayer.MsgConn, targetAddr netLayer.Addr) {
|
||||
@@ -607,7 +607,7 @@ func passToOutClient(iics incomingInserverConnState, isfallback bool, wlc net.Co
|
||||
}
|
||||
|
||||
if wlc == nil && udp_wlc == nil {
|
||||
//无wlc证明 inServer 握手失败,且 没有任何回落可用, 直接退出。
|
||||
//证明 inServer 握手失败,且 没有任何回落可用, 直接退出。
|
||||
if ce := iics.CanLogDebug("invalid request and no matched fallback, hung up"); ce != nil {
|
||||
ce.Write()
|
||||
}
|
||||
@@ -729,7 +729,13 @@ func passToOutClient(iics incomingInserverConnState, isfallback bool, wlc net.Co
|
||||
|
||||
if len(iics.firstPayload) > 0 {
|
||||
|
||||
inserverMarkedSniffing := (inServer != nil && inServer.Sniffing())
|
||||
inserverMarkedSniffing := false
|
||||
|
||||
if inServer == nil {
|
||||
inserverMarkedSniffing = iics.useSniffing
|
||||
} else {
|
||||
inserverMarkedSniffing = inServer.Sniffing()
|
||||
}
|
||||
|
||||
dialIslazy := iics.defaultClient.IsLazyTls()
|
||||
|
||||
@@ -793,6 +799,8 @@ func passToOutClient(iics incomingInserverConnState, isfallback bool, wlc net.Co
|
||||
}
|
||||
if inServer != nil {
|
||||
desc.InTag = inServer.GetTag()
|
||||
} else {
|
||||
desc.InTag = iics.inTag
|
||||
}
|
||||
if uc, ok := wlc.(utils.User); ok {
|
||||
desc.UserIdentityStr = uc.IdentityStr()
|
||||
|
||||
@@ -105,7 +105,9 @@ http://ivo-wang.github.io/2018/02/24/ss-redir/
|
||||
package tproxy
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/e1732a364fed/v2ray_simple/netLayer"
|
||||
)
|
||||
@@ -120,10 +122,26 @@ type Machine struct {
|
||||
|
||||
func (m *Machine) Stop() {
|
||||
if m.Listener != nil {
|
||||
m.Listener.Close()
|
||||
log.Println("closing tproxy listener")
|
||||
//后来发现,不知为何,这个 Close调用会卡住
|
||||
|
||||
ch := make(chan int)
|
||||
go func() {
|
||||
m.Listener.Close()
|
||||
close(ch)
|
||||
}()
|
||||
tCh := time.After(time.Second)
|
||||
select {
|
||||
case <-tCh:
|
||||
log.Println("close tproxy listener timeout")
|
||||
case <-ch:
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
if m.UDPConn != nil {
|
||||
log.Println("closing tproxy udp conn")
|
||||
|
||||
m.UDPConn.Close()
|
||||
|
||||
}
|
||||
|
||||
@@ -8,6 +8,13 @@ import (
|
||||
"github.com/e1732a364fed/v2ray_simple/utils"
|
||||
)
|
||||
|
||||
//用于 tproxy 和 tun/tap 这种 只有 网络层 和传输层的情况
|
||||
type LesserConf struct {
|
||||
Addr string
|
||||
Tag string
|
||||
UseSniffing bool
|
||||
}
|
||||
|
||||
// CommonConf is the common part of ListenConf and DialConf.
|
||||
type CommonConf struct {
|
||||
Tag string `toml:"tag"` //可选
|
||||
|
||||
@@ -61,16 +61,25 @@ func (ClientCreator) NewClient(dc *proxy.DialConf) (proxy.Client, error) {
|
||||
c.user = utils.V2rayUser(uuid)
|
||||
c.opt = OptChunkStream
|
||||
|
||||
hasSetSecurityByExtra := false
|
||||
|
||||
if len(dc.Extra) > 0 {
|
||||
if thing := dc.Extra["vmess_security"]; thing != nil {
|
||||
if str, ok := thing.(string); ok {
|
||||
if err = c.specifySecurityByStr(str); err != nil {
|
||||
|
||||
err = c.specifySecurityByStr(str)
|
||||
|
||||
if err == nil {
|
||||
hasSetSecurityByExtra = true
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
||||
if !hasSetSecurityByExtra {
|
||||
c.specifySecurityByStr("")
|
||||
}
|
||||
|
||||
|
||||
@@ -11,15 +11,15 @@ import (
|
||||
)
|
||||
|
||||
//非阻塞。监听透明代理
|
||||
func ListenTproxy(addr string, defaultOutClientForThis proxy.Client, routePolicy *netLayer.RoutePolicy) (tm *tproxy.Machine) {
|
||||
func ListenTproxy(lc proxy.LesserConf, defaultOutClientForThis proxy.Client, routePolicy *netLayer.RoutePolicy) (tm *tproxy.Machine) {
|
||||
utils.Info("Start running Tproxy")
|
||||
|
||||
ad, err := netLayer.NewAddr(addr)
|
||||
ad, err := netLayer.NewAddr(lc.Addr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
//因为 tproxy比较特殊, 不属于 proxy.Server, 所以 需要 独立的 转发过程去处理.
|
||||
lis, err := startLoopTCP(ad, defaultOutClientForThis, &proxy.RoutingEnv{
|
||||
lis, err := startLoopTCP(ad, lc, defaultOutClientForThis, &proxy.RoutingEnv{
|
||||
RoutePolicy: routePolicy,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -28,7 +28,7 @@ func ListenTproxy(addr string, defaultOutClientForThis proxy.Client, routePolicy
|
||||
}
|
||||
return
|
||||
}
|
||||
udpConn := startLoopUDP(ad, defaultOutClientForThis, &proxy.RoutingEnv{
|
||||
udpConn := startLoopUDP(ad, lc, defaultOutClientForThis, &proxy.RoutingEnv{
|
||||
RoutePolicy: routePolicy,
|
||||
})
|
||||
|
||||
@@ -38,7 +38,7 @@ func ListenTproxy(addr string, defaultOutClientForThis proxy.Client, routePolicy
|
||||
}
|
||||
|
||||
//非阻塞
|
||||
func startLoopTCP(ad netLayer.Addr, defaultOutClientForThis proxy.Client, env *proxy.RoutingEnv) (net.Listener, error) {
|
||||
func startLoopTCP(ad netLayer.Addr, lc proxy.LesserConf, defaultOutClientForThis proxy.Client, env *proxy.RoutingEnv) (net.Listener, error) {
|
||||
return netLayer.ListenAndAccept("tcp", ad.String(), &netLayer.Sockopt{TProxy: true}, 0, func(conn net.Conn) {
|
||||
tcpconn := conn.(*net.TCPConn)
|
||||
targetAddr := tproxy.HandshakeTCP(tcpconn)
|
||||
@@ -48,6 +48,8 @@ func startLoopTCP(ad netLayer.Addr, defaultOutClientForThis proxy.Client, env *p
|
||||
}
|
||||
|
||||
passToOutClient(incomingInserverConnState{
|
||||
inTag: lc.Tag,
|
||||
useSniffing: lc.UseSniffing,
|
||||
wrappedConn: tcpconn,
|
||||
defaultClient: defaultOutClientForThis,
|
||||
routingEnv: env,
|
||||
@@ -57,7 +59,7 @@ func startLoopTCP(ad netLayer.Addr, defaultOutClientForThis proxy.Client, env *p
|
||||
}
|
||||
|
||||
//非阻塞
|
||||
func startLoopUDP(ad netLayer.Addr, defaultOutClientForThis proxy.Client, env *proxy.RoutingEnv) *net.UDPConn {
|
||||
func startLoopUDP(ad netLayer.Addr, lc proxy.LesserConf, defaultOutClientForThis proxy.Client, env *proxy.RoutingEnv) *net.UDPConn {
|
||||
ad.Network = "udp"
|
||||
conn, err := ad.ListenUDP_withOpt(&netLayer.Sockopt{TProxy: true})
|
||||
if err != nil {
|
||||
@@ -83,6 +85,8 @@ func startLoopUDP(ad netLayer.Addr, defaultOutClientForThis proxy.Client, env *p
|
||||
}
|
||||
|
||||
go passToOutClient(incomingInserverConnState{
|
||||
inTag: lc.Tag,
|
||||
useSniffing: lc.UseSniffing,
|
||||
defaultClient: defaultOutClientForThis,
|
||||
routingEnv: env,
|
||||
}, false, nil, msgConn, raddr)
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
//非阻塞。在非linux系统中无效。
|
||||
func ListenTproxy(string, proxy.Client, *netLayer.RoutePolicy) (_ *tproxy.Machine) {
|
||||
func ListenTproxy(lc proxy.LesserConf, defaultClient proxy.Client, routePolicy *netLayer.RoutePolicy) (_ *tproxy.Machine) {
|
||||
utils.Error("Tproxy not possible on non-linux device")
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user