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 handleResponse(conn *net.TCPConn, request *protocol.VMessRequest, output chan<- []byte, finish *sync.Mutex) { defer finish.Unlock() defer close(output) responseKey := md5.Sum(request.RequestKey[:]) responseIV := md5.Sum(request.RequestIV[:]) decryptResponseReader, err := v2io.NewAesDecryptReader(responseKey[:], responseIV[:], conn) if err != nil { log.Error("VMessOut: Failed to create decrypt reader: %v", err) return } response := protocol.VMessResponse{} nBytes, err := decryptResponseReader.Read(response[:]) if err != nil { log.Error("VMessOut: Failed to read VMess response (%d bytes): %v", nBytes, err) log.Error(InfoTimeNotSync) return } if !bytes.Equal(response[:], request.ResponseHeader[:]) { log.Warning("VMessOut: unexepcted response header. The connection is probably hijacked.") return } v2net.ReaderToChan(output, decryptResponseReader) return }
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 handleResponse(conn net.Conn, request *protocol.VMessRequest, output chan<- []byte, finish *sync.Mutex, isUDP bool) { defer finish.Unlock() defer close(output) responseKey := md5.Sum(request.RequestKey[:]) responseIV := md5.Sum(request.RequestIV[:]) decryptResponseReader, err := v2io.NewAesDecryptReader(responseKey[:], responseIV[:], conn) if err != nil { log.Error("VMessOut: Failed to create decrypt reader: %v", err) return } buffer := make([]byte, 2*1024) nBytes, err := decryptResponseReader.Read(buffer) if err != nil { //log.Error("VMessOut: Failed to read VMess response (%d bytes): %v", nBytes, err) return } if !bytes.Equal(buffer[:4], request.ResponseHeader[:]) { log.Warning("VMessOut: unexepcted response header. The connection is probably hijacked.") return } output <- buffer[4:nBytes] if !isUDP { v2net.ReaderToChan(output, decryptResponseReader) } return }
func handleResponse(conn net.Conn, request *protocol.VMessRequest, output chan<- *alloc.Buffer, finish *sync.Mutex, isUDP bool) { defer finish.Unlock() defer close(output) responseKey := md5.Sum(request.RequestKey[:]) responseIV := md5.Sum(request.RequestIV[:]) decryptResponseReader, err := v2io.NewAesDecryptReader(responseKey[:], responseIV[:], conn) if err != nil { log.Error("VMessOut: Failed to create decrypt reader: %v", err) return } buffer, err := v2net.ReadFrom(decryptResponseReader, nil) if err != nil { log.Error("VMessOut: Failed to read VMess response (%d bytes): %v", buffer.Len(), err) return } if buffer.Len() < 4 || !bytes.Equal(buffer.Value[:4], request.ResponseHeader[:]) { log.Warning("VMessOut: unexepcted response header. The connection is probably hijacked.") return } log.Info("VMessOut received %d bytes from %s", buffer.Len()-4, conn.RemoteAddr().String()) buffer.SliceFrom(4) output <- buffer if !isUDP { v2net.ReaderToChan(output, decryptResponseReader) } return }
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 handleInput(request *protocol.VMessRequest, reader io.Reader, input chan<- *alloc.Buffer, finish *sync.Mutex) { defer close(input) defer finish.Unlock() requestReader, err := v2io.NewAesDecryptReader(request.RequestKey, request.RequestIV, reader) if err != nil { log.Error("VMessIn: Failed to create decrypt reader: %v", err) return } v2net.ReaderToChan(input, requestReader) }
func handleInput(request *protocol.VMessRequest, reader io.Reader, input chan<- *alloc.Buffer, finish *sync.Mutex) { defer close(input) defer finish.Unlock() aesStream, err := v2crypto.NewAesDecryptionStream(request.RequestKey, request.RequestIV) if err != nil { log.Error("VMessIn: Failed to create AES decryption stream: ", err) return } requestReader := v2crypto.NewCryptionReader(aesStream, reader) v2net.ReaderToChan(input, requestReader) }
func handleInput(request *protocol.VMessRequest, reader io.Reader, input chan<- []byte, finish chan<- bool) { defer close(input) defer close(finish) requestReader, err := v2io.NewAesDecryptReader(request.RequestKey[:], request.RequestIV[:], reader) if err != nil { log.Error("VMessIn: Failed to create decrypt reader: %v", err) return } v2net.ReaderToChan(input, requestReader) }
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 handleResponse(conn net.Conn, request *protocol.VMessRequest, output chan<- *alloc.Buffer, finish *sync.Mutex, isUDP bool) { defer finish.Unlock() defer close(output) responseKey := md5.Sum(request.RequestKey[:]) responseIV := md5.Sum(request.RequestIV[:]) aesStream, err := v2crypto.NewAesDecryptionStream(responseKey[:], responseIV[:]) if err != nil { log.Error("VMessOut: Failed to create AES encryption stream: ", err) return } decryptResponseReader := v2crypto.NewCryptionReader(aesStream, conn) buffer, err := v2net.ReadFrom(decryptResponseReader, nil) if err != nil { log.Error("VMessOut: Failed to read VMess response (", buffer.Len(), " bytes): ", err) buffer.Release() return } if buffer.Len() < 4 || !headerMatch(request, buffer.Value[:2]) { log.Warning("VMessOut: unexepcted response header. The connection is probably hijacked.") return } log.Info("VMessOut received ", buffer.Len()-4, " bytes from ", conn.RemoteAddr()) responseBegin := 4 if buffer.Value[2] != 0 { dataLen := int(buffer.Value[3]) if buffer.Len() < dataLen+4 { // Rare case diffBuffer := make([]byte, dataLen+4-buffer.Len()) v2net.ReadAllBytes(decryptResponseReader, diffBuffer) buffer.Append(diffBuffer) } command := buffer.Value[2] data := buffer.Value[4 : 4+dataLen] go handleCommand(command, data) responseBegin = 4 + dataLen } buffer.SliceFrom(responseBegin) output <- buffer if !isUDP { v2net.ReaderToChan(output, decryptResponseReader) } return }
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 dumpOutput(conn net.Conn, output chan<- []byte, finish *sync.Mutex, udp bool) { defer finish.Unlock() defer close(output) response, err := v2net.ReadFrom(conn) if len(response) > 0 { output <- response } if err != nil { return } if udp { return } v2net.ReaderToChan(output, conn) }
func dumpOutput(conn net.Conn, output chan<- []byte, finish *sync.Mutex, udp bool) { defer finish.Unlock() defer close(output) response, err := v2net.ReadFrom(conn) log.Info("Freedom receives %d bytes from %s", len(response), conn.RemoteAddr().String()) if len(response) > 0 { output <- response } if err != nil { return } if udp { return } v2net.ReaderToChan(output, conn) }
func dumpOutput(conn net.Conn, output chan<- *alloc.Buffer, finish *sync.Mutex, udp bool) { defer finish.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 udp { return } v2net.ReaderToChan(output, conn) }
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 dumpInput(reader io.Reader, input chan<- *alloc.Buffer, finish *sync.Mutex) { v2net.ReaderToChan(input, reader) finish.Unlock() close(input) }
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 (server *SocksServer) dumpInput(reader io.Reader, input chan<- []byte, finish chan<- bool) { v2net.ReaderToChan(input, reader) close(input) log.Debug("Socks input closed") finish <- true }
func dumpOutput(conn net.Conn, output chan<- []byte, finish chan<- bool) { v2net.ReaderToChan(output, conn) close(output) close(finish) }
func (vconn *FreedomConnection) DumpOutput(conn net.Conn, output chan<- []byte, finish chan<- bool) { v2net.ReaderToChan(output, conn) close(output) finish <- true }
func dumpOutput(conn net.Conn, output chan<- []byte, finish *sync.Mutex) { v2net.ReaderToChan(output, conn) finish.Unlock() close(output) }
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 dumpInput(reader io.Reader, input chan<- []byte, finish chan<- bool) { v2net.ReaderToChan(input, reader) close(input) close(finish) }