IDL-technieken voor betere interface- en methodeontwerp
Overweeg het gebruik van de volgende IDL-specifieke technieken om de beveiliging en prestaties te verbeteren wanneer u RPC-interfaces en -methoden ontwikkelt die zowel conforme als variantgegevens verwerken. De kenmerken waarnaar in dit onderwerp wordt verwezen, zijn de IDL-kenmerken die zijn ingesteld op methodeparameters die conforme gegevens verwerken (bijvoorbeeld de kenmerken [size_is] en [max_is] ) of variantgegevens (bijvoorbeeld de kenmerken [length_is] en [tekenreeks]).
Het kenmerk [bereik] gebruiken met conforme gegevensparameters
Het kenmerk [bereik] geeft de RPC-runtime opdracht om extra groottevalidatie uit te voeren tijdens het proces voor het niet-weergeven van gegevens. Met name wordt gecontroleerd of de opgegeven grootte van de gegevens die zijn doorgegeven als de bijbehorende parameter binnen het opgegeven bereik valt.
Het kenmerk [bereik] heeft geen invloed op de draadindeling.
Als de waarde op draad buiten het toegestane bereik valt, genereert RPC een RPC_X_INVALID_BOUND of RPC_X_BAD_STUB_DATA uitzondering. Dit biedt een extra niveau van gegevensvalidatie en kan helpen veelvoorkomende beveiligingsfouten te voorkomen, zoals bufferoverschrijdingen. Op dezelfde manier kan het gebruik van [bereik] de prestaties van de toepassing verbeteren, omdat conforme gegevens die met het bereik zijn gemarkeerd, duidelijk gedefinieerde beperkingen hebben die beschikbaar zijn voor overweging door de RPC-service.
Regels voor RPC-server-stubgeheugenbeheer
Het is belangrijk om inzicht te hebben in regels voor geheugenbeheer van de RPC-server bij het maken van de IDL-bestanden voor een toepassing met RPC-functionaliteit. Toepassingen kunnen het gebruik van serverresources verbeteren met behulp van [bereik] in combinatie met conforme gegevens zoals hierboven aangegeven, en het opzettelijk vermijden van de toepassing van idL-kenmerken van variabele lengte, zoals [length_is] om te voldoen aan gegevens.
De toepassing van [length_is] op gegevensstructuurvelden die zijn gedefinieerd in een IDL-bestand wordt niet aanbevolen.
Aanbevolen procedures voor gegevensparameters met variabele lengte
Hier volgen enkele aanbevolen procedures om rekening mee te houden bij het definiëren van de IDL-kenmerken voor gegevensstructuren van variabele grootte, methodeparameters en velden.
Gebruik een vroege correlatie. Over het algemeen is het beter om de parameter of het veld voor variabelegrootte te definiëren, zodat deze direct na het besturingsintegraaltype plaatsvindt.
Bijvoorbeeld
earlyCorr ( [in, range(MIN_COUNT, MAX_COUNT)] long size, [in,size_is(size)] char *pv );
is beter dan
lateCorr ( [in,size_is(size)] char *pv, [in, range(MIN_COUNT, MAX_COUNT)] long size) );
waarbij earlyCorr de grootteparameter onmiddellijk vóór de parameter voor de gegevensparameter variabelelengte declareert en lateCorr de parameter grootte erna declareert. Het gebruik van vroege correspondentie verbetert de prestaties in het algemeen, met name in gevallen waarin de methode vaak wordt aangeroepen.
Voor parameters die zijn gemarkeerd met de [out, size_is] kenmerk tuple en waar de gegevenslengte aan de clientzijde bekend is of waar de client een redelijke bovengrens heeft, moet de methodedefinitie vergelijkbaar zijn met het volgende in termen van parametertoewijzing en -volgorde:
outKnownSize ( [in,range(MIN_COUNT, MAX_COUNT)] long lSize, [out,size_is(lSize)] UserDataType * pArr );
In dit geval biedt de client een buffer met een vaste grootte voor pArr-, waardoor de RPC-service aan de serverzijde een buffer met een redelijke mate van zekerheid kan toewijzen. Houd er rekening mee dat in het voorbeeld de gegevens van de server worden ontvangen ([]). De definitie is vergelijkbaar voor gegevens die worden doorgegeven aan de server ([in]).
In situaties waarin het onderdeel aan de serverzijde van een RPC-toepassing de gegevenslengte bepaalt, moet de methodedefinitie er ongeveer als volgt uitzien:
typedef [range(MIN_COUNT,MAX_COUNT)] long RANGED_LONG; outUnknownSize ( [out] RANGED_LONG *pSize, [out,size_is(,*pSize)] UserDataType **ppArr );
RANGED_LONG is een type dat is gedefinieerd voor zowel de client- als server-stubs, en voor een opgegeven grootte die de client correct kan verwachten. In het voorbeeld geeft de client ppArr- door als NULL-en wijst het RPC-servertoepassingsonderdeel de juiste hoeveelheid geheugen toe. Bij terugkeer wijst de RPC-service aan de clientzijde het geheugen toe voor de geretourneerde gegevens.
Als de client een subset van een grote conforme matrix naar de server wil verzenden, kan de toepassing de grootte van de subset opgeven, zoals wordt weergegeven in het volgende voorbeeld:
inConformantVaryingArray ( [in,range(MIN_COUNT,MAX_COUNT)] long lSize, [in] long lLength, [in,size_is(lSize), length_is(lLength)] UserDataType *pArr );
Op deze manier verzendt RPC alleen lLength elementen van de matrix over de draad. Deze definitie dwingt echter af dat de RPC-service geheugen van grootte toewijst lSize- aan de serverzijde.
Als het clienttoepassingsonderdeel de maximale grootte van een matrix bepaalt die de server kan retourneren, maar de server toestaat een subset van die matrix te verzenden, kan de toepassing een dergelijk gedrag opgeven door de IDL te definiëren die vergelijkbaar is met het volgende voorbeeld:
inMaxSizeOutLength ( [in, range(MIN_COUNT, MAX_COUNT)] long lSize, [out] long *pLength, [out,size_is(lSize), length_is(*pLength)] UserDataType *pArr );
Het clienttoepassingsonderdeel geeft de maximale grootte van de matrix aan en de server geeft aan hoeveel elementen deze naar de client verzendt.
Als het servertoepassingsonderdeel een tekenreeks moet retourneren aan het clienttoepassingsonderdeel en als de client weet dat de maximale grootte moet worden geretourneerd van de server, kan de toepassing een conform tekenreekstype gebruiken, zoals wordt weergegeven in het volgende voorbeeld:
outStringKnownSize ( [in,range(MIN_COUNT, MAX_STRING)] long lSize, [out,size_is(lSize),string] wchar_t *pString );
Als het clienttoepassingsonderdeel de grootte van de tekenreeks niet mag beheren, kan de RPC-service specifiek het geheugen toewijzen, zoals wordt gedemonstreerd in het volgende voorbeeld:
outStringUnknownSize ( [out] LPWSTR *ppStr );
Het clienttoepassingsonderdeel moet ppStr- instellen op NULL- bij het aanroepen van de RPC-methode.