func Dial(dest v2net.Destination) (net.Conn, error) { if dest.Address().IsDomain() { dialer := &net.Dialer{ Timeout: time.Second * 60, DualStack: true, } network := "tcp" if dest.IsUDP() { network = "udp" } return dialer.Dial(network, dest.NetAddr()) } ip := dest.Address().IP() if dest.IsTCP() { return net.DialTCP("tcp", nil, &net.TCPAddr{ IP: ip, Port: int(dest.Port()), }) } else { return net.DialUDP("udp", nil, &net.UDPAddr{ IP: ip, Port: int(dest.Port()), }) } }
func (this *Listener) OnReceive(payload *alloc.Buffer, src v2net.Destination) { defer payload.Release() if valid := this.block.Open(payload); !valid { log.Info("KCP|Listener: discarding invalid payload from ", src) return } if !this.running { return } this.Lock() defer this.Unlock() if !this.running { return } if payload.Len() < 4 { return } conv := serial.BytesToUint16(payload.Value) cmd := Command(payload.Value[2]) sourceId := src.NetAddr() + "|" + serial.Uint16ToString(conv) conn, found := this.sessions[sourceId] if !found { if cmd == CommandTerminate { return } log.Debug("KCP|Listener: Creating session with id(", sourceId, ") from ", src) writer := &Writer{ id: sourceId, hub: this.hub, dest: src, listener: this, } srcAddr := &net.UDPAddr{ IP: src.Address().IP(), Port: int(src.Port()), } conn = NewConnection(conv, writer, this.localAddr, srcAddr, this.block) select { case this.awaitingConns <- conn: case <-time.After(time.Second * 5): conn.Close() return } this.sessions[sourceId] = conn } conn.Input(payload.Value) }
func DialToDest(src v2net.Address, dest v2net.Destination) (net.Conn, error) { dialer := &net.Dialer{ Timeout: time.Second * 60, DualStack: true, } if src != nil && src != v2net.AnyIP { var addr net.Addr if dest.IsTCP() { addr = &net.TCPAddr{ IP: src.IP(), Port: 0, } } else { addr = &net.UDPAddr{ IP: src.IP(), Port: 0, } } dialer.LocalAddr = addr } return dialer.Dial(dest.Network().String(), dest.NetAddr()) }