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 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 (this *Router) TakeDetour(dest v2net.Destination) (string, error) { destStr := dest.String() found, tag, err := this.cache.Get(destStr) if !found { tag, err := this.takeDetourWithoutCache(dest) this.cache.Set(destStr, tag, err) return tag, err } return tag, err }
func (this *UDPServer) Dispatch(source v2net.Destination, packet v2net.Packet, callback UDPResponseCallback) { destString := source.String() + "-" + packet.Destination().String() if this.locateExistingAndDispatch(destString, packet) { return } this.Lock() inboundRay := this.packetDispatcher.DispatchToOutbound(v2net.NewPacket(packet.Destination(), packet.Chunk(), true)) this.conns[destString] = &connEntry{ inboundRay: inboundRay, callback: callback, } this.Unlock() go this.handleConnection(destString, inboundRay, source, callback) }
func (this *UDPServer) Dispatch(source v2net.Destination, destination v2net.Destination, payload *alloc.Buffer, callback UDPResponseCallback) { destString := source.String() + "-" + destination.String() log.Debug("UDP Server: Dispatch request: ", destString) if this.locateExistingAndDispatch(destString, payload) { return } log.Info("UDP Server: establishing new connection for ", destString) inboundRay := this.packetDispatcher.DispatchToOutbound(destination) timedInboundRay := NewTimedInboundRay(destString, inboundRay, this) outputStream := timedInboundRay.InboundInput() if outputStream != nil { outputStream.Write(payload) } this.Lock() this.conns[destString] = timedInboundRay this.Unlock() go this.handleConnection(timedInboundRay, source, callback) }
func startCommunicate(request *protocol.VMessRequest, dest v2net.Destination, ray ray.OutboundRay, firstPacket v2net.Packet) error { var destIp net.IP if dest.Address().IsIPv4() || dest.Address().IsIPv6() { destIp = dest.Address().IP() } else { ips, err := net.LookupIP(dest.Address().Domain()) if err != nil { return err } destIp = ips[0] } conn, err := net.DialTCP("tcp", nil, &net.TCPAddr{ IP: destIp, Port: int(dest.Port()), }) 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, (request.Command == protocol.CmdUDP)) requestFinish.Lock() conn.CloseWrite() responseFinish.Lock() return nil }
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 }