diff --git a/transport/internet/kcp/dialer.go b/transport/internet/kcp/dialer.go index 1879570c3..a66fd6475 100644 --- a/transport/internet/kcp/dialer.go +++ b/transport/internet/kcp/dialer.go @@ -1,17 +1,45 @@ package kcp import ( + "errors" + "math/rand" + "net" + v2net "github.com/v2ray/v2ray-core/common/net" "github.com/v2ray/v2ray-core/transport/internet" ) +var ( + ErrUnknownDestination = errors.New("Destination IP can't be resolved.") +) + func DialKCP(src v2net.Address, dest v2net.Destination) (internet.Connection, error) { - cpip, _ := NewNoneBlockCrypt(nil) - kcv, err := DialWithOptions(dest.NetAddr(), cpip) + var ip net.IP + if dest.Address().IsDomain() { + ips, err := net.LookupIP(dest.Address().Domain()) + if err != nil { + return nil, err + } + if len(ips) == 0 { + return nil, ErrUnknownDestination + } + ip = ips[0] + } else { + ip = dest.Address().IP() + } + udpAddr := &net.UDPAddr{ + IP: ip, + Port: int(dest.Port()), + } + + udpConn, err := net.ListenUDP("udp", &net.UDPAddr{}) if err != nil { return nil, err } - kcvn := &KCPVconn{hc: kcv} + + cpip, _ := NewNoneBlockCrypt(nil) + session := newUDPSession(rand.Uint32(), nil, udpConn, udpAddr, cpip) + kcvn := &KCPVconn{hc: session} err = kcvn.ApplyConf() if err != nil { return nil, err diff --git a/transport/internet/kcp/sess.go b/transport/internet/kcp/sess.go index 596312e66..7a53e2367 100644 --- a/transport/internet/kcp/sess.go +++ b/transport/internet/kcp/sess.go @@ -558,60 +558,6 @@ func (l *Listener) Addr() net.Addr { return l.conn.LocalAddr() } -// Listen listens for incoming KCP packets addressed to the local address laddr on the network "udp", -func Listen(laddr string) (*Listener, error) { - return ListenWithOptions(laddr, nil) -} - -// ListenWithOptions listens for incoming KCP packets addressed to the local address laddr on the network "udp" with packet encryption, -// FEC = 0 means no FEC, FEC > 0 means num(FEC) as a FEC cluster -func ListenWithOptions(laddr string, block BlockCrypt) (*Listener, error) { - udpaddr, err := net.ResolveUDPAddr("udp", laddr) - if err != nil { - return nil, err - } - conn, err := net.ListenUDP("udp", udpaddr) - if err != nil { - return nil, err - } - - l := new(Listener) - l.conn = conn - l.sessions = make(map[string]*UDPSession) - l.chAccepts = make(chan *UDPSession, 1024) - l.chDeadlinks = make(chan net.Addr, 1024) - l.die = make(chan struct{}) - l.block = block - - // caculate header size - if l.block != nil { - l.headerSize += cryptHeaderSize - } - - go l.monitor() - return l, nil -} - -// Dial connects to the remote address raddr on the network "udp" -func Dial(raddr string) (*UDPSession, error) { - return DialWithOptions(raddr, nil) -} - -// DialWithOptions connects to the remote address raddr on the network "udp" with packet encryption -func DialWithOptions(raddr string, block BlockCrypt) (*UDPSession, error) { - udpaddr, err := net.ResolveUDPAddr("udp", raddr) - if err != nil { - return nil, err - } - - for { - port := basePort + rand.Int()%(maxPort-basePort) - if udpconn, err := net.ListenUDP("udp", &net.UDPAddr{Port: port}); err == nil { - return newUDPSession(rand.Uint32(), nil, udpconn, udpaddr, block), nil - } - } -} - func currentMs() uint32 { return uint32(time.Now().UnixNano() / int64(time.Millisecond)) } diff --git a/transport/internet/kcp/session.go b/transport/internet/kcp/session.go index dccdd9a52..ef32dba27 100644 --- a/transport/internet/kcp/session.go +++ b/transport/internet/kcp/session.go @@ -75,8 +75,6 @@ type KCPVconn struct { conntokeep time.Time } -//var counter int - func (kcpvc *KCPVconn) Read(b []byte) (int, error) { ifb := time.Now().Add(time.Duration(effectiveConfig.ReadTimeout) * time.Second) if ifb.After(kcpvc.conntokeep) { @@ -117,8 +115,6 @@ func (kcpvc *KCPVconn) ApplyConf() error { kcpvc.hc.SetMtu(effectiveConfig.Mtu) kcpvc.hc.SetACKNoDelay(effectiveConfig.Acknodelay) kcpvc.hc.SetDSCP(effectiveConfig.Dscp) - //counter++ - //log.Info(counter) return nil } @@ -129,8 +125,6 @@ or the VMess EOF can be too late to send. func (kcpvc *KCPVconn) Close() error { go func() { time.Sleep(2000 * time.Millisecond) - //counter-- - //log.Info(counter) kcpvc.hc.Close() }() return nil @@ -165,11 +159,31 @@ func (this *KCPVconn) SetReusable(b bool) { } func ListenKCP(address v2net.Address, port v2net.Port) (internet.Listener, error) { - laddr := address.String() + ":" + port.String() - crypt, _ := NewNoneBlockCrypt(nil) - kcl, err := ListenWithOptions(laddr, crypt) - kcvl := &KCPVlistener{lst: kcl} - return kcvl, err + conn, err := net.ListenUDP("udp", &net.UDPAddr{ + IP: address.IP(), + Port: int(port), + }) + if err != nil { + return nil, err + } + + block, _ := NewNoneBlockCrypt(nil) + + l := new(Listener) + l.conn = conn + l.sessions = make(map[string]*UDPSession) + l.chAccepts = make(chan *UDPSession, 1024) + l.chDeadlinks = make(chan net.Addr, 1024) + l.die = make(chan struct{}) + l.block = block + + // caculate header size + if l.block != nil { + l.headerSize += cryptHeaderSize + } + + go l.monitor() + return &KCPVlistener{lst: l}, nil } func init() {