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() { v2io.ChanToRawWriter(this.ConnOutput, input) writeFinish.Unlock() }() writeFinish.Lock() } v2io.RawReaderToChan(output, this.ConnInput) close(output) return nil }
func (this *InboundConnectionHandler) Communicate(packet v2net.Packet) error { ray := this.PacketDispatcher.DispatchToOutbound(packet) input := ray.InboundInput() output := ray.InboundOutput() readFinish := &sync.Mutex{} writeFinish := &sync.Mutex{} readFinish.Lock() writeFinish.Lock() go func() { v2io.RawReaderToChan(input, this.ConnInput) close(input) readFinish.Unlock() }() go func() { v2io.ChanToRawWriter(this.ConnOutput, output) writeFinish.Unlock() }() readFinish.Lock() writeFinish.Lock() return nil }
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() { v2io.ChanToRawWriter(conn, input) writeMutex.Unlock() }() } go func() { defer readMutex.Unlock() defer close(output) var reader io.Reader = conn if firstPacket.Destination().IsUDP() { reader = v2net.NewTimeOutReader(16 /* seconds */, conn) } v2io.RawReaderToChan(output, reader) }() writeMutex.Lock() if tcpConn, ok := conn.(*net.TCPConn); ok { tcpConn.CloseWrite() } readMutex.Lock() 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() { v2io.ChanToRawWriter(ioutil.Discard, ray.OutboundInput()) } 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() { v2io.RawReaderToChan(ray.InboundInput(), input) close(ray.InboundInput()) wg.Done() }() go func() { v2io.ChanToRawWriter(output, ray.InboundOutput()) wg.Done() }() }
func (this *SocksServer) transport(reader io.Reader, writer io.Writer, firstPacket v2net.Packet) { ray := this.packetDispatcher.DispatchToOutbound(firstPacket) input := ray.InboundInput() output := ray.InboundOutput() var inputFinish, outputFinish sync.Mutex inputFinish.Lock() outputFinish.Lock() go func() { v2io.RawReaderToChan(input, reader) inputFinish.Unlock() close(input) }() go func() { v2io.ChanToRawWriter(writer, output) outputFinish.Unlock() }() outputFinish.Lock() }
func dumpOutput(writer io.Writer, output <-chan *alloc.Buffer, finish *sync.Mutex) { v2io.ChanToRawWriter(writer, output) finish.Unlock() }
func (this *Shadowsocks) handleConnection(conn *hub.TCPConn) { defer conn.Close() buffer := alloc.NewSmallBuffer() defer buffer.Release() _, err := io.ReadFull(conn, buffer.Value[:this.config.Cipher.IVSize()]) if err != nil { log.Access(conn.RemoteAddr(), serial.StringLiteral(""), log.AccessRejected, serial.StringLiteral(err.Error())) 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, NewAuthenticator(HeaderKeyGenerator(iv, key)), false) if err != nil { log.Access(conn.RemoteAddr(), serial.StringLiteral(""), log.AccessRejected, serial.StringLiteral(err.Error())) log.Warning("Shadowsocks: Invalid request from ", conn.RemoteAddr(), ": ", err) return } dest := v2net.TCPDestination(request.Address, request.Port) log.Access(conn.RemoteAddr(), dest, log.AccessAccepted, serial.StringLiteral("")) log.Info("Shadowsocks: Tunnelling request to ", dest) packet := v2net.NewPacket(dest, nil, true) ray := this.packetDispatcher.DispatchToOutbound(packet) var writeFinish sync.Mutex writeFinish.Lock() go func() { if payload, ok := <-ray.InboundOutput(); ok { payload.SliceBack(16) rand.Read(payload.Value[:16]) writer, err := this.config.Cipher.NewEncodingStream(key, payload.Value[:16], conn) if err != nil { log.Error("Shadowsocks: Failed to create encoding stream: ", err) return } writer.Write(payload.Value) payload.Release() v2io.ChanToRawWriter(writer, ray.InboundOutput()) } writeFinish.Unlock() }() var payloadReader v2io.Reader if request.OTA { payloadAuth := NewAuthenticator(ChunkKeyGenerator(iv)) payloadReader = NewChunkReader(reader, payloadAuth) } else { payloadReader = v2io.NewAdaptiveReader(reader) } v2io.ReaderToChan(ray.InboundInput(), payloadReader) close(ray.InboundInput()) writeFinish.Lock() }