Files
v2ray_simple/proxy/dokodemo/server.go
T
hahahrfool 447bd8749a 重构所有udp部分的代码! 摒弃了过去非常复杂的upd转发机制;
不再使用 UDP_Putter 等机制去转发udp,而是用一个 netLayer.MsgConn 结构

proxy.Server 和 proxy.Client 接口改动,

Client在握手udp时不再使用handshake方法, 而是用新的 EstablishUDPChannel 方法

Server 在 Handshake时会选择性返回两种接口,io.ReadWriteCloser 用于tcp, netLayer.MsgConn 用于 udp

此时vless、socks5、direct 的udp转发都已经成功经过了 go test 验证, 但是 main.go 还未修改。
2022-04-08 13:49:56 +08:00

89 lines
2.8 KiB
Go

/*Package dokodemo implements a dokodemo-door proxy.Server.
Server that wants to relay data to a dokodemo target address.
dokodemo 是 dokodemo-door 协议的实现。目前不含透明代理功能。
dokodemo 是 listen端, 监听一个普通的tcp端口,试图将一切流量转发到特定的预定义的地址. 并不是直接转发,而是转发到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 (
"errors"
"io"
"net"
"net/url"
"github.com/hahahrfool/v2ray_simple/netLayer"
"github.com/hahahrfool/v2ray_simple/proxy"
)
const name = "dokodemo"
func init() {
proxy.RegisterServer(name, &ServerCreator{})
}
type ServerCreator struct{}
// NewServerFromURL returns "Not implemented".
//因为 tcp:// 这种url没法轻易放在 url的query里,还需转义,所以不实用
func (_ ServerCreator) NewServerFromURL(*url.URL) (proxy.Server, error) {
return nil, errors.New("Not implemented")
}
// 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
}
type Server struct {
proxy.ProxyCommonStruct
targetAddr netLayer.Addr
}
func NewServer() (proxy.Server, error) {
d := &Server{}
return d, nil
}
func (d *Server) Name() string { return name }
//因为dokodemo的单目标性质, 不会建立任何udp通道.
func (s *Server) Handshake(underlay net.Conn) (io.ReadWriteCloser, netLayer.MsgConn, netLayer.Addr, error) {
return underlay, nil, s.targetAddr, nil
}