func startCommunicate(request *protocol.VMessRequest, dest v2net.Destination, ray core.OutboundRay, firstPacket v2net.Packet) error { conn, err := net.Dial(dest.Network(), dest.Address().String()) if err != nil { log.Error("Failed to open %s: %v", dest.String(), err) if ray != nil { close(ray.OutboundOutput()) } return err } log.Info("VMessOut: Tunneling request to %s via %s", request.Address.String(), dest.String()) defer conn.Close() input := ray.OutboundInput() output := ray.OutboundOutput() var requestFinish, responseFinish sync.Mutex requestFinish.Lock() responseFinish.Lock() go handleRequest(conn, request, firstPacket, input, &requestFinish) go handleResponse(conn, request, output, &responseFinish, dest.IsUDP()) requestFinish.Lock() if tcpConn, ok := conn.(*net.TCPConn); ok { tcpConn.CloseWrite() } responseFinish.Lock() return nil }
func startCommunicate(request *protocol.VMessRequest, dest *v2net.Destination, ray core.OutboundRay) error { input := ray.OutboundInput() output := ray.OutboundOutput() conn, err := net.DialTCP(dest.Network(), nil, &net.TCPAddr{dest.Address().IP(), int(dest.Address().Port()), ""}) if err != nil { log.Error("Failed to open tcp (%s): %v", dest.String(), err) close(output) return err } log.Info("VMessOut: Tunneling request for %s", request.Address.String()) defer conn.Close() requestFinish := make(chan bool) responseFinish := make(chan bool) go handleRequest(conn, request, input, requestFinish) go handleResponse(conn, request, output, responseFinish) <-requestFinish conn.CloseWrite() <-responseFinish return nil }
func (this *FieldRule) Apply(dest v2net.Destination) bool { address := dest.Address() if len(this.Domain) > 0 { if !address.IsDomain() { return false } foundMatch := false for _, domain := range this.Domain { if domain.Match(address.Domain()) { foundMatch = true break } } if !foundMatch { return false } } if this.IP != nil && len(this.IP) > 0 { if !(address.IsIPv4() || address.IsIPv6()) { return false } foundMatch := false for _, ipnet := range this.IP { if ipnet.Contains(address.IP()) { foundMatch = true break } } if !foundMatch { return false } } if this.Port != nil { port := dest.Port() if port.Value() < this.Port.From().Value() || port.Value() > this.Port.To().Value() { return false } } if this.Network != nil { if !this.Network.HasNetwork(v2net.Network(dest.Network())) { return false } } return true }
func startCommunicate(request *protocol.VMessRequest, dest v2net.Destination, ray core.OutboundRay, firstPacket v2net.Packet) error { conn, err := net.DialTCP(dest.Network(), nil, &net.TCPAddr{dest.Address().IP(), int(dest.Address().Port()), ""}) if err != nil { log.Error("Failed to open tcp (%s): %v", dest.String(), err) if ray != nil { close(ray.OutboundOutput()) } return err } log.Info("VMessOut: Tunneling request for %s", request.Address.String()) defer conn.Close() if chunk := firstPacket.Chunk(); chunk != nil { conn.Write(chunk) } if !firstPacket.MoreChunks() { if ray != nil { close(ray.OutboundOutput()) } return nil } input := ray.OutboundInput() output := ray.OutboundOutput() var requestFinish, responseFinish sync.Mutex requestFinish.Lock() responseFinish.Lock() go handleRequest(conn, request, input, &requestFinish) go handleResponse(conn, request, output, &responseFinish) requestFinish.Lock() conn.CloseWrite() responseFinish.Lock() return nil }
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()) }
func (this *NetworkMatcher) Apply(dest v2net.Destination) bool { return this.network.HasNetwork(v2net.Network(dest.Network())) }