fix #144, 令direct拨号时使用sockopt.

This commit is contained in:
e1732a364fed
2000-01-01 00:00:00 +00:00
parent 27c81b60e8
commit 9dacc9e44b
5 changed files with 36 additions and 13 deletions

View File

@@ -1042,14 +1042,15 @@ func dialClient(iics incomingInserverConnState, targetAddr netLayer.Addr,
}
realTargetAddr.Network = client.Network()
}
var clientConn net.Conn
var clientConn net.Conn //拨号所得到的net.Conn, 在下面代码中 会一层层进行包装
var dialedCommonConn any
not_udp_direct := !(client.Name() == proxy.DirectName && isudp)
not_direct := !(client.Name() == proxy.DirectName)
/*
direct 的udp 是自己拨号的,因为要考虑到fullcone。
direct 的tcp也是自己拨号因为还考虑到 sockopt
不是direct的udp的话也要分情况:
如果是单路的, 则我们在此dial, 如果是多路复用, 则不行, 因为要复用同一个连接
@@ -1061,7 +1062,7 @@ func dialClient(iics incomingInserverConnState, targetAddr netLayer.Addr,
var muxC advLayer.MuxClient
if not_udp_direct {
if not_direct {
if adv != "" && advClient.IsMux() {

View File

@@ -361,10 +361,26 @@ type UDPMsgConn struct {
// 如果是普通的单目标的客户端,用 (nil,false,false) 即可.
//
// 满足fullcone/symmetric, 由 fullcone 的值决定.
func NewUDPMsgConn(laddr *net.UDPAddr, fullcone bool, isserver bool) (*UDPMsgConn, error) {
func NewUDPMsgConn(laddr *net.UDPAddr, fullcone bool, isserver bool, sockopt *Sockopt) (*UDPMsgConn, error) {
uc := new(UDPMsgConn)
var udpConn *net.UDPConn
var err error
if sockopt != nil {
if laddr == nil {
laddr = &net.UDPAddr{}
}
a := NewAddrFromUDPAddr(laddr)
pConn, e := a.ListenUDP_withOpt(sockopt)
if e != nil {
err = e
} else {
udpConn = pConn.(*net.UDPConn)
}
} else {
udpConn, err = net.ListenUDP("udp", laddr)
}
udpConn, err := net.ListenUDP("udp", laddr)
if err != nil {
return nil, err
}

View File

@@ -25,6 +25,10 @@ func (DirectCreator) NewClientFromURL(url *url.URL) (Client, error) {
func (DirectCreator) NewClient(dc *DialConf) (Client, error) {
d := &DirectClient{}
if dc.Sockopt != nil {
opt := *dc.Sockopt
d.Sockopt = &opt
}
return d, nil
}
@@ -38,7 +42,11 @@ func (*DirectClient) Name() string { return DirectName }
func (d *DirectClient) Handshake(underlay net.Conn, firstPayload []byte, target netLayer.Addr) (result io.ReadWriteCloser, err error) {
if underlay == nil {
result, err = target.Dial()
if d.Sockopt != nil {
result, err = target.DialWithOpt(d.Sockopt)
} else {
result, err = target.Dial()
}
} else {
result = underlay
@@ -48,7 +56,7 @@ func (d *DirectClient) Handshake(underlay net.Conn, firstPayload []byte, target
return
}
if len(firstPayload) > 0 {
_, err = underlay.Write(firstPayload)
_, err = result.Write(firstPayload)
utils.PutBytes(firstPayload)
}
@@ -60,10 +68,10 @@ func (d *DirectClient) Handshake(underlay net.Conn, firstPayload []byte, target
//direct的Client的 EstablishUDPChannel 直接 监听一个udp端口无视传入的net.Conn.
func (d *DirectClient) EstablishUDPChannel(_ net.Conn, firstPayload []byte, target netLayer.Addr) (netLayer.MsgConn, error) {
if len(firstPayload) == 0 {
return netLayer.NewUDPMsgConn(nil, d.IsFullcone, false)
return netLayer.NewUDPMsgConn(nil, d.IsFullcone, false, d.Sockopt)
} else {
mc, err := netLayer.NewUDPMsgConn(nil, d.IsFullcone, false)
mc, err := netLayer.NewUDPMsgConn(nil, d.IsFullcone, false, d.Sockopt)
if err != nil {
return nil, err
}

View File

@@ -106,9 +106,7 @@ func GetFullName(pc BaseInterface) string {
// return GetFullName(pc) + "://" + pc.AddrStr() (+ #tag)
func GetVSI_url(pc BaseInterface) string {
n := pc.Name()
if n == DirectName {
return DirectURL
}
sb := getFullNameBuilder(pc, n)
sb.WriteString("://")
sb.WriteString(pc.AddrStr())

View File

@@ -269,7 +269,7 @@ func TestUDP(protocol string, version int, proxyPort string, use_multi int, t *t
na, _ := netLayer.NewAddr(remoteAddrStr)
na.Network = "udp"
wrc, err := netLayer.NewUDPMsgConn(nil, false, false)
wrc, err := netLayer.NewUDPMsgConn(nil, false, false, nil)
if err != nil {
t.Logf("failed netLayer.NewUDPMsgConn\n")
t.Fail()