func handleRequest(conn *net.TCPConn, request *protocol.VMessRequest, input <-chan []byte, finish *sync.Mutex) { defer finish.Unlock() encryptRequestWriter, err := v2io.NewAesEncryptWriter(request.RequestKey[:], request.RequestIV[:], conn) if err != nil { log.Error("VMessOut: Failed to create encrypt writer: %v", err) return } buffer := make([]byte, 0, 2*1024) buffer, err = request.ToBytes(user.NewTimeHash(user.HMACHash{}), user.GenerateRandomInt64InRange, buffer) if err != nil { log.Error("VMessOut: Failed to serialize VMess request: %v", err) return } // Send first packet of payload together with request, in favor of small requests. payload, open := <-input if open { encryptRequestWriter.Crypt(payload) buffer = append(buffer, payload...) _, err = conn.Write(buffer) if err != nil { log.Error("VMessOut: Failed to write VMess request: %v", err) return } v2net.ChanToWriter(encryptRequestWriter, input) } return }
func (this *OutboundConnectionHandler) Dispatch(packet v2net.Packet, ray ray.OutboundRay) error { input := ray.OutboundInput() output := ray.OutboundOutput() this.Destination = packet.Destination() if packet.Chunk() != nil { this.ConnOutput.Write(packet.Chunk().Value) packet.Chunk().Release() } if packet.MoreChunks() { writeFinish := &sync.Mutex{} writeFinish.Lock() go func() { v2net.ChanToWriter(this.ConnOutput, input) writeFinish.Unlock() }() writeFinish.Lock() } v2net.ReaderToChan(output, this.ConnInput) close(output) return nil }
func (this *InboundConnectionHandler) Communicate(packet v2net.Packet) error { ray := this.Dispatcher.DispatchToOutbound(packet) input := ray.InboundInput() output := ray.InboundOutput() readFinish := &sync.Mutex{} writeFinish := &sync.Mutex{} readFinish.Lock() writeFinish.Lock() go func() { v2net.ReaderToChan(input, this.ConnInput) close(input) readFinish.Unlock() }() go func() { v2net.ChanToWriter(this.ConnOutput, output) writeFinish.Unlock() }() readFinish.Lock() writeFinish.Lock() return nil }
func (this *FreedomConnection) Dispatch(firstPacket v2net.Packet, ray ray.OutboundRay) error { conn, err := net.Dial(firstPacket.Destination().Network(), firstPacket.Destination().Address().String()) log.Info("Freedom: Opening connection to %s", firstPacket.Destination().String()) if err != nil { close(ray.OutboundOutput()) log.Error("Freedom: Failed to open connection: %s : %v", firstPacket.Destination().String(), err) return err } input := ray.OutboundInput() output := ray.OutboundOutput() var readMutex, writeMutex sync.Mutex readMutex.Lock() writeMutex.Lock() if chunk := firstPacket.Chunk(); chunk != nil { conn.Write(chunk.Value) chunk.Release() } if !firstPacket.MoreChunks() { writeMutex.Unlock() } else { go func() { v2net.ChanToWriter(conn, input) writeMutex.Unlock() }() } go func() { defer readMutex.Unlock() defer close(output) response, err := v2net.ReadFrom(conn, nil) log.Info("Freedom receives %d bytes from %s", response.Len(), conn.RemoteAddr().String()) if response.Len() > 0 { output <- response } else { response.Release() } if err != nil { return } if firstPacket.Destination().IsUDP() { return } v2net.ReaderToChan(output, conn) }() writeMutex.Lock() if tcpConn, ok := conn.(*net.TCPConn); ok { tcpConn.CloseWrite() } readMutex.Lock() conn.Close() return nil }
func (this *BlackHole) Dispatch(firstPacket v2net.Packet, ray ray.OutboundRay) error { if chunk := firstPacket.Chunk(); chunk != nil { chunk.Release() } close(ray.OutboundOutput()) if firstPacket.MoreChunks() { v2net.ChanToWriter(ioutil.Discard, ray.OutboundInput()) } return nil }
func (handler *InboundConnectionHandler) Communicate(packet v2net.Packet) error { ray := handler.Server.DispatchToOutbound(packet) input := ray.InboundInput() output := ray.InboundOutput() input <- handler.Data2Send close(input) v2net.ChanToWriter(handler.DataReturned, output) return nil }
func (handler *InboundConnectionHandler) Communicate(dest v2net.Destination) error { ray := handler.Server.NewInboundConnectionAccepted(dest) input := ray.InboundInput() output := ray.InboundOutput() input <- handler.Data2Send close(input) v2net.ChanToWriter(handler.DataReturned, output) return nil }
func runBenchmarkTransport(size int) { transportChanA := make(chan *alloc.Buffer, 16) transportChanB := make(chan *alloc.Buffer, 16) readerA := &StaticReader{size, 0} readerB := &StaticReader{size, 0} writerA := ioutil.Discard writerB := ioutil.Discard finishA := make(chan bool) finishB := make(chan bool) go func() { v2net.ChanToWriter(writerA, transportChanA) close(finishA) }() go func() { v2net.ReaderToChan(transportChanA, readerA) close(transportChanA) }() go func() { v2net.ChanToWriter(writerB, transportChanB) close(finishB) }() go func() { v2net.ReaderToChan(transportChanB, readerB) close(transportChanB) }() <-transportChanA <-transportChanB }
func (handler *InboundConnectionHandler) Communicate(packet v2net.Packet) error { ray := handler.Server.DispatchToOutbound(packet) input := ray.InboundInput() output := ray.InboundOutput() buffer := alloc.NewBuffer() buffer.Clear() buffer.Append(handler.Data2Send) input <- buffer close(input) v2net.ChanToWriter(handler.DataReturned, output) return nil }
func (this *HttpProxyServer) transport(input io.Reader, output io.Writer, ray ray.InboundRay) { var wg sync.WaitGroup wg.Add(2) defer wg.Wait() go func() { v2net.ReaderToChan(ray.InboundInput(), input) close(ray.InboundInput()) wg.Done() }() go func() { v2net.ChanToWriter(output, ray.InboundOutput()) wg.Done() }() }
func handleRequest(conn net.Conn, request *protocol.VMessRequest, firstPacket v2net.Packet, input <-chan *alloc.Buffer, finish *sync.Mutex) { defer finish.Unlock() aesStream, err := v2crypto.NewAesEncryptionStream(request.RequestKey[:], request.RequestIV[:]) if err != nil { log.Error("VMessOut: Failed to create AES encryption stream: ", err) return } encryptRequestWriter := v2crypto.NewCryptionWriter(aesStream, conn) buffer := alloc.NewBuffer().Clear() defer buffer.Release() buffer, err = request.ToBytes(protocol.NewRandomTimestampGenerator(protocol.Timestamp(time.Now().Unix()), 30), buffer) if err != nil { log.Error("VMessOut: Failed to serialize VMess request: ", err) return } // Send first packet of payload together with request, in favor of small requests. firstChunk := firstPacket.Chunk() moreChunks := firstPacket.MoreChunks() for firstChunk == nil && moreChunks { firstChunk, moreChunks = <-input } if firstChunk == nil && !moreChunks { log.Warning("VMessOut: Nothing to send. Existing...") return } aesStream.XORKeyStream(firstChunk.Value, firstChunk.Value) buffer.Append(firstChunk.Value) firstChunk.Release() _, err = conn.Write(buffer.Value) if err != nil { log.Error("VMessOut: Failed to write VMess request: ", err) return } if moreChunks { v2net.ChanToWriter(encryptRequestWriter, input) } return }
func handleRequest(conn net.Conn, request *protocol.VMessRequest, firstPacket v2net.Packet, input <-chan *alloc.Buffer, finish *sync.Mutex) { defer finish.Unlock() encryptRequestWriter, err := v2io.NewAesEncryptWriter(request.RequestKey[:], request.RequestIV[:], conn) if err != nil { log.Error("VMessOut: Failed to create encrypt writer: %v", err) return } buffer := alloc.NewBuffer() buffer.Clear() requestBytes, err := request.ToBytes(user.NewTimeHash(user.HMACHash{}), user.GenerateRandomInt64InRange, buffer.Value) if err != nil { log.Error("VMessOut: Failed to serialize VMess request: %v", err) return } // Send first packet of payload together with request, in favor of small requests. firstChunk := firstPacket.Chunk() moreChunks := firstPacket.MoreChunks() if firstChunk == nil && moreChunks { firstChunk, moreChunks = <-input } if firstChunk != nil { encryptRequestWriter.Crypt(firstChunk.Value) requestBytes = append(requestBytes, firstChunk.Value...) firstChunk.Release() _, err = conn.Write(requestBytes) buffer.Release() if err != nil { log.Error("VMessOut: Failed to write VMess request: %v", err) return } } if moreChunks { v2net.ChanToWriter(encryptRequestWriter, input) } return }
func (this *SocksServer) transport(reader io.Reader, writer io.Writer, firstPacket v2net.Packet) { ray := this.space.PacketDispatcher().DispatchToOutbound(firstPacket) input := ray.InboundInput() output := ray.InboundOutput() var inputFinish, outputFinish sync.Mutex inputFinish.Lock() outputFinish.Lock() go func() { v2net.ReaderToChan(input, reader) inputFinish.Unlock() close(input) }() go func() { v2net.ChanToWriter(writer, output) outputFinish.Unlock() }() outputFinish.Lock() }
func TestReaderAndWrite(t *testing.T) { v2testing.Current(t) size := 1024 * 1024 buffer := make([]byte, size) nBytes, err := rand.Read(buffer) assert.Int(nBytes).Equals(len(buffer)) assert.Error(err).IsNil() readerBuffer := bytes.NewReader(buffer) writerBuffer := bytes.NewBuffer(make([]byte, 0, size)) transportChan := make(chan *alloc.Buffer, 1024) err = v2net.ReaderToChan(transportChan, readerBuffer) assert.Error(err).Equals(io.EOF) close(transportChan) err = v2net.ChanToWriter(writerBuffer, transportChan) assert.Error(err).IsNil() assert.Bytes(buffer).Equals(writerBuffer.Bytes()) }
func (vconn *FreedomConnection) DumpInput(conn net.Conn, input <-chan []byte, finish chan<- bool) { v2net.ChanToWriter(conn, input) finish <- true }
func (server *SocksServer) dumpOutput(writer io.Writer, output <-chan []byte, finish chan<- bool) { v2net.ChanToWriter(writer, output) log.Debug("Socks output closed") finish <- true }
func dumpOutput(writer io.Writer, output <-chan []byte, finish chan<- bool) { v2net.ChanToWriter(writer, output) close(finish) }
func dumpInput(conn net.Conn, input <-chan []byte, finish *sync.Mutex) { v2net.ChanToWriter(conn, input) finish.Unlock() }
func dumpInput(conn net.Conn, input <-chan []byte, finish chan<- bool) { v2net.ChanToWriter(conn, input) close(finish) }
func dumpOutput(writer io.Writer, output <-chan []byte, finish *sync.Mutex) { v2net.ChanToWriter(writer, output) finish.Unlock() }
func (this *FreedomConnection) Dispatch(firstPacket v2net.Packet, ray ray.OutboundRay) error { log.Info("Freedom: Opening connection to ", firstPacket.Destination()) var conn net.Conn err := retry.Timed(5, 100).On(func() error { rawConn, err := dialer.Dial(firstPacket.Destination()) if err != nil { return err } conn = rawConn return nil }) if err != nil { close(ray.OutboundOutput()) log.Error("Freedom: Failed to open connection to ", firstPacket.Destination(), ": ", err) return err } defer conn.Close() input := ray.OutboundInput() output := ray.OutboundOutput() var readMutex, writeMutex sync.Mutex readMutex.Lock() writeMutex.Lock() if chunk := firstPacket.Chunk(); chunk != nil { conn.Write(chunk.Value) chunk.Release() } if !firstPacket.MoreChunks() { writeMutex.Unlock() } else { go func() { v2net.ChanToWriter(conn, input) writeMutex.Unlock() }() } go func() { defer readMutex.Unlock() defer close(output) response, err := v2net.ReadFrom(conn, nil) log.Info("Freedom receives ", response.Len(), " bytes from ", conn.RemoteAddr()) if response.Len() > 0 { output <- response } else { response.Release() } if err != nil { return } if firstPacket.Destination().IsUDP() { return } v2net.ReaderToChan(output, conn) }() if this.space.HasDnsCache() { if firstPacket.Destination().Address().IsDomain() { domain := firstPacket.Destination().Address().Domain() addr := conn.RemoteAddr() switch typedAddr := addr.(type) { case *net.TCPAddr: this.space.DnsCache().Add(domain, typedAddr.IP) case *net.UDPAddr: this.space.DnsCache().Add(domain, typedAddr.IP) } } } writeMutex.Lock() if tcpConn, ok := conn.(*net.TCPConn); ok { tcpConn.CloseWrite() } readMutex.Lock() return nil }
func (this *Shadowsocks) handleConnection(conn *listener.TCPConn) { defer conn.Close() buffer := alloc.NewSmallBuffer() defer buffer.Release() _, err := v2net.ReadAllBytes(conn, buffer.Value[:this.config.Cipher.IVSize()]) if err != nil { log.Error("Shadowsocks: Failed to read IV: ", err) return } iv := buffer.Value[:this.config.Cipher.IVSize()] key := this.config.Key reader, err := this.config.Cipher.NewDecodingStream(key, iv, conn) if err != nil { log.Error("Shadowsocks: Failed to create decoding stream: ", err) return } request, err := ReadRequest(reader) if err != nil { return } packet := v2net.NewPacket(v2net.TCPDestination(request.Address, request.Port), nil, true) ray := this.space.PacketDispatcher().DispatchToOutbound(packet) respIv := make([]byte, this.config.Cipher.IVSize()) rand.Read(respIv) writer, err := this.config.Cipher.NewEncodingStream(key, respIv, conn) if err != nil { log.Error("Shadowsocks: Failed to create encoding stream: ", err) return } var writeFinish sync.Mutex writeFinish.Lock() go func() { firstChunk := alloc.NewBuffer().Clear() defer firstChunk.Release() firstChunk.Append(respIv) if payload, ok := <-ray.InboundOutput(); ok { firstChunk.Append(payload.Value) payload.Release() writer.Write(firstChunk.Value) v2net.ChanToWriter(writer, ray.InboundOutput()) } writeFinish.Unlock() }() v2net.ReaderToChan(ray.InboundInput(), reader) close(ray.InboundInput()) writeFinish.Lock() }
func handleOutput(request *protocol.VMessRequest, writer io.Writer, output <-chan []byte, finish chan<- bool) { v2net.ChanToWriter(writer, output) close(finish) }
func handleOutput(request *protocol.VMessRequest, writer io.Writer, output <-chan *alloc.Buffer, finish *sync.Mutex) { v2net.ChanToWriter(writer, output) finish.Unlock() }
func dumpOutput(writer io.Writer, output <-chan *alloc.Buffer, finish *sync.Mutex) { v2net.ChanToWriter(writer, output) finish.Unlock() }
func dumpInput(conn net.Conn, input <-chan *alloc.Buffer, finish *sync.Mutex) { v2net.ChanToWriter(conn, input) finish.Unlock() }