mirror of
https://github.com/e1732a364fed/v2ray_simple.git
synced 2025-12-24 13:27:56 +08:00
取消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 方法
107 lines
2.1 KiB
Go
107 lines
2.1 KiB
Go
package proxy
|
||
|
||
import (
|
||
"errors"
|
||
"io"
|
||
"net"
|
||
"net/url"
|
||
|
||
"github.com/e1732a364fed/v2ray_simple/netLayer"
|
||
"github.com/e1732a364fed/v2ray_simple/utils"
|
||
)
|
||
|
||
const (
|
||
DirectName = "direct"
|
||
DirectURL = DirectName + "://"
|
||
)
|
||
|
||
// implements ClientCreator for direct
|
||
type DirectCreator struct{ CreatorCommonStruct }
|
||
|
||
func (DirectCreator) UseUDPAsMsgConn() bool {
|
||
return true
|
||
}
|
||
|
||
// true
|
||
func (DirectCreator) MultiTransportLayer() bool {
|
||
return true
|
||
}
|
||
|
||
func (DirectCreator) URLToDialConf(url *url.URL, iv *DialConf, format int) (*DialConf, error) {
|
||
if iv != nil {
|
||
return iv, nil
|
||
} else {
|
||
d := &DialConf{}
|
||
|
||
return d, nil
|
||
}
|
||
|
||
}
|
||
|
||
func (DirectCreator) NewClient(dc *DialConf) (Client, error) {
|
||
d := &DirectClient{}
|
||
|
||
if dc.Network == "" {
|
||
dc.Network = netLayer.DualNetworkName
|
||
}
|
||
|
||
return d, nil
|
||
}
|
||
|
||
type DirectClient struct {
|
||
Base
|
||
}
|
||
|
||
func (*DirectClient) Name() string { return DirectName }
|
||
func (*DirectClient) GetCreator() ClientCreator {
|
||
return DirectCreator{}
|
||
}
|
||
|
||
// 若 underlay 为nil,则会对target进行拨号, 否则返回underlay本身
|
||
func (d *DirectClient) Handshake(underlay net.Conn, firstPayload []byte, target netLayer.Addr) (result io.ReadWriteCloser, err error) {
|
||
if d.Network() == "udp" {
|
||
return nil, errors.New("direct's network set to udp, but Handshake called")
|
||
}
|
||
|
||
if underlay == nil {
|
||
|
||
result, err = d.Base.DialTCP(target)
|
||
|
||
} else {
|
||
result = underlay
|
||
|
||
}
|
||
if err != nil {
|
||
return
|
||
}
|
||
if len(firstPayload) > 0 {
|
||
_, err = result.Write(firstPayload)
|
||
utils.PutBytes(firstPayload)
|
||
|
||
}
|
||
|
||
return
|
||
|
||
}
|
||
|
||
// direct的Client的 EstablishUDPChannel 直接 监听一个udp端口,无视传入的net.Conn.
|
||
// 这是因为要考虑到fullcone.
|
||
func (d *DirectClient) EstablishUDPChannel(_ net.Conn, firstPayload []byte, target netLayer.Addr) (netLayer.MsgConn, error) {
|
||
if d.Network() == "tcp" {
|
||
return nil, errors.New("direct's network set to tcp, but EstablishUDPChannel called")
|
||
}
|
||
|
||
if len(firstPayload) == 0 {
|
||
|
||
return d.Base.DialUDP(target)
|
||
|
||
} else {
|
||
mc, err := d.Base.DialUDP(target)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return mc, mc.WriteMsgTo(firstPayload, target)
|
||
|
||
}
|
||
}
|