func ReadUserPassRequest(reader io.Reader) (request Socks5UserPassRequest, err error) { buffer := alloc.NewSmallBuffer() defer buffer.Release() _, err = reader.Read(buffer.Value[0:2]) if err != nil { return } request.version = buffer.Value[0] nUsername := buffer.Value[1] nBytes, err := reader.Read(buffer.Value[:nUsername]) if err != nil { return } request.username = string(buffer.Value[:nBytes]) _, err = reader.Read(buffer.Value[0:1]) if err != nil { return } nPassword := buffer.Value[0] nBytes, err = reader.Read(buffer.Value[:nPassword]) if err != nil { return } request.password = string(buffer.Value[:nBytes]) return }
func ReadRequest(reader io.Reader) (request *Socks5Request, err error) { buffer := alloc.NewSmallBuffer() defer buffer.Release() _, err = io.ReadFull(reader, buffer.Value[:4]) if err != nil { return } request = &Socks5Request{ Version: buffer.Value[0], Command: buffer.Value[1], // buffer[2] is a reserved field AddrType: buffer.Value[3], } switch request.AddrType { case AddrTypeIPv4: _, err = io.ReadFull(reader, request.IPv4[:]) if err != nil { return } case AddrTypeDomain: _, err = io.ReadFull(reader, buffer.Value[0:1]) if err != nil { return } domainLength := buffer.Value[0] _, err = io.ReadFull(reader, buffer.Value[:domainLength]) if err != nil { return } request.Domain = string(append([]byte(nil), buffer.Value[:domainLength]...)) case AddrTypeIPv6: _, err = io.ReadFull(reader, request.IPv6[:]) if err != nil { return } default: log.Warning("Socks: Unexpected address type ", request.AddrType) err = transport.ErrCorruptedPacket return } _, err = io.ReadFull(reader, buffer.Value[:2]) if err != nil { return } request.Port = v2net.PortFromBytes(buffer.Value[:2]) return }
func (this *Server) handleConnection(conn internet.Connection) { defer conn.Close() buffer := alloc.NewSmallBuffer() defer buffer.Release() timedReader := v2net.NewTimeOutReader(16, conn) defer timedReader.Release() bufferedReader := v2io.NewBufferedReader(timedReader) defer bufferedReader.Release() ivLen := this.config.Cipher.IVSize() _, err := io.ReadFull(bufferedReader, buffer.Value[:ivLen]) if err != nil { if err != io.EOF { log.Access(conn.RemoteAddr(), "", log.AccessRejected, err) log.Warning("Shadowsocks: Failed to read IV: ", err) } return } iv := buffer.Value[:ivLen] key := this.config.Key stream, err := this.config.Cipher.NewDecodingStream(key, iv) if err != nil { log.Error("Shadowsocks: Failed to create decoding stream: ", err) return } reader := crypto.NewCryptionReader(stream, bufferedReader) request, err := ReadRequest(reader, NewAuthenticator(HeaderKeyGenerator(key, iv)), false) if err != nil { log.Access(conn.RemoteAddr(), "", log.AccessRejected, err) log.Warning("Shadowsocks: Invalid request from ", conn.RemoteAddr(), ": ", err) return } defer request.Release() bufferedReader.SetCached(false) userSettings := protocol.GetUserSettings(this.config.Level) timedReader.SetTimeOut(userSettings.PayloadReadTimeout) dest := v2net.TCPDestination(request.Address, request.Port) log.Access(conn.RemoteAddr(), dest, log.AccessAccepted, "") log.Info("Shadowsocks: Tunnelling request to ", dest) ray := this.packetDispatcher.DispatchToOutbound(this.meta, &proxy.SessionInfo{ Source: v2net.DestinationFromAddr(conn.RemoteAddr()), Destination: dest, }) defer ray.InboundOutput().Release() var writeFinish sync.Mutex writeFinish.Lock() go func() { if payload, err := ray.InboundOutput().Read(); err == nil { payload.SliceBack(ivLen) rand.Read(payload.Value[:ivLen]) stream, err := this.config.Cipher.NewEncodingStream(key, payload.Value[:ivLen]) if err != nil { log.Error("Shadowsocks: Failed to create encoding stream: ", err) return } stream.XORKeyStream(payload.Value[ivLen:], payload.Value[ivLen:]) conn.Write(payload.Value) payload.Release() writer := crypto.NewCryptionWriter(stream, conn) v2writer := v2io.NewAdaptiveWriter(writer) v2io.Pipe(ray.InboundOutput(), v2writer) writer.Release() v2writer.Release() } writeFinish.Unlock() }() var payloadReader v2io.Reader if request.OTA { payloadAuth := NewAuthenticator(ChunkKeyGenerator(iv)) payloadReader = NewChunkReader(reader, payloadAuth) } else { payloadReader = v2io.NewAdaptiveReader(reader) } v2io.Pipe(payloadReader, ray.InboundInput()) ray.InboundInput().Close() payloadReader.Release() writeFinish.Lock() }
func ReadRequest(reader io.Reader, auth *Authenticator, udp bool) (*Request, error) { buffer := alloc.NewSmallBuffer() defer buffer.Release() _, err := io.ReadFull(reader, buffer.Value[:1]) if err != nil { if err != io.EOF { log.Warning("Shadowsocks: Failed to read address type: ", err) return nil, transport.ErrCorruptedPacket } return nil, err } lenBuffer := 1 request := new(Request) addrType := (buffer.Value[0] & 0x0F) if (buffer.Value[0] & 0x10) == 0x10 { request.OTA = true } switch addrType { case AddrTypeIPv4: _, err := io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+4]) if err != nil { log.Warning("Shadowsocks: Failed to read IPv4 address: ", err) return nil, transport.ErrCorruptedPacket } request.Address = v2net.IPAddress(buffer.Value[lenBuffer : lenBuffer+4]) lenBuffer += 4 case AddrTypeIPv6: _, err := io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+16]) if err != nil { log.Warning("Shadowsocks: Failed to read IPv6 address: ", err) return nil, transport.ErrCorruptedPacket } request.Address = v2net.IPAddress(buffer.Value[lenBuffer : lenBuffer+16]) lenBuffer += 16 case AddrTypeDomain: _, err := io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+1]) if err != nil { log.Warning("Shadowsocks: Failed to read domain lenth: ", err) return nil, transport.ErrCorruptedPacket } domainLength := int(buffer.Value[lenBuffer]) lenBuffer++ _, err = io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+domainLength]) if err != nil { log.Warning("Shadowsocks: Failed to read domain: ", err) return nil, transport.ErrCorruptedPacket } request.Address = v2net.DomainAddress(string(buffer.Value[lenBuffer : lenBuffer+domainLength])) lenBuffer += domainLength default: log.Warning("Shadowsocks: Unknown address type: ", addrType) return nil, transport.ErrCorruptedPacket } _, err = io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+2]) if err != nil { log.Warning("Shadowsocks: Failed to read port: ", err) return nil, transport.ErrCorruptedPacket } request.Port = v2net.PortFromBytes(buffer.Value[lenBuffer : lenBuffer+2]) lenBuffer += 2 var authBytes []byte if udp { nBytes, err := reader.Read(buffer.Value[lenBuffer:]) if err != nil { log.Warning("Shadowsocks: Failed to read UDP payload: ", err) return nil, transport.ErrCorruptedPacket } buffer.Slice(0, lenBuffer+nBytes) if request.OTA { authBytes = buffer.Value[lenBuffer+nBytes-AuthSize:] request.UDPPayload = alloc.NewSmallBuffer().Clear().Append(buffer.Value[lenBuffer : lenBuffer+nBytes-AuthSize]) lenBuffer = lenBuffer + nBytes - AuthSize } else { request.UDPPayload = alloc.NewSmallBuffer().Clear().Append(buffer.Value[lenBuffer:]) } } else { if request.OTA { authBytes = buffer.Value[lenBuffer : lenBuffer+AuthSize] _, err = io.ReadFull(reader, authBytes) if err != nil { log.Warning("Shadowsocks: Failed to read OTA: ", err) return nil, transport.ErrCorruptedPacket } } } if request.OTA { actualAuth := auth.Authenticate(nil, buffer.Value[0:lenBuffer]) if !bytes.Equal(actualAuth, authBytes) { log.Warning("Shadowsocks: Invalid OTA.") return nil, proxy.ErrInvalidAuthentication } } return request, nil }