Files
v2ray_simple/proxy/dokodemo/server.go
hahahrfool ce735dbb99 修订udp代码; dial配置 添加 fullcone 选项;默认为非fullcone
现在整个程序均通过了go test, main 也可以正常运行了。

Relay_UDP 函数添加流量计数;

发现之前 Relay函数的流量计数 在main.go里参数传反了,导致实际上计数的是上传而不是下载,已修复

对fullcone的情况做了特别考量。MsgConn的 Close函数在fullcone时不能随便被调用。

因此我添加了一个 CloseConnWithRaddr(raddr Addr) error  方法,以及 Fullcone() bool     方法

在utils包的init部分使用 rand 随机种子
2022-04-08 20:31:59 +08:00

93 lines
2.9 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 是 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 }
func (s *Server) Handshake(underlay net.Conn) (io.ReadWriteCloser, netLayer.MsgConn, netLayer.Addr, error) {
if s.targetAddr.IsUDP() {
return nil, netLayer.UniTargetMsgConn{Conn: underlay}, s.targetAddr, nil
} else {
return underlay, nil, s.targetAddr, nil
}
}