Compartir a través de


Técnicas IDL para mejorar la interfaz y el diseño de métodos

Considere la posibilidad de usar las siguientes técnicas específicas de IDL para mejorar la seguridad y el rendimiento cuando desarrolle interfaces y métodos de RPC que controlen los datos conformes y variantes. Los atributos a los que se hace referencia en este tema son los atributos IDL establecidos en los parámetros de método que controlan datos conformes (por ejemplo, los atributos [size_is] y [max_is] ) o los datos variantes (por ejemplo, los atributos [length_is] y [string]).

Uso del atributo [range] con parámetros de datos conformes

El atributo [range] indica al tiempo de ejecución de RPC que realice una validación de tamaño adicional durante el proceso de deserialización de datos. En concreto, comprueba que el tamaño proporcionado de los datos pasados como parámetro asociado esté dentro del intervalo especificado.

El atributo [range] no afecta al formato de conexión.

Si el valor de la conexión está fuera del intervalo permitido, RPC producirá una excepción de RPC_X_INVALID_BOUND o RPC_X_BAD_STUB_DATA. Esto proporciona un nivel adicional de validación de datos y puede ayudar a evitar errores de seguridad comunes, como saturaciones de búfer. Del mismo modo, el uso de [range] puede mejorar el rendimiento de la aplicación, ya que los datos conformes marcados con él tienen restricciones claramente definidas disponibles para su consideración por el servicio RPC.

Reglas de administración de memoria de código auxiliar del servidor RPC

Es importante comprender las reglas de administración de memoria de código auxiliar del servidor RPC al crear los archivos IDL para una aplicación habilitada para RPC. Las aplicaciones pueden mejorar el uso de recursos del servidor mediante [range] junto con datos conformes como se indicó anteriormente, así como evitar deliberadamente la aplicación de atributos IDL de datos de longitud variable como [length_is] a los datos conformes.

No se recomienda la aplicación de [length_is] a los campos de estructura de datos definidos en un archivo IDL.

Procedimientos recomendados para parámetros de datos de longitud variable

A continuación se muestran varios procedimientos recomendados que se deben tener en cuenta al definir los atributos IDL para estructuras de datos de tamaño variable, parámetros de método y campos.

  • Use la correlación temprana. Por lo general, es mejor definir el parámetro o campo de tamaño variable de forma que se produzca inmediatamente después del tipo entero de control.

    Por ejemplo,

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

    es mejor que

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

    Donde earlyCorr declara el parámetro de tamaño inmediatamente antes del parámetro de datos de longitud variable y lateCorr declara el parámetro de tamaño después de él. El uso de la correspondencia temprana mejora el rendimiento general, especialmente en los casos en los que se llama con frecuencia al método.

  • Para los parámetros marcados con la tupla de atributo [out, size_is] y donde la longitud de los datos se conoce en el lado cliente o donde el cliente tiene un límite superior razonable, la definición del método debe ser similar a la siguiente en términos de atribución y secuencia de parámetros:

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

    En este caso, el cliente proporciona un búfer de tamaño fijo para pArr, lo que permite al servicio RPC del lado servidor asignar un búfer de tamaño razonable con un buen grado de garantía. Tenga en cuenta que, en el ejemplo, los datos se reciben del servidor ([out]). La definición es similar para los datos pasados al servidor ([in]).

  • En situaciones en las que el componente del lado servidor de una aplicación RPC decide la longitud de los datos, la definición del método debe ser similar a la siguiente:

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

    RANGED_LONG es un tipo definido para los códigos auxiliares de cliente y servidor, y de un tamaño especificado que el cliente puede prever correctamente. En el ejemplo, el cliente pasa ppArr como NULL y el componente de aplicación del servidor RPC asigna la cantidad correcta de memoria. Tras la devolución, el servicio RPC del lado cliente asigna la memoria de los datos devueltos.

  • Si el cliente quiere enviar un subconjunto de una matriz de gran conformidad al servidor, la aplicación puede especificar el tamaño del subconjunto como se muestra en el ejemplo siguiente:

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

    De este modo la RPC solo transmitirá los elementos lLength de la matriz a través de la conexión. Sin embargo, esta definición fuerza al servicio RPC a asignar memoria de tamaño lSize en el lado servidor.

  • Si el componente de aplicación cliente determina el tamaño máximo de una matriz que el servidor puede devolver, pero permite que el servidor transmita un subconjunto de esa matriz, la aplicación puede especificar este comportamiento definiendo el IDL similar al ejemplo siguiente:

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

    El componente de aplicación cliente especifica el tamaño máximo de la matriz y el servidor especifica cuántos elementos transmite de vuelta al cliente.

  • Si el componente de aplicación del servidor debe devolver una cadena al componente de aplicación cliente y, si el cliente conoce el tamaño máximo que se va a devolver desde el servidor, la aplicación puede usar un tipo de cadena conforme como se muestra en el ejemplo siguiente:

    outStringKnownSize
    (
    [in,range(MIN_COUNT, MAX_STRING)] long lSize,
    [out,size_is(lSize),string] wchar_t *pString
    );
    
  • Si el componente de aplicación cliente no debe controlar el tamaño de la cadena, el servicio RPC puede asignar específicamente la memoria como se muestra en el ejemplo siguiente:

    outStringUnknownSize
    (
    [out] LPWSTR *ppStr
    );
    

    El componente de aplicación cliente debe establecer ppStr en NULL al llamar al método RPC.