다음을 통해 공유


더 나은 인터페이스 및 메서드 디자인을 위한 IDL 기술

준수 및 변형 데이터를 모두 처리하는 RPC 인터페이스 및 메서드를 개발할 때 다음 IDL 관련 기술을 사용하여 보안 및 성능을 개선하는 것이 좋습니다. 이 항목에서 참조되는 특성은 규칙 데이터(예: [size_is] 및 [max_is] 특성) 또는 변형 데이터(예: [length_is] 및 [문자열] 특성)를 처리하는 메서드 매개 변수에 설정된 IDL 특성입니다.

준수 데이터 매개 변수와 함께 [range] 특성 사용

[range] 특성은 데이터 구분 해제 프로세스 중에 추가 크기 유효성 검사를 수행하도록 RPC 런타임에 지시합니다. 특히 연결된 매개 변수로 전달된 데이터의 제공된 크기가 지정된 범위 내에 있는지 확인합니다.

[range] 특성은 와이어 형식에 영향을 주지 않습니다.

와이어의 값이 허용 범위를 벗어나면 RPC는 RPC_X_INVALID_BOUND throw하거나 예외를 RPC_X_BAD_STUB_DATA. 이렇게 하면 추가 수준의 데이터 유효성 검사가 제공되고 버퍼 오버런과 같은 일반적인 보안 오류를 방지할 수 있습니다. 마찬가지로 [range]를 사용하면 표시된 규칙적인 데이터에 RPC 서비스에서 고려할 수 있는 명확하게 정의된 제약 조건이 있으므로 애플리케이션 성능을 향상시킬 수 있습니다.

RPC Server 스텁 메모리 관리 규칙

RPC 지원 애플리케이션에 대한 IDL 파일을 만들 때 RPC 서버 스텁 메모리 관리 규칙을 이해하는 것이 중요합니다. 애플리케이션은 위에서 설명한 대로 [range]를 준수 데이터와 함께 사용할 뿐만 아니라 [length_is]와 같은 가변 길이 데이터 IDL 특성이 규칙적인 데이터에 의도적으로 적용되지 않도록 하여 서버 리소스 사용률을 향상시킬 수 있습니다.

IDL 파일에 정의된 데이터 구조 필드에 [length_is]을 적용하는 것은 권장되지 않습니다.

가변 길이 데이터 매개 변수에 대한 모범 사례

다음은 변수 크기의 데이터 구조, 메서드 매개 변수 및 필드에 대한 IDL 특성을 정의할 때 고려해야 할 몇 가지 모범 사례입니다.

  • 초기 상관 관계를 사용합니다. 일반적으로 제어 정수 형식 직후에 발생하도록 변수 크기 매개 변수 또는 필드를 정의하는 것이 좋습니다.

    예를 들면 다음과 같습니다.

    earlyCorr
    (
    [in, range(MIN_COUNT, MAX_COUNT)] long size, 
    [in,size_is(size)] char *pv
    );
    

    가 아래보다 좋습니다.

    lateCorr
    (
    [in,size_is(size)] char *pv, 
    [in, range(MIN_COUNT, MAX_COUNT)] long size)
    );
    

    여기서 earlyCorr는 가변 길이 데이터 매개 변수 바로 앞에 크기 매개 변수를 선언하고 lateCorr는 크기 매개 변수를 선언합니다. 초기 대응을 사용하면 특히 메서드가 자주 호출되는 경우 전반적인 성능이 향상됩니다.

  • [out, size_is] 특성 튜플로 표시된 매개 변수의 경우 및 클라이언트 쪽에서 데이터 길이가 알려지거나 클라이언트에 적절한 상한이 있는 경우 메서드 정의는 매개 변수 특성 및 시퀀스 측면에서 다음과 유사해야 합니다.

    outKnownSize
    (
    [in,range(MIN_COUNT, MAX_COUNT)] long lSize,
    [out,size_is(lSize)] UserDataType * pArr
    );
    

    이 경우 클라이언트는 pArr에 대한 고정 크기 버퍼를 제공하여 서버 쪽 RPC 서비스가 적절한 수준의 보증으로 적절한 크기의 버퍼를 할당할 수 있도록 합니다. 예제에서 데이터는 서버([out])에서 수신됩니다. 정의는 서버에 전달된 데이터에 대해 유사합니다([in]).

  • RPC 애플리케이션의 서버 쪽 구성 요소가 데이터 길이를 결정하는 경우 메서드 정의는 다음과 유사해야 합니다.

    typedef [range(MIN_COUNT,MAX_COUNT)] long RANGED_LONG;
    
    outUnknownSize
    (
    [out] RANGED_LONG *pSize,
    [out,size_is(,*pSize)] UserDataType **ppArr
    );
    

    RANGED_LONG 클라이언트와 서버 스텁 모두에 대해 정의된 형식이며 클라이언트가 올바르게 예상할 수 있는 지정된 크기입니다. 이 예제에서 클라이언트는 ppArrNULL전달하고 RPC 서버 애플리케이션 구성 요소는 올바른 양의 메모리를 할당합니다. 반환 시 클라이언트 쪽의 RPC 서비스는 반환된 데이터에 대한 메모리를 할당합니다.

  • 클라이언트가 큰 규칙 배열의 하위 집합을 서버에 보내려는 경우 애플리케이션은 다음 예제와 같이 하위 집합의 크기를 지정할 수 있습니다.

    inConformantVaryingArray
    (
    [in,range(MIN_COUNT,MAX_COUNT)] long lSize,
    [in] long lLength, 
    [in,size_is(lSize), length_is(lLength)] UserDataType *pArr
    );
    

    이러한 방식으로 RPC는 와이어를 통해 배열의 lLength 요소만 전송합니다. 그러나 이 정의는 RPC 서비스가 서버 쪽에서 lSize 크기의 메모리를 할당하도록 강제합니다.

  • 클라이언트 애플리케이션 구성 요소에서 서버가 반환할 수 있는 배열의 최대 크기를 결정하지만 서버가 해당 배열의 하위 집합을 전송하도록 허용하는 경우 애플리케이션은 다음 예제와 유사한 IDL을 정의하여 이러한 동작을 지정할 수 있습니다.

    inMaxSizeOutLength
    (
    [in, range(MIN_COUNT, MAX_COUNT)] long lSize,
    [out] long *pLength,
    [out,size_is(lSize), length_is(*pLength)] UserDataType *pArr
    );
    

    클라이언트 애플리케이션 구성 요소는 배열의 최대 크기를 지정하고 서버는 클라이언트로 다시 전송하는 요소 수를 지정합니다.

  • 서버 애플리케이션 구성 요소가 클라이언트 애플리케이션 구성 요소에 문자열을 반환해야 하고 클라이언트가 서버에서 반환할 최대 크기를 알고 있는 경우 애플리케이션은 다음 예제와 같이 규칙적인 문자열 형식을 사용할 수 있습니다.

    outStringKnownSize
    (
    [in,range(MIN_COUNT, MAX_STRING)] long lSize,
    [out,size_is(lSize),string] wchar_t *pString
    );
    
  • 클라이언트 애플리케이션 구성 요소가 문자열의 크기를 제어하지 않아야 하는 경우 RPC 서비스는 다음 예제와 같이 메모리를 특별히 할당할 수 있습니다.

    outStringUnknownSize
    (
    [out] LPWSTR *ppStr
    );
    

    클라이언트 애플리케이션 구성 요소는 RPC 메서드를 호출할 때 ppStr을 NULL로 설정해야 합니다.