| 
					
				 | 
			
			
				@@ -279,7 +279,7 @@ func writeSocks5Response(writer io.Writer, errCode byte, address net.Address, po 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 func writeSocks4Response(writer io.Writer, errCode byte, address net.Address, port net.Port) error { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	buffer := buf.NewLocal(32) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	buffer.AppendBytes(0x00, errCode) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	buffer.AppendSupplier(serial.WriteUint16(port.Value())) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	common.Must(buffer.AppendSupplier(serial.WriteUint16(port.Value()))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	buffer.Append(address.IP()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	_, err := writer.Write(buffer.Bytes()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return err 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -392,6 +392,40 @@ func (w *UDPWriter) Write(b []byte) (int, error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return len(b), nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func ReadAddress(b *buf.Buffer, addrType byte, reader io.Reader) (net.Address, net.Port, error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	var address net.Address 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	switch addrType { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case addrTypeIPv4: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if err := b.AppendSupplier(buf.ReadFullFrom(reader, 4)); err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return nil, 0, err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		address = net.IPAddress(b.BytesFrom(-4)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case addrTypeIPv6: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if err := b.AppendSupplier(buf.ReadFullFrom(reader, 16)); err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return nil, 0, err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		address = net.IPAddress(b.BytesFrom(-16)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case addrTypeDomain: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if err := b.AppendSupplier(buf.ReadFullFrom(reader, 1)); err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return nil, 0, err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		domainLength := int(b.Byte(b.Len() - 1)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if err := b.AppendSupplier(buf.ReadFullFrom(reader, domainLength)); err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return nil, 0, err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		address = net.DomainAddress(string(b.BytesFrom(-domainLength))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return nil, 0, newError("unknown address type: ", addrType) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if err := b.AppendSupplier(buf.ReadFullFrom(reader, 2)); err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return nil, 0, err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	port := net.PortFromBytes(b.BytesFrom(-2)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return address, port, nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 func ClientHandshake(request *protocol.RequestHeader, reader io.Reader, writer io.Writer) (*protocol.RequestHeader, error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	authByte := byte(authNotRequired) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if request.User != nil { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -444,7 +478,10 @@ func ClientHandshake(request *protocol.RequestHeader, reader io.Reader, writer i 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		command = byte(cmdUDPPort) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	b.AppendBytes(socks5Version, command, 0x00 /* reserved */) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	AppendAddress(b, request.Address, request.Port) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if err := AppendAddress(b, request.Address, request.Port); err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return nil, err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if _, err := writer.Write(b.Bytes()); err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return nil, err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -463,35 +500,10 @@ func ClientHandshake(request *protocol.RequestHeader, reader io.Reader, writer i 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	b.Clear() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	var address net.Address 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	switch addrType { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	case addrTypeIPv4: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if err := b.AppendSupplier(buf.ReadFullFrom(reader, 4)); err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return nil, err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		address = net.IPAddress(b.Bytes()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	case addrTypeIPv6: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if err := b.AppendSupplier(buf.ReadFullFrom(reader, 16)); err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return nil, err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		address = net.IPAddress(b.Bytes()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	case addrTypeDomain: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if err := b.AppendSupplier(buf.ReadFullFrom(reader, 1)); err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return nil, err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		domainLength := int(b.Byte(0)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if err := b.AppendSupplier(buf.ReadFullFrom(reader, domainLength)); err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return nil, err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		address = net.DomainAddress(string(b.BytesFrom(-domainLength))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return nil, newError("unknown address type: ", addrType) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if err := b.AppendSupplier(buf.ReadFullFrom(reader, 2)); err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	address, port, err := ReadAddress(b, addrType, reader) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return nil, err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	port := net.PortFromBytes(b.BytesFrom(-2)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if request.Command == protocol.RequestCommandUDP { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		udpRequest := &protocol.RequestHeader{ 
			 |