Files
v2ray_simple/proxy/dokodemo/server.go
e1732a364fed a9a746ba2f 多项对接口的修改,为ss做准备:
取消Client的LocalAddr,改为 LocalTCPAddr 和 LocalUDPAddr
删除direct中的对应条目。这样可更清晰地配置双本地地址

将设置sendthrough设置双地址的代码移动到 proxy.newClient函数

这样不仅direct可指定不同的tcp和udp的本地地址,任何client协议都可以了

为ClientCreator 接口 添加 UseUDPAsMsgConn 方法,direct和ss返回true

在ss的client的EstablishUDPChannel进行自行拨号

在ss的server建立后,自动循环监听udp,绕过vs的基本监听机制。因为vs架构的限制,一个代理只能有一个唯一的传输层协议。

ServerCreator 接口 添加 AfterCommonConfServer 方法
2022-12-03 23:51:51 +08:00

100 lines
3.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
Package dokodemo implements a dokodemo-door proxy.Server.
Server that wants to relay data to a dokodemo target address.
dokodemo 是 v2ray的 dokodemo-door 协议的实现。不含透明代理功能。
严格来说 dokodemo-door 并不是一个 "协议", 而是一个预先指定目标的转发方式。
dokodemo 是 listen端, 监听一个普通的tcp/udp端口试图将一切流量转发到特定的预定义的地址. 并不是直接连接而是转发到dial。
dokodemo 属于 “单目标”代理而其它proxy.Server 一般都属于 “泛目标”代理。
内部实际上就是 指定了目标的 纯tcp/udp协议属于监听协议中最简单、最纯粹的一种。
# Example 应用例子
使用 dokodemo 做监听用direct 拨号指定一个target那么实际上就是把 该监听的节点 与远程target间建立了一个信道;
dokodemo 每监听到一个新连接, 就会新增一条 与 target 间的信道.
所以可能比较适合 中转机的情况,
比如如果有两个服务器 A和 B 和客户C。
我们只告诉C 服务器B 的地址然后告诉它B使用vless协议。然后C就会用vless协议对B 拨号。
此时B我们实际配置 为用 dokodemo 监听而不是用vless监听然后 dokodemo 的目标 指向 服务器A 的 vless监听端口.
这样就形成了一个中转机制.
实际例子:
https://www.40huo.cn/blog/wireguard-over-vless.html
就是说,任意门把客户数据的出口、自己的入口点从本地搬到了某个代理服务器的入口,然后指定了该数据的实际远程目标;就好像数据是从代理服务器直接发出的一样.
到底是哪个代理服务器由outbound即本作的dial以及routing配置决定的。如果没有配置routing那就是默认走第一个dial.
*/
package dokodemo
import (
"net"
"net/url"
"github.com/e1732a364fed/v2ray_simple/netLayer"
"github.com/e1732a364fed/v2ray_simple/proxy"
"github.com/e1732a364fed/v2ray_simple/utils"
)
const name = "dokodemo"
func init() {
proxy.RegisterServer(name, &ServerCreator{})
}
type ServerCreator struct{ proxy.CreatorCommonStruct }
func (ServerCreator) URLToListenConf(url *url.URL, lc *proxy.ListenConf, format int) (*proxy.ListenConf, error) {
if format != proxy.StandardMode {
return lc, utils.ErrUnImplemented
}
if lc == nil {
return nil, utils.ErrNilParameter
}
return lc, nil
}
// use lc.TargetAddr
func (ServerCreator) NewServer(lc *proxy.ListenConf) (proxy.Server, error) {
ta, e := netLayer.NewAddrByURL(lc.TargetAddr)
if e != nil {
return nil, e
}
s := &Server{
targetAddr: ta,
}
return s, nil
}
// implements proxy.Server
type Server struct {
proxy.Base
targetAddr netLayer.Addr
}
func NewServer() (proxy.Server, error) {
d := &Server{}
return d, nil
}
func (*Server) Name() string { return name }
func (s *Server) Handshake(underlay net.Conn) (net.Conn, netLayer.MsgConn, netLayer.Addr, error) {
if s.targetAddr.IsUDP() {
return nil, netLayer.UniTargetMsgConn{Conn: underlay, Target: s.targetAddr}, s.targetAddr, nil
} else {
return underlay, nil, s.targetAddr, nil
}
}