├── .build ├── CBT │ ├── CBT.Core.dll │ └── build.props └── Local │ └── CBTModules │ └── CBTModules.proj ├── .gitignore ├── Directory.Build.props ├── LICENSE.txt ├── NuGet.Config ├── README.md ├── SECURITY.md ├── dirs.proj ├── docs ├── IND2Adapter.md ├── IND2CompletionQueue.md ├── IND2Connector.md ├── IND2Listener.md ├── IND2MemoryRegion.md ├── IND2MemoryWindow.md ├── IND2Overlapped.md ├── IND2Provider.md ├── IND2QueuePair.md ├── IND2SharedReceiveQueue.md ├── NetworkDirectSPI.md └── cq.png └── src ├── dirs.proj ├── examples ├── bldver.rc ├── dirs.proj ├── examples.props ├── logging.h ├── ndadapterinfo │ ├── NuGetAssetsLock.props │ ├── ndadapterinfo.cpp │ ├── ndadapterinfo.rc │ └── ndadapterinfo.vcxproj ├── ndcat │ ├── NuGetAssetsLock.props │ ├── ndcat.cpp │ ├── ndcat.rc │ └── ndcat.vcxproj ├── ndcommon.h ├── ndmrlat │ ├── NuGetAssetsLock.props │ ├── ndmrlat.cpp │ ├── ndmrlat.rc │ └── ndmrlat.vcxproj ├── ndmrrate │ ├── NuGetAssetsLock.props │ ├── ndmrrate.cpp │ ├── ndmrrate.rc │ └── ndmrrate.vcxproj ├── ndping │ ├── NuGetAssetsLock.props │ ├── ndping.cpp │ ├── ndping.rc │ └── ndping.vcxproj ├── ndpingpong │ ├── NuGetAssetsLock.props │ ├── ndpingpong.cpp │ ├── ndpingpong.rc │ └── ndpingpong.vcxproj ├── ndrping │ ├── NuGetAssetsLock.props │ ├── ndrping.cpp │ ├── ndrping.rc │ └── ndrping.vcxproj ├── ndrpingpong │ ├── NuGetAssetsLock.props │ ├── ndrpingpong.cpp │ ├── ndrpingpong.rc │ └── ndrpingpong.vcxproj ├── ndsupport.h └── ndtestutil │ ├── NuGetAssetsLock.props │ ├── ndtestutil.cpp │ ├── ndtestutil.h │ └── ndtestutil.vcxproj ├── ndutil ├── NuGetAssetsLock.props ├── assertutil.h ├── list.h ├── ndaddr.cpp ├── ndaddr.h ├── nddef.h ├── ndfrmwrk.cpp ├── ndfrmwrk.h ├── ndioctl.h ├── ndprov.cpp ├── ndprov.h ├── ndspi.h ├── ndstatus.mc ├── ndsupport.h ├── ndutil.h ├── ndutil.vcxproj └── precomp.h ├── netdirect.sln ├── src.props └── unittests ├── dirs.proj ├── ndconn ├── NuGetAssetsLock.props ├── ndconn.cpp ├── ndconn.h ├── ndconn.rc └── ndconn.vcxproj ├── ndcq ├── NuGetAssetsLock.props ├── ndcq.cpp ├── ndcq.rc └── ndcq.vcxproj ├── ndmemorytest ├── NuGetAssetsLock.props ├── ndconnectlistenerclosing.cpp ├── ndconnrejectclose.cpp ├── nddualconnection.cpp ├── ndduallisten.cpp ├── ndinvalidip.cpp ├── ndinvalidreadwrite.cpp ├── ndlargeprivatedata.cpp ├── ndlargeqpdepth.cpp ├── ndmemorytest.cpp ├── ndmemorytest.h ├── ndmemorytest.vcxproj ├── ndmrderegister.cpp ├── ndmrinvalidbuffer.cpp ├── ndoverreadwrite.cpp ├── ndqpmaxall.cpp ├── ndreceiveconnectorclosed.cpp ├── ndreceiveflushqp.cpp ├── ndsendnoreceive.cpp └── ndwriteviolation.cpp ├── ndmpic ├── NuGetAssetsLock.props ├── ndmpic.cpp ├── ndmpic.rc └── ndmpic.vcxproj ├── ndmval ├── NuGetAssetsLock.props ├── ndmval.cpp ├── ndmval.rc └── ndmval.vcxproj ├── ndmw ├── NuGetAssetsLock.props ├── ndmw.cpp ├── ndmw.rc └── ndmw.vcxproj └── unittests.props /.build/CBT/CBT.Core.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/NetworkDirect/043f1bf05e41343cc88dda619ddd86aee60a02fe/.build/CBT/CBT.Core.dll -------------------------------------------------------------------------------- /.build/Local/CBTModules/CBTModules.proj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net46 5 | 6 | 22 | 23 | 24 | 31 | 32 | 33 | 40 | 41 | 42 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015/2017 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # Visual Studio 2017 auto generated files 33 | Generated\ Files/ 34 | 35 | # MSTest test Results 36 | [Tt]est[Rr]esult*/ 37 | [Bb]uild[Ll]og.* 38 | 39 | # NUNIT 40 | *.VisualState.xml 41 | TestResult.xml 42 | 43 | # Build Results of an ATL Project 44 | [Dd]ebugPS/ 45 | [Rr]eleasePS/ 46 | dlldata.c 47 | 48 | # Benchmark Results 49 | BenchmarkDotNet.Artifacts/ 50 | 51 | # .NET Core 52 | project.lock.json 53 | project.fragment.lock.json 54 | artifacts/ 55 | **/Properties/launchSettings.json 56 | 57 | # StyleCop 58 | StyleCopReport.xml 59 | 60 | # Files built by Visual Studio 61 | *_i.c 62 | *_p.c 63 | *_i.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.iobj 68 | *.pch 69 | *.pdb 70 | *.ipdb 71 | *.pgc 72 | *.pgd 73 | *.rsp 74 | *.sbr 75 | *.tlb 76 | *.tli 77 | *.tlh 78 | *.tmp 79 | *.tmp_proj 80 | *.log 81 | *.vspscc 82 | *.vssscc 83 | .builds 84 | *.pidb 85 | *.svclog 86 | *.scc 87 | 88 | # Chutzpah Test files 89 | _Chutzpah* 90 | 91 | # Visual C++ cache files 92 | ipch/ 93 | *.aps 94 | *.ncb 95 | *.opendb 96 | *.opensdf 97 | *.sdf 98 | *.cachefile 99 | *.VC.db 100 | *.VC.VC.opendb 101 | 102 | # Visual Studio profiler 103 | *.psess 104 | *.vsp 105 | *.vspx 106 | *.sap 107 | 108 | # Visual Studio Trace Files 109 | *.e2e 110 | 111 | # TFS 2012 Local Workspace 112 | $tf/ 113 | 114 | # Guidance Automation Toolkit 115 | *.gpState 116 | 117 | # ReSharper is a .NET coding add-in 118 | _ReSharper*/ 119 | *.[Rr]e[Ss]harper 120 | *.DotSettings.user 121 | 122 | # JustCode is a .NET coding add-in 123 | .JustCode 124 | 125 | # TeamCity is a build add-in 126 | _TeamCity* 127 | 128 | # DotCover is a Code Coverage Tool 129 | *.dotCover 130 | 131 | # AxoCover is a Code Coverage Tool 132 | .axoCover/* 133 | !.axoCover/settings.json 134 | 135 | # Visual Studio code coverage results 136 | *.coverage 137 | *.coveragexml 138 | 139 | # NCrunch 140 | _NCrunch_* 141 | .*crunch*.local.xml 142 | nCrunchTemp_* 143 | 144 | # MightyMoose 145 | *.mm.* 146 | AutoTest.Net/ 147 | 148 | # Web workbench (sass) 149 | .sass-cache/ 150 | 151 | # Installshield output folder 152 | [Ee]xpress/ 153 | 154 | # DocProject is a documentation generator add-in 155 | DocProject/buildhelp/ 156 | DocProject/Help/*.HxT 157 | DocProject/Help/*.HxC 158 | DocProject/Help/*.hhc 159 | DocProject/Help/*.hhk 160 | DocProject/Help/*.hhp 161 | DocProject/Help/Html2 162 | DocProject/Help/html 163 | 164 | # Click-Once directory 165 | publish/ 166 | 167 | # Publish Web Output 168 | *.[Pp]ublish.xml 169 | *.azurePubxml 170 | # Note: Comment the next line if you want to checkin your web deploy settings, 171 | # but database connection strings (with potential passwords) will be unencrypted 172 | *.pubxml 173 | *.publishproj 174 | 175 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 176 | # checkin your Azure Web App publish settings, but sensitive information contained 177 | # in these scripts will be unencrypted 178 | PublishScripts/ 179 | 180 | # NuGet Packages 181 | *.nupkg 182 | # The packages folder can be ignored because of Package Restore 183 | **/[Pp]ackages/* 184 | # except build/, which is used as an MSBuild target. 185 | !**/[Pp]ackages/build/ 186 | # Uncomment if necessary however generally it will be regenerated when needed 187 | #!**/[Pp]ackages/repositories.config 188 | # NuGet v3's project.json files produces more ignorable files 189 | *.nuget.props 190 | *.nuget.targets 191 | 192 | # Microsoft Azure Build Output 193 | csx/ 194 | *.build.csdef 195 | 196 | # Microsoft Azure Emulator 197 | ecf/ 198 | rcf/ 199 | 200 | # Windows Store app package directories and files 201 | AppPackages/ 202 | BundleArtifacts/ 203 | Package.StoreAssociation.xml 204 | _pkginfo.txt 205 | *.appx 206 | 207 | # Visual Studio cache files 208 | # files ending in .cache can be ignored 209 | *.[Cc]ache 210 | # but keep track of directories ending in .cache 211 | !*.[Cc]ache/ 212 | 213 | # Others 214 | ClientBin/ 215 | ~$* 216 | *~ 217 | *.dbmdl 218 | *.dbproj.schemaview 219 | *.jfm 220 | *.pfx 221 | *.publishsettings 222 | orleans.codegen.cs 223 | 224 | # Including strong name files can present a security risk 225 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 226 | #*.snk 227 | 228 | # Since there are multiple workflows, uncomment next line to ignore bower_components 229 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 230 | #bower_components/ 231 | 232 | # RIA/Silverlight projects 233 | Generated_Code/ 234 | 235 | # Backup & report files from converting an old project file 236 | # to a newer Visual Studio version. Backup files are not needed, 237 | # because we have git ;-) 238 | _UpgradeReport_Files/ 239 | Backup*/ 240 | UpgradeLog*.XML 241 | UpgradeLog*.htm 242 | ServiceFabricBackup/ 243 | *.rptproj.bak 244 | 245 | # SQL Server files 246 | *.mdf 247 | *.ldf 248 | *.ndf 249 | 250 | # Business Intelligence projects 251 | *.rdl.data 252 | *.bim.layout 253 | *.bim_*.settings 254 | *.rptproj.rsuser 255 | 256 | # Microsoft Fakes 257 | FakesAssemblies/ 258 | 259 | # GhostDoc plugin setting file 260 | *.GhostDoc.xml 261 | 262 | # Node.js Tools for Visual Studio 263 | .ntvs_analysis.dat 264 | node_modules/ 265 | 266 | # Visual Studio 6 build log 267 | *.plg 268 | 269 | # Visual Studio 6 workspace options file 270 | *.opt 271 | 272 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 273 | *.vbw 274 | 275 | # Visual Studio LightSwitch build output 276 | **/*.HTMLClient/GeneratedArtifacts 277 | **/*.DesktopClient/GeneratedArtifacts 278 | **/*.DesktopClient/ModelManifest.xml 279 | **/*.Server/GeneratedArtifacts 280 | **/*.Server/ModelManifest.xml 281 | _Pvt_Extensions 282 | 283 | # Paket dependency manager 284 | .paket/paket.exe 285 | paket-files/ 286 | 287 | # FAKE - F# Make 288 | .fake/ 289 | 290 | # JetBrains Rider 291 | .idea/ 292 | *.sln.iml 293 | 294 | # CodeRush 295 | .cr/ 296 | 297 | # Python Tools for Visual Studio (PTVS) 298 | __pycache__/ 299 | *.pyc 300 | 301 | # Cake - Uncomment if you are using it 302 | # tools/** 303 | # !tools/packages.config 304 | 305 | # Tabs Studio 306 | *.tss 307 | 308 | # Telerik's JustMock configuration file 309 | *.jmconfig 310 | 311 | # BizTalk build output 312 | *.btp.cs 313 | *.btm.cs 314 | *.odx.cs 315 | *.xsd.cs 316 | 317 | # OpenCover UI analysis results 318 | OpenCover/ 319 | 320 | # Azure Stream Analytics local run output 321 | ASALocalRun/ 322 | 323 | # MSBuild Binary and Structured Log 324 | *.binlog 325 | 326 | # NVidia Nsight GPU debugger configuration file 327 | *.nvuser 328 | 329 | # MFractors (Xamarin productivity tool) working folder 330 | .mfractor/ 331 | -------------------------------------------------------------------------------- /Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 12 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 13 | 14 | 17 | $(MSBuildThisFileDirectory.TrimEnd('\\')) 18 | $(EnlistmentRoot)\packages 19 | 20 | 23 | 24 | 28 | 29 | 30 | 33 | 34 | 35 | 36 | CustomDictionary.xml 37 | 38 | 39 | 40 | False 41 | true 42 | 300 43 | false 44 | false 45 | 46 | 47 | 50 | 51 | true 52 | 53 | 54 | 59 | 60 | 61 | 64 | 65 | $(MSBuildExtensionsPath)\NuProj 66 | $(CBTModule_NuProj)\tools 67 | 68 | false 69 | 70 | 71 | 72 | 73 | $(EnlistmentRoot)\out\$(Configuration)-$(Platform)\ 74 | 75 | 76 | 77 | $(StagingOutputRootPath)$(MSBuildProjectName)\ 78 | $(StagingOutputRootPath)include 79 | 14.15.26726 80 | 10.0.16299.0 81 | v141 82 | Unicode 83 | $(OutputPath) 84 | false 85 | 86 | 87 | 88 | true 89 | true 90 | 91 | 92 | 93 | false 94 | false 95 | true 96 | 97 | 98 | 99 | 100 | Level3 101 | true 102 | true 103 | ProgramDatabase 104 | 26439 105 | 106 | 107 | ;%(AdditionalDependencies) 108 | Windows 109 | 110 | 111 | 112 | 113 | 114 | Disabled 115 | _DEBUG;%(PreprocessorDefinitions) 116 | MultiThreadedDebug 117 | true 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | MaxSpeed 126 | NDEBUG;%(PreprocessorDefinitions) 127 | MultiThreaded 128 | true 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | WIN32;%(PreprocessorDefinitions) 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. All rights reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NetworkDirect SPI 2 | 3 | The NetworkDirect architecture provides application developers with a networking interface that enables zero-copy data transfers between applications, kernel-bypass I/O generation and completion processing, and one-sided data transfer operations. The NetworkDirect service provider interface (SPI) defines the interface that NetworkDirect providers implement to expose their hardware capabilities to applications. 4 | 5 | Please find additional documentation in [docs/](./docs) folder. 6 | 7 | NetworkDirect SDK is available in [Nuget](https://www.nuget.org/packages/networkdirect) also. 8 | 9 | # Building 10 | 11 | ## Prerequisites 12 | 13 | - [Visial Studio 2017](https://docs.microsoft.com/visualstudio/install/install-visual-studio) 14 | 15 | Please make sure to select the following workloads during installation: 16 | - .NET desktop development (required for CBT/Nuget packages) 17 | - Desktop development with C++ 18 | 19 | - [Windows SDK](https://developer.microsoft.com/windows/downloads/windows-10-sdk) 20 | - [Windows WDK](https://docs.microsoft.com/windows-hardware/drivers/download-the-wdk) 21 | 22 | Based on the installed VS/SDK/WDK versions, update _VCToolsVersion_ and _WindowsTargetPlatformVersion_ in Directory.Build.props 23 | 24 | Note that the build system uses [CommonBuildToolSet(CBT)](https://commonbuildtoolset.github.io/). You may need to unblock __CBT.core.dll__ (under .build/CBT) depending on your security configurations. Please refer to [CBT documentation](https://commonbuildtoolset.github.io/#/getting-started) for additional details. 25 | 26 | 27 | ## Build 28 | To build, open a __Native Tools Command Prompt for Visual Studio__ and run ``msbuild`` from root folder. 29 | 30 | # Contributing 31 | 32 | This project welcomes contributions and suggestions. Most contributions require you to agree to a 33 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 34 | the rights to use your contribution. For details, visit https://cla.microsoft.com. 35 | 36 | When you submit a pull request, a CLA-bot will automatically determine whether you need to provide 37 | a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions 38 | provided by the bot. You will only need to do this once across all repos using our CLA. 39 | 40 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 41 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 42 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 43 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /dirs.proj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /docs/IND2Listener.md: -------------------------------------------------------------------------------- 1 | # IND2Listener interface 2 | Use to listen for connection requests from peers. The [IND2Adapter::CreateListener](./IND2Adapter.md#ind2adaptercreatelistener) method returns this interface. 3 | 4 | The IND2Listener interface inherits from [IND2Overlapped](./IND2Overlapped.md). In addition, IND2Listener defines the following methods. 5 | 6 | - [__Bind__](#ind2listenerbind) - Binds listener object to a local address. 7 | - [__Listen__](#ind2listenerlisten) - Starts listening for incoming connection requests. 8 | - [__GetLocalAddress__](#ind2listenergetlocaladdress) - Retrieves the address of the listen object. 9 | - [__GetConnectionRequest__](#ind2listenergetconnectionrequest) - Retrieves the handle for a pending connection request. 10 | 11 | __Remarks:__ 12 | 13 | NetworkDirect uses an active/passive model for establishing a connection between peers; the passive side listens for connection requests from the active side. 14 | 15 | The active side makes the following calls: 16 | 1. Receive (can occur before or after Connect) 17 | 2. Connect (completes after the peer calls Accept or Reject) 18 | 3. CompleteConnect 19 | 4. Send (begins the first Send/Receive exchange) 20 | 21 | The passive side makes the following calls: 22 | 1. GetConnectionRequest (receives the Connect request) 23 | 2. Receive (posts a request to Receives the first Send request) 24 | 3. Accept 25 | 26 | The iWARP specification requires that the active side always initiates a Send request to the passive side before the passive side can issue a Send request to the active side. After the connection is established, the passive side cannot issue a Send request until it has received its first message from the active side.This requires that the passive side always issues at least one Receive request, and waits for it to complete before it can begin issuing Send requests (even if it issues only Send requests after that time). 27 | 28 | Either side of a connection can terminate the connection by calling the [IND2Connector::Disconnect](./IND2Connector.md#ind2connectordisconnect) method. When a queue pair is disconnected, all requests are flushed. The completion status is ND_CANCELED for all outstanding Send and Receive requests on both sides of the connection. 29 | 30 | NetworkDirect providers should not make any assumptions about client response times to asynchronous connection establishment events, and they should make every effort to accommodate clients that experience delays in processing connection-related I/O completions. 31 | 32 | ## IND2Listener::Bind 33 | Binds Listener to a local address. 34 | ``` 35 | HRESULT Bind( 36 | [in] const struct sockaddr *pAddress, 37 | [in] ULONG cbAddress, 38 | ); 39 | ``` 40 | 41 | __Parameters:__ 42 | 43 | - __pAddress__ [in] 44 | 45 | A sockaddr buffer that specifies the local address on which to listen for connection requests. Typically, this is a sockaddr_in structure for IPv4 addresses and a sockaddr_in6 structure for IPv6 addresses. 46 | 47 | If the sin_port or sin6_port member is specified as zero, the provider assigns a unique port number to the application. If the sin_addr or sin6_addr is INADDR_ANY or IN6ADDR_ANY the listen object can be multi-homed if the NetworkDirect adapter supports multiple IP addresses, but it cannot span multiple NetworkDirect adapters. 48 | 49 | - __cbAddress__ [in] 50 | 51 | Size, in bytes, of the pAddress buffer. 52 | 53 | __Return Value:__ 54 | 55 | When you implement this method, you should return the following return values. If you return others, try to use well-known values to aid in debugging issues. 56 | 57 | - __ND_SUCCESS__ - The operation completed successfully. 58 | - __ND_SHARING_VIOLATION__ - The specified address is already in use on this NetworkDirect adapter. 59 | - __ND_INSUFFICIENT_RESOURCES__ - There were not enough resources to complete the request. 60 | - __ND_TOO_MANY_ADDRESSES__ - The client specified a local port number of zero, and the NetworkDirect provider was unable to allocate a port from the ephemeral port space (ports 49152-65535.) 61 | 62 | 63 | ## IND2Listener::Listen 64 | Starts listening for incoming connection requests. 65 | ``` 66 | HRESULT Listen( 67 | [in] ULONG Backlog 68 | ); 69 | ``` 70 | 71 | __Parameters:__ 72 | 73 | - __Backlog__ [in] 74 | 75 | The maximum number of pending connection requests to maintain for the listen request. Set to zero to indicate no limit. 76 | 77 | __Return Value:__ 78 | 79 | When you implement this method, you should return the following return values. If you return others, try to use well-known values to aid in debugging issues. 80 | 81 | - __ND_SUCCESS__ - The operation completed successfully. 82 | - __ND_INSUFFICIENT_RESOURCES__ - There were not enough resources to complete the request. 83 | 84 | __Implementation Notes:__ 85 | 86 | NetworkDirect service providers may restrict the range of the backlog and silently apply limits. There is no provision for retrieving the actual backlog value. 87 | 88 | __Remarks:__ 89 | 90 | The server side of a client-server application listens for connection requests from the client side. 91 | 92 | ## IND2Listener::GetLocalAddress 93 | Retrieves the listen object's address, which includes the adapter address and port number. To succeed, the listen object must be listening. 94 | ``` 95 | HRESULT GetLocalAddress( 96 | [out, optional] struct sockaddr *pAddress, 97 | [in, out] ULONG *pcbAddress 98 | ); 99 | ``` 100 | 101 | __Parameters:__ 102 | 103 | - __pAddress__ [out, optional] 104 | 105 | A sockaddr buffer that will receive the local address. May be nullptr if pcbAddress is zero. 106 | 107 | - __pcbAddress__ [in, out] 108 | 109 | The size, in bytes, of the pAddress buffer. If the buffer is too small, the method fails with ND_BUFFER_OVERFLOW and sets this parameter to the required buffer size. If the buffer is too big, the method sets this parameter to the size that is used on output. 110 | 111 | __Return Value:__ 112 | 113 | When you implement this method, you should return the following return values. If you return others, try to use well-known values to aid in debugging issues. 114 | 115 | - __ND_SUCCESS__ - The operation succeeded. 116 | - __ND_BUFFER_OVERFLOW__ - The pAddress buffer is not large enough to hold the address, and the buffer was not modified. The pcbAddress parameter is updated with the required buffer size. 117 | - __ND_INVALID_DEVICE_STATE__ - The listen object is not listening. 118 | 119 | ## IND2Listener::GetConnectionRequest 120 | Retrieves the handle for a pending connection request. 121 | 122 | ``` 123 | HRESULT GetConnectionRequest( 124 | [in, out] IUnknown *pConnector, 125 | [in, out] OVERLAPPED *pOverlapped 126 | ); 127 | ``` 128 | 129 | __Parameters:__ 130 | 131 | - __pConnector__ [in, out] 132 | 133 | An interface to the connector request that is returned by a previous call to [IND2Adapter::CreateConnector](./IND2Adapter.md#ind2adaptercreateconnector). 134 | 135 | - __pOverlapped__ [in, out] 136 | 137 | A pointer to an [OVERLAPPED](https://docs.microsoft.com/windows/desktop/api/minwinbase/ns-minwinbase-_overlapped) structure that is used to indicate completion of the operation. 138 | 139 | __Return Value:__ 140 | 141 | When you implement this method, you should return the following return values. If you return others, try to use well-known values to aid in debugging issues. 142 | 143 | - __ND_SUCCESS__ - The operation succeeded. 144 | - __ND_PENDING__ - The request is pending, and it will be completed when the listening peer accepts the connection request. 145 | - __ND_CANCELED__ - The listen request was closed. 146 | - __ND_DEVICE_REMOVED__ - The underlying NetworkDirect adapter was removed from the system. 147 | 148 | __Remarks:__ 149 | 150 | You can issue multiple GetConnectionRequest requests to prepare for future connection requests. The overlapped requests complete one at a time for each connection request that is received. You detect completion of the overlapped request like you do for any other overlapped operation (for more information, see the Remarks for [IND2Adapter::CreateOverlappedFile](./IND2Adapter.md#ind2adaptercreateoverlappedfile)). 151 | -------------------------------------------------------------------------------- /docs/IND2MemoryRegion.md: -------------------------------------------------------------------------------- 1 | # IND2MemoryRegion interface 2 | Use to make application buffers accessible to the NetworkDirect adapter, which will use them in I/O operations. 3 | 4 | Note that only one memory buffer can be registered to a memory region object. The user should be able to register the same memory buffer multiple times, even for different access rights. However, one can not register two different memory buffers to the same memory region. 5 | 6 | The IND2MemoryRegion interface inherits from [IND2Overlapped](./IND2Overlapped.md). 7 | In addition, IND2MemoryRegion defines the following methods. 8 | 9 | - [__Register__](#ind2memoryregionregister) - Registers an application-defined buffer. 10 | 11 | - [__Deregister__](#ind2memoryregionderegister) - Deregisters a previously registered application-defined buffer. 12 | 13 | - [__GetLocalToken__](#ind2memoryregiongetlocaltoken) - Retrieves the local token for the memory region, used in [ND2_SGE](./IND2QueuePair.md#nd2_sge-structure) structures as part of I/O requests. 14 | - [__GetRemoteToken__](#ind2memoryregiongetremotetoken) - Retrieves the remote token that allows remote access to the memory region. It is used by the connected QueuePair in Read and Write requests. 15 | 16 | __Remarks:__ 17 | 18 | Memory registrations are fundamental to data transfer operations with NetworkDirect adapters. Memory registrations map application buffers to a NetworkDirect adapter and provide the NetworkDirect adapter the ability to access application buffers directly without operating system involvement. 19 | 20 | Memory registration is typically an expensive operation and the NetworkDirect SPI allows all memory registration and deregistration operations to be processed asynchronously in order to parallelize application processing with registration. Because memory region operations can be asynchronous, there is no opportunity for post-processing by the user-mode NetworkDirect provider libraries that support NetworkDirect adapters. 21 | 22 | ## IND2MemoryRegion::Register 23 | Registers an application-defined buffer that is used for Send, Receive, Read, and Write requests. 24 | ``` 25 | HRESULT Register( 26 | [in] const void *pBuffer, 27 | [in] SIZE_T cbBuffer, 28 | [in] ULONG flags, 29 | [in, out] OVERLAPPED *pOverlapped 30 | ); 31 | ``` 32 | 33 | __Parameters:__ 34 | 35 | - __pBuffer__ [in] 36 | 37 | The application-defined buffer to register. 38 | 39 | - __cbBuffer__ [in] 40 | 41 | The size, in bytes, of the application-defined buffer. 42 | 43 | - __flags__ [in] 44 | 45 | The following flags control the behavior of the Register request. You can specify one or more of the following flags: 46 | 47 | - __ND_MR_FLAG_ALLOW_LOCAL_WRITE__ 48 | 49 | Allow the adapter Write access to the memory region. 50 | 51 | - __ND_MR_FLAG_ALLOW_REMOTE_READ__ 52 | 53 | Enable Read access to the memory region by any connected peer. 54 | 55 | - __ND_MR_FLAG_ALLOW_REMOTE_WRITE__ 56 | 57 | Enable write access to the memory region by any connected peer. 58 | 59 | - __ND_MR_FLAG_RDMA_READ_SINK__ 60 | 61 | Enable access to the memory region to be used as a sink for RDMA read operation. 62 | 63 | - __ND_MR_FLAG_DO_NOT_SECURE_VM__ 64 | 65 | Instructs the provider to not secure the virtual memory range by calling the [MmSecureVirtualMemory](https://docs.microsoft.com/windows-hardware/drivers/ddi/content/ntddk/nf-ntddk-mmsecurevirtualmemory) function. Applications that are using [AWE memory management](https://docs.microsoft.com/windows/desktop/memory/address-windowing-extensions) functions must specify this flag to register AWE memory. Securing memory is only required when implementing a cache of memory registrations. Memory registrations that are not going to be cached (where the lifetime of the memory region is always less than the lifetime of the buffer) do not need to be secured. 66 | 67 | - __pOverlapped__ [in, out] 68 | 69 | A pointer to an [OVERLAPPED](https://docs.microsoft.com/windows/desktop/api/minwinbase/ns-minwinbase-_overlapped) structure that must remain valid for the duration of the operation. 70 | 71 | __Return Value:__ 72 | 73 | When you implement this method, you should return the following return values. If you return others, try to use well-known values to aid in debugging issues. 74 | 75 | - __ND_SUCCESS__ - The operation completed successfully. 76 | - __ND_PENDING__ - The NetworkDirect adapter is in process of registering the memory. Completion is reported asynchronously. 77 | - __ND_INSUFFICIENT_RESOURCES__ - There were not enough hardware resources to register the memory. 78 | - __ND_ACCESS_VIOLATION__ - The specified buffer or buffer size was not valid. 79 | - __ND_DEVICE_REMOVED__ - The underlying NetworkDirect adapter was removed from the system. Only cleanup operations on the NetworkDirect adapter will succeed. 80 | - __ND_INVALID_PARAMETER__ - The buffer exceeds the size supported by the adapter. For details, see the MaxRegistrationSize member of the [ND2_ADAPTER_INFO](./IND2Adapter.md#nd2_adapter_info-structure) structure. 81 | 82 | 83 | __Remarks:__ 84 | 85 | The MaxRegistrationSize member of the [ND2_ADAPTER_INFO](./IND2Adapter.md#nd2_adapter_info-structure) structure contains the maximum application-defined buffer size that can be registered with the adapter. To get the adapter information, call the [IND2Adapter::Query](./IND2Adapter.md#ind2adapterquery) method. 86 | 87 | You can allocate and register your memory before connecting, or you can start the connection process and then register the memory before calling [IND2Connector::Accept](./IND2Connector.md#ind2connectoraccept) or [IND2Connector::CompleteConnect](./IND2Connector.md#ind2connectorcompleteconnect). 88 | 89 | The registered memory's scope is the adapter object. It can be used on any objects within the adapter, for example, multiple queue pairs can both use the registered memory. 90 | 91 | ## IND2MemoryRegion::Deregister 92 | Removes the memory registration for an application-defined buffer. 93 | ``` 94 | HRESULT Deregister ( 95 | [in] OVERLAPPED *pOverlapped 96 | ); 97 | ``` 98 | 99 | __Parameters:__ 100 | 101 | - __pOverlapped__ [in] 102 | 103 | A pointer to an [OVERLAPPED](https://docs.microsoft.com/windows/desktop/api/minwinbase/ns-minwinbase-_overlapped) structure that must remain valid for the duration of the operation. 104 | 105 | 106 | __Return Value:__ 107 | 108 | When you implement this method, you should return the following return values. If you return others, try to use well-known values to aid in debugging issues. 109 | 110 | - __ND_SUCCESS__ - The operation completed successfully. 111 | - __ND_PENDING__ - The memory region is in the process of being freed. Completion will be reported asynchronously. 112 | - __ND_DEVICE_BUSY__ - The memory region still has memory windows bound to it. 113 | 114 | __Remarks:__ 115 | 116 | It is very important that Deregister is called before the memory region is released, otherwise the registered memory buffer will stay locked and count against your process. 117 | 118 | ## IND2MemoryRegion::GetLocalToken 119 | Gets the local memory token to allow the region to be referenced in [ND2_SGE](./IND2QueuePair.md#nd2_sge-structure) structures that are passed to Send, Receive, Read, and Write requests. 120 | 121 | ``` 122 | UINT32 GetLocalToken(); 123 | ``` 124 | 125 | __Return Value:__ 126 | 127 | The local token to use in [ND2_SGE](./IND2QueuePair.md#nd2_sge-structure) structures. 128 | 129 | ## IND2MemoryRegion::GetRemoteToken 130 | Gets the remote memory token to send to remote peers to enable them to perform Read or Write requests against the region. 131 | 132 | ``` 133 | UINT32 GetRemoteToken(); 134 | ``` 135 | 136 | __Return Value:__ 137 | 138 | The remote access token to send to connected peers. This value is opaque to the client. This value should be in network order to enable interoperability with other system architectures. 139 | -------------------------------------------------------------------------------- /docs/IND2MemoryWindow.md: -------------------------------------------------------------------------------- 1 | # IND2MemoryWindow interface 2 | Memory windows are used to grant a remote peer Read and/or Write access to a region of your registered memory. 3 | The [IND2Adapter::CreateMemoryWindow](./IND2Adapter.md#ind2adaptercreatememorywindow) method returns this interface. 4 | 5 | The IND2MemoryWindow interface inherits from [IUnknown interface](https://docs.microsoft.com/windows/desktop/api/unknwn/nn-unknwn-iunknown). In addition, IND2MemoryWindow defines the following methods. 6 | 7 | - [__GetRemoteToken__](#ind2memorywindowgetremotetoken) - Retrieves the remote token that allows remote access to the memory window. It can be used by the connected [QueuePair](#./IND2QueuePair.md) in Read and Write requests. 8 | 9 | __Remarks:__ 10 | 11 | The memory window is created in an invalidated state, and it is not usable until you call the [IND2QueuePair::Bind](ind2queuepairbind) method to define the size of the window and bind it to a queue pair and a memory region. 12 | 13 | A memory window can be bound only to a single queue pair. After being invalidated (unbound), the window can be bound to a different queue pair or to different memory region. The adapter that is used to create the memory window, memory region, and queue pair must be the same. 14 | 15 | Multiple windows can be bound to the same registered memory. Memory windows can overlap and have different access rights; the windows are independent. The flags parameter of the [IND2QueuePair::Bind](ind2queuepairbind) method determines the operations that the remote peer can perform on the window. 16 | 17 | Clients call the [IND2MemoryWindow::GetRemoteToken](#ind2memorywindowgetremotetoken) method to get the remote access token for a memory window after it has been bound to a queue pair. 18 | 19 | A memory window becomes invalid when the owner of the memory window calls the [IND2QueuePair::Invalidate](#ind2queuepairinvalidate) method. Memory windows can be bound and invalidated repeatedly. 20 | 21 | __Implementation notes:__ 22 | 23 | For InfiniBand devices, Type 2 memory windows should be used to implement IND2MemoryWindow support. Type 1 memory windows can be used, but they are less secure than Type 2 memory windows, and testing may expose this limitation. 24 | 25 | ## IND2MemoryWindow::GetRemoteToken 26 | Gets the remote memory token to send to remote peers to enable them to perform Read or Write requests against the window. 27 | ``` 28 | UINT32 GetRemoteToken(); 29 | ``` 30 | __Return Value:__ 31 | 32 | The remote access token to send to connected peers. This value is opaque to the client. This value should be in network order to enable interoperability with other system architectures. 33 | -------------------------------------------------------------------------------- /docs/IND2Overlapped.md: -------------------------------------------------------------------------------- 1 | # IND2Overlapped interface 2 | This interface is the base interface that is used for interfaces on which overlapped operations can be performed. 3 | 4 | The IND2Overlapped interface inherits the methods of the [IUnknown interface](https://docs.microsoft.com/windows/desktop/api/unknwn/nn-unknwn-iunknown). 5 | In addition, IND2Overlapped defines the following methods: 6 | 7 | - [__CancelOverlappedRequests__](#ind2overlappedcanceloverlappedrequests) - Cancels all in-progress overlapped requests. 8 | - [__GetOverlappedResult__](#ind2overlappedgetoverlappedresult) - Retrieves the result of an overlapped request. 9 | 10 | __Remarks:__ 11 | 12 | Many operations in the NetworkDirect SPI take an [OVERLAPPED](https://docs.microsoft.com/windows/desktop/api/minwinbase/ns-minwinbase-_overlapped) structure as input. These operations provide the same functionality as Win32 asynchronous I/O operations. For added flexibility, this class also exposes the adapter's underlying file handle on which asynchronous operations are performed. 13 | 14 | Providers never invoke callbacks into client code. All notifications are explicitly requested by the client. 15 | 16 | ## IND2Overlapped::CancelOverlappedRequests 17 | Cancels all overlapped requests that are in-progress. 18 | 19 | ``` 20 | HRESULT CancelOverlappedRequests(); 21 | ``` 22 | 23 | __Return Value:__ 24 | 25 | When you implement this method, you should return the following return values. If you return others, try to use well-known values to aid in debugging issues. 26 | 27 | - __ND_SUCCESS__ - The operation succeeded. All requests for asynchronous notifications have been completed with ND_CANCELED. Note that completions for such notification requests may not have been delivered or processed. 28 | - __ND_UNSUCCESSFUL__ - All outstanding operations could not be canceled. 29 | 30 | ## IND2Overlapped::GetOverlappedResult 31 | Retrieves the result of an overlapped request. 32 | 33 | ``` 34 | HRESULT GetOverlappedResult( 35 | [in] OVERLAPPED *pOverlapped, 36 | [in] BOOL wait 37 | ); 38 | ``` 39 | 40 | __Parameters:__ 41 | - __pOverlapped__ [in] 42 | 43 | The [OVERLAPPED](https://docs.microsoft.com/windows/desktop/api/minwinbase/ns-minwinbase-_overlapped) structure that was specified when the overlapped operation started. 44 | - __wait__ [in] 45 | 46 | If this parameter is _true_, the function does not return until the operation completes. If this parameter is _false_, and the operation is still pending, the function returns ND_PENDING. Applications that set this parameter to _true_ must have specified a valid event handle in the [OVERLAPPED](https://docs.microsoft.com/windows/desktop/api/minwinbase/ns-minwinbase-_overlapped) structure when initiating the I/O request. 47 | 48 | __Return Value:__ 49 | 50 | When you implement this method, you should return the following return values. If you return others, try to use well-known values to aid in debugging issues. 51 | 52 | - __ND_SUCCESS__ - The operation completed successfully. 53 | - __ND_PENDING__ - The operation is still outstanding and has not yet completed. 54 | - __ND_CANCELED__ - The NetworkDirect adapter was closed, or a new request for asynchronous notification was requested. 55 | - __ND_DEVICE_REMOVED__ - The underlying NetworkDirect adapter was removed from the system. Only cleanup operations on the NetworkDirect adapter will succeed. 56 | 57 | __Remarks:__ 58 | 59 | Clients are required to call this method to determine the final status of an operation, even if they detected completion through the Win32 [GetOverlappedResult](https://docs.microsoft.com/windows/desktop/api/ioapiset/nf-ioapiset-getoverlappedresult) function, [GetQueuedCompletionStatus](https://msdn.microsoft.com/library/windows/desktop/aa364986(v=vs.85).aspx), or other native Win32 APIs. This requirement allows providers to perform post-processing as necessary. 60 | 61 | The behavior of this method is identical to that of the Win32 [GetOverlappedResult](https://docs.microsoft.com/windows/desktop/api/ioapiset/nf-ioapiset-getoverlappedresult) function. You can call this function; however, you will not get the NetworkDirect return value. Specifically, instead of returning the status through GetLastError mechanisms, [IND2Overlapped::GetOverlappedResult](#ind2overlappedgetoverlappedresult) simply returns the actual result of the operation. When calling the Win32 [GetOverlappedResult](https://docs.microsoft.com/windows/desktop/api/ioapiset/nf-ioapiset-getoverlappedresult) function, the value of the parameter specified by _lpNumberOfBytesTransferred_ is specific to the provider implementationand does not convey any meaning to the client. 62 | 63 | Multiple instances of this function w.r.t. the same IND2Overlapped interface can be called concurrently as long as the _pOverlapped_ parameters point to different [OVERLAPPED](https://docs.microsoft.com/windows/desktop/api/minwinbase/ns-minwinbase-_overlapped) objects. To construct a parallel system using this feature, one may have multiple threads waiting for IOCP notifications by calling [GetQueuedCompletionStatus](https://msdn.microsoft.com/library/windows/desktop/aa364986(v=vs.85).aspx), and then process the notification by calling GetOverlappedResult. 64 | 65 | When completing a request that is in error, providers cannot change the status value to a success value in their [IND2Overlapped::GetOverlappedResult](#ind2overlappedgetoverlappedresult) method. They can, however, change a success value to an error, and they can return ND_PENDING if the request was only partially complete and the next phase initiated successfully. In the latter case, clients are required to again wait for the request completes. 66 | 67 | The NetworkDirect status values are defined to map 1 to 1 to their corresponding NTSTATUS values. Providers are encouraged to use the WDK function [NtDeviceIoControlFile](https://docs.microsoft.com/en-us/windows/desktop/api/winternl/nf-winternl-ntdeviceiocontrolfile) to issue IOCTL requests to preserve the status value that is returned by their kernel driver. Note that this function is marked as deprecated in the Microsoft Platform SDK, but it is valid for device drivers to use given their tight coupling with the operating system. 68 | -------------------------------------------------------------------------------- /docs/IND2Provider.md: -------------------------------------------------------------------------------- 1 | # IND2Provider interface 2 | 3 | Use to discover the NetworkDirect adapters that the provider supports. 4 | For details on getting an instance of this interface, see [Instantiating a NetworkDirect Provider](./NetworkDirectSPI.md#instantiate-provider). Note that NetworkDirect providers are not registered with the system by using COM registration, so you do _not_ use the CoCreateInstance function to get this interface. 5 | 6 | The IND2Provider interface inherits the methods of the [IUnknown interface](https://docs.microsoft.com/windows/desktop/api/unknwn/nn-unknwn-iunknown). 7 | In addition, IND2Provider defines the following methods: 8 | 9 | - [__QueryAddressList__](#ind2providerqueryaddresslist) - Retrieves a list of local addresses that the provider supports. 10 | 11 | - [__ResolveAddress__](#ind2providerresolveaddress) - Resolves a local IPv4 or IPv6 address to a unique adapter ID. 12 | 13 | - [__OpenAdapter__](#ind2provideropenadapter) - Retrieves an interface to a local NetworkDirect adapter. 14 | 15 | #### Implementation Notes 16 | 17 | __Requirements for InfiniBand:__ 18 | 19 | NetworkDirect providers use IP addresses to represent local and remote queue pairs, and it is the responsibility of the InfiniBand providers to manage mappings from these IP addresses to path records. Provides should use a distinct port space for RDMA connections, and only map to host TCP ports when absolutely necessary. 20 | 21 | InfiniBand vendors should use the IP addressing annex to the IP specification for formatting the connection establishment messages. InfiniBand providers can use the TCP port space for connection management, but the port space should be managed separately from the host port space. 22 | 23 | The InfiniBand 1.2 specification defines extensions to the architecture that provides matching semantics to iWARP. Specifically, the NetworkDirect SPI makes use of the following extensions: 24 | - Base Queue Management Extensions 25 | - Base Memory Management Extensions 26 | 27 | __Requirements for iWARP devices:__ 28 | 29 | iWARP devices are expected to support establishing connections in RDMA mode without any streaming-mode support. RDMA read with local invalidate operations is not supported because the InfiniBand architecture does not support that capability. 30 | 31 | __Registration:__ 32 | 33 | For details about how to register your provider, see the section [Registering a NetworkDirect service provider](./NetworkDirectSPI.md#registering-a-networkdirect-provider). 34 | 35 | ## IND2Provider::QueryAddressList 36 | Retrieves a list of local addresses that the provider supports. 37 | 38 | ``` 39 | HRESULT QueryAddressList( 40 | [in, out, optional] SOCKET_ADDRESS_LIST *pAddressList, 41 | [in, out] ULONG *pcbAddressList 42 | ); 43 | ``` 44 | 45 | __Parameters:__ 46 | 47 | - __pAddressList__ [in, out, optional] 48 | 49 | A list of addresses that the NetworkDirect adapters support. (For details of the list, see [SOCKET_ADDRESS_LIST](https://docs.microsoft.com/windows/desktop/api/ws2def/ns-ws2def-_socket_address_list) structure. May be nullptr if pcbAddressList is zero. 50 | 51 | - __pcbAddressList__ [in, out] 52 | 53 | The size, in bytes, of the pAddressList buffer. If the buffer is too small to hold the addresses, the method fails with ND_BUFFER_OVERFLOW and sets this parameter to the required buffer size. If the buffer is too big, the method sets this parameter to the size that is used on output. 54 | 55 | __Return Value:__ 56 | 57 | When you implement this method, you should return the following return values. If you return others, try to use well-known values to aid in debugging issues. 58 | 59 | - __ND_SUCCESS__ - All addresses supported by NetworkDirect adapters were returned in pAddressList. 60 | - __ND_BUFFER_OVERFLOW__ - The pAddressList buffer is not large enough to hold the addresses, and the pAddressList buffer was not modified. The pcbAddressList parameter is updated with the required buffer size. 61 | 62 | __Remarks:__ 63 | To determine the required buffer size, set pAddressList to nullptr, and set the value that is pointed to by pcbAddressList to zero. Then, call this method and use the value that is returned in the pcbAddressList parameter to allocate the pAddressList buffer. You may need to perform these calls in a loop because the size could change between calls. 64 | 65 | ### IND2Provider::ResolveAddress 66 | Returns a provider-managed unique ID for an adapter when given a local IPv4 or IPv6 address. 67 | 68 | ``` 69 | HRESULT 70 | ResolveAddress( 71 | [in] const struct sockaddr *pAddress, 72 | [in] ULONG cbAddress, 73 | [out] UINT64* pAdapterId 74 | ); 75 | ``` 76 | 77 | __Parameters:__ 78 | - __pAddress__ [in] 79 | 80 | A sockaddr structure that specifies the address of a local NetworkDirect adapter to open. Typically, this is a sockaddr_in structure for IPv4 addresses and a sockaddr_in6 structure for IPv6 addresses. The sin_port and sin6_port members are ignored for sockaddr_in and sockaddr_in6 address structures, respectively. 81 | - __cbAddress__ [in] 82 | 83 | The size, in bytes, of the pAddress buffer. 84 | - __pAdapterId__ [out] 85 | 86 | A unique identifier for the requested adapter. 87 | 88 | __Return Value:__ 89 | 90 | When you implement this method, you should return the following return values. If you return others, try to use well-known values to aid in debugging issues. 91 | 92 | - __ND_SUCCESS__ - The call succeeded and the ID of the requested adapter is returned in the pAdapterId parameter. 93 | - __ND_NO_MEMORY__ - There was not enough memory to resolve the address. 94 | - __ND_INVALID_ADDRESS__ - The address specified by the pAddress parameter is not supported by the NetworkDirect provider. 95 | 96 | __Remarks:__ 97 | 98 | A single NetworkDirect adapter can support more than a single IP address. By making the relationship between the addresses and the adapters explicit, this function allows sharing common resources such as completion queues and memory regions between connections that are active on different IP addresses of the same adapter. 99 | 100 | 101 | ## IND2Provider::OpenAdapter 102 | Retrieves an interface to a local NetworkDirect adapter. 103 | 104 | ``` 105 | HRESULT OpenAdapter( 106 | [in] REFIID iid, 107 | [in] UINT64 adapterId, 108 | [out] void **ppAdapter 109 | ); 110 | ``` 111 | 112 | __Parameters:__ 113 | - __iid__ [in] 114 | 115 | The IID of the adapter interface requested. IID_IND2Adapter must be supported, but other IIDs may be supported as new interfaces are defined. 116 | - __adapterId__ [in] 117 | 118 | ID returned by a previous call to the [IND2Provider::ResolveAddress](#ind2providerresolveaddress) method. 119 | - __ppAdapter__ [out] 120 | 121 | The requested interface to the opened adapter. 122 | 123 | __Return Value:__ 124 | 125 | When you implement this method, you should return the following return values. If you return others, try to use well-known values to aid in debugging issues. 126 | 127 | - __ND_SUCCESS__ - The call succeeded and the handle to the opened adapter is returned in the ppAdapter parameter. 128 | - __ND_NO_MEMORY__ - There was not enough memory to open the adapter. 129 | - __ND_INVALID_PARAMETER__ - The adapterId specified is not valid. 130 | 131 | __Implementation Notes:__ 132 | 133 | After getting an interface to the adapter, the application can release the IND2Provider interface. Providers must ensure that they remain loaded while resources are allocated. 134 | -------------------------------------------------------------------------------- /docs/cq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/NetworkDirect/043f1bf05e41343cc88dda619ddd86aee60a02fe/docs/cq.png -------------------------------------------------------------------------------- /src/dirs.proj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/examples/bldver.rc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | VS_VERSION_INFO VERSIONINFO 4 | FILEVERSION 1,0,0,1 5 | PRODUCTVERSION 1,0,0,1 6 | FILEFLAGSMASK 0x3fL 7 | #ifdef DEBUG 8 | FILEFLAGS 0x1L 9 | #else 10 | FILEFLAGS 0x0L 11 | #endif 12 | FILEOS 0x40004L 13 | FILETYPE RC_FILE_TYPE 14 | FILESUBTYPE 0x0L 15 | BEGIN 16 | BLOCK "StringFileInfo" 17 | BEGIN 18 | BLOCK "040904b0" 19 | BEGIN 20 | VALUE "CompanyName", "Microsoft Corporation\0" 21 | VALUE "FileDescription", RC_VERSION_FILE_DESCRIPTION 22 | VALUE "InternalName", RC_VERSION_INTERNAL_NAME 23 | VALUE "LegalCopyright", "Copyright \251 1995-2008 Microsoft Corporation\0" 24 | VALUE "LegalTrademarks", "Microsoft\256 is a registered trademark of Microsoft Corporation.\0" 25 | VALUE "OriginalFilename", RC_VERSION_ORIGINAL_FILE_NAME 26 | VALUE "ProductName", "Microsoft NetworkDirect DDK" 27 | VALUE "FileVersion", "1.0.0.1" 28 | VALUE "ProductVersion", "1.0.0.1" 29 | END 30 | END 31 | BLOCK "VarFileInfo" 32 | BEGIN 33 | VALUE "Translation", 0x409, 1200 34 | END 35 | END 36 | -------------------------------------------------------------------------------- /src/examples/dirs.proj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/examples/examples.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ..\;..\ndtestutil\;$(OutIncludePath);%(AdditionalIncludeDirectories) 7 | 8 | 9 | kernel32.lib;ws2_32.lib;uuid.lib;Iphlpapi.lib;%(AdditionalDependencies) 10 | $(OutDir)\..\ndutil\;..\ndtestutil\;%(AdditionalLibraryDirectories) 11 | 12 | 13 | ..;%(AdditionalIncludeDirectories) 14 | 15 | 16 | 17 | 18 | examples 19 | *.exe 20 | 21 | 22 | 23 | 24 | {6955ed94-3b21-4835-838a-a797aff63183} 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/examples/logging.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) Microsoft Corporation.All rights reserved. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | inline void INIT_LOG(const LPCWSTR testname) 7 | { 8 | wprintf(L"Beginning test: %s\n", testname); 9 | } 10 | 11 | inline void END_LOG(const LPCWSTR testname) 12 | { 13 | wprintf(L"End of test: %s\n", testname); 14 | } 15 | 16 | inline void LOG_FAILURE_HRESULT_AND_EXIT(HRESULT hr, const LPCWSTR errormessage, int LINE) 17 | { 18 | wprintf(errormessage, hr); 19 | wprintf(L" Line: %d\n", LINE); 20 | 21 | exit(LINE); 22 | } 23 | 24 | inline void LOG_FAILURE_AND_EXIT(const LPCWSTR errormessage, int LINE) 25 | { 26 | wprintf(errormessage); 27 | wprintf(L" Line: %d\n", LINE); 28 | 29 | exit(LINE); 30 | } 31 | 32 | inline void LOG_FAILURE_HRESULT(HRESULT hr, const LPCWSTR errormessage, int LINE) 33 | { 34 | wprintf(errormessage, hr); 35 | wprintf(L" Line: %d\n", LINE); 36 | } 37 | 38 | inline void LOG_FAILURE(const LPCWSTR errormessage, int LINE) 39 | { 40 | wprintf(errormessage); 41 | wprintf(L" Line: %d\n", LINE); 42 | } 43 | 44 | inline void RedirectLogsToFile(const TCHAR* logFileName) 45 | { 46 | // Can't use freopen_s because it doesn't allow sharing. 47 | // So supress the deprecated warning, because for our use 48 | // it isn't deprecated. 49 | #pragma warning( disable : 4996 ) 50 | if (_tfreopen(logFileName, _T("w"), stdout) == NULL || 51 | _tfreopen(logFileName, _T("a+"), stderr) == NULL) 52 | #pragma warning( default : 4996 ) 53 | { 54 | LOG_FAILURE_AND_EXIT(L"failed to redirect logs", __LINE__); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/examples/ndadapterinfo/NuGetAssetsLock.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | 6 | 7 | 8 | 9 | [1.0.0] 10 | imbNHw4hg7nnbLjFuagxR1oc7TJv058rCclt+DmqJrvYYKJ10R/tGuKjne1nq94y0FTM1zd4j9v9v9n5A9Va6w== 11 | vc150/1.0.0 12 | vc150.1.0.0.nupkg.sha512 13 | 14 | 15 | [1.0.3] 16 | SeyxBzNqK/4Mh0yqD7LrJKxKu7b8Bja+iJFivyUu09B45brU4gOwTYFO7hSgk6Ll+OCjl9pA5RZYmtyy2aU0DA== 17 | wk10/1.0.3 18 | wk10.1.0.3.nupkg.sha512 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/examples/ndadapterinfo/ndadapterinfo.cpp: -------------------------------------------------------------------------------- 1 | // Copyright(c) Microsoft Corporation.All rights reserved. 2 | // Licensed under the MIT License. 3 | // 4 | // ndadapterinfo.cpp - NetworkDirect AdapterInfo Test 5 | // 6 | // This test checks that the input IP address is a valid NetworkDirect 7 | // address, and that all addresses returned by QueryAddressList are 8 | // valid NetworkDirect addresses. If there are no addresses the test 9 | // generates an error. 10 | 11 | #include "ndcommon.h" 12 | #include 13 | #include 14 | 15 | const LPCWSTR TESTNAME = L"ndadapterinfo.exe"; 16 | 17 | void ShowUsage() 18 | { 19 | printf("ndadapterinfo [options] \n" 20 | "Options:\n" 21 | "\t-l,--logFile Log output to a given file\n" 22 | "\t-h,--help Show this message\n"); 23 | } 24 | 25 | static std::string TranslateAdapterInfoFlags(ULONG flags) 26 | { 27 | std::string flagsString; 28 | ULONG allFlags = ND_ADAPTER_FLAG_IN_ORDER_DMA_SUPPORTED | 29 | ND_ADAPTER_FLAG_CQ_INTERRUPT_MODERATION_SUPPORTED | 30 | ND_ADAPTER_FLAG_MULTI_ENGINE_SUPPORTED | 31 | ND_ADAPTER_FLAG_CQ_RESIZE_SUPPORTED | 32 | ND_ADAPTER_FLAG_LOOPBACK_CONNECTIONS_SUPPORTED; 33 | 34 | if (flags & ND_ADAPTER_FLAG_IN_ORDER_DMA_SUPPORTED) 35 | { 36 | flagsString += "\n\t\tND_ADAPTER_FLAG_IN_ORDER_DMA_SUPPORTED"; 37 | } 38 | 39 | if (flags & ND_ADAPTER_FLAG_CQ_INTERRUPT_MODERATION_SUPPORTED) 40 | { 41 | flagsString += "\n\t\tND_ADAPTER_FLAG_CQ_INTERRUPT_MODERATION_SUPPORTED"; 42 | } 43 | 44 | if (flags & ND_ADAPTER_FLAG_MULTI_ENGINE_SUPPORTED) 45 | { 46 | flagsString += "\n\t\tND_ADAPTER_FLAG_MULTI_ENGINE_SUPPORTED"; 47 | } 48 | 49 | if (flags & ND_ADAPTER_FLAG_CQ_RESIZE_SUPPORTED) 50 | { 51 | flagsString += "\n\t\tND_ADAPTER_FLAG_CQ_RESIZE_SUPPORTED"; 52 | } 53 | 54 | if (flags & ND_ADAPTER_FLAG_LOOPBACK_CONNECTIONS_SUPPORTED) 55 | { 56 | flagsString += "\n\t\tND_ADAPTER_FLAG_LOOPBACK_CONNECTIONS_SUPPORTED"; 57 | } 58 | 59 | if ((flags | allFlags) != allFlags) 60 | { 61 | ULONG additionalFlags = flags & ~allFlags; 62 | char tmpBuf[64]; 63 | snprintf(tmpBuf, sizeof(tmpBuf), "\n\t\t%08x", additionalFlags); 64 | flagsString += tmpBuf; 65 | } 66 | return flagsString; 67 | } 68 | 69 | int __cdecl _tmain(int argc, TCHAR* argv[]) 70 | { 71 | if (argc < 2) 72 | { 73 | ShowUsage(); 74 | return -1; 75 | } 76 | 77 | WSADATA wsaData; 78 | int ret = ::WSAStartup(MAKEWORD(2, 2), &wsaData); 79 | if (ret != 0) 80 | { 81 | printf("Failed to initialize Windows Sockets: %d\n", ret); 82 | exit(__LINE__); 83 | } 84 | 85 | TCHAR *logFileName = nullptr; 86 | for (int i = 1; i < argc; i++) 87 | { 88 | TCHAR *arg = argv[i]; 89 | if ((wcscmp(arg, L"-l") == 0) || (wcscmp(arg, L"--logFile") == 0)) 90 | { 91 | RedirectLogsToFile(argv[++i]); 92 | } 93 | else if ((wcscmp(arg, L"-h") == 0) || (wcscmp(arg, L"--help") == 0)) 94 | { 95 | ShowUsage(); 96 | exit(0); 97 | } 98 | } 99 | 100 | TCHAR *ipAddress = argv[argc -1]; 101 | struct sockaddr_in v4 = { 0 }; 102 | INT len = sizeof(v4); 103 | WSAStringToAddress( 104 | ipAddress, 105 | AF_INET, 106 | nullptr, 107 | reinterpret_cast(&v4), 108 | &len 109 | ); 110 | 111 | if (v4.sin_addr.s_addr == 0) 112 | { 113 | printf("Bad address.\n"); 114 | ShowUsage(); 115 | exit(__LINE__); 116 | } 117 | 118 | HRESULT hr = NdStartup(); 119 | if (FAILED(hr)) 120 | { 121 | LOG_FAILURE_HRESULT_AND_EXIT(hr, L"NdStartup failed with %08x", __LINE__); 122 | } 123 | 124 | hr = NdCheckAddress(reinterpret_cast(&v4), sizeof(v4)); 125 | if (FAILED(hr)) 126 | { 127 | LOG_FAILURE_HRESULT_AND_EXIT(hr, L"NdCheckAddress for input address returned %08x", __LINE__); 128 | } 129 | 130 | IND2Adapter *pAdapter = nullptr; 131 | hr = NdOpenAdapter( 132 | IID_IND2Adapter, 133 | reinterpret_cast(&v4), 134 | sizeof(v4), 135 | reinterpret_cast(&pAdapter) 136 | ); 137 | if (FAILED(hr)) 138 | { 139 | LOG_FAILURE_HRESULT_AND_EXIT(hr, L"Failed open adapter: %08x\n", __LINE__); 140 | } 141 | 142 | ND2_ADAPTER_INFO adapterInfo = { 0 }; 143 | adapterInfo.InfoVersion = ND_VERSION_2; 144 | ULONG adapterInfoSize = sizeof(adapterInfo); 145 | 146 | hr = pAdapter->Query(&adapterInfo, &adapterInfoSize); 147 | if (FAILED(hr)) 148 | { 149 | LOG_FAILURE_HRESULT_AND_EXIT(hr, L"IND2Adapter::GetAdapterInfo failed: %08x", __LINE__); 150 | } 151 | 152 | printf("InfoVersion: %lu\n", adapterInfo.InfoVersion); 153 | printf("VendorId: %u\n", adapterInfo.VendorId); 154 | printf("DeviceId: %u\n", adapterInfo.DeviceId); 155 | printf("AdapterId: 0x%08llx\n", adapterInfo.AdapterId); 156 | printf("MaxRegistrationSize: %zu\n", adapterInfo.MaxRegistrationSize); 157 | printf("MaxWindowSize: %zu\n", adapterInfo.MaxWindowSize); 158 | printf("MaxInitiatorSge: %lu\n", adapterInfo.MaxInitiatorSge); 159 | printf("MaxReceiveSge: %lu\n", adapterInfo.MaxReceiveSge); 160 | printf("MaxReadSge: %lu\n", adapterInfo.MaxReadSge); 161 | printf("MaxTransferLength: %lu\n", adapterInfo.MaxTransferLength); 162 | printf("MaxInlineDataSize: %lu\n", adapterInfo.MaxInlineDataSize); 163 | printf("MaxInboundReadLimit: %lu\n", adapterInfo.MaxInboundReadLimit); 164 | printf("MaxOutboundReadLimit: %lu\n", adapterInfo.MaxOutboundReadLimit); 165 | printf("MaxReceiveQueueDepth: %lu\n", adapterInfo.MaxReceiveQueueDepth); 166 | printf("MaxInitiatorQueueDepth: %lu\n", adapterInfo.MaxInitiatorQueueDepth); 167 | printf("MaxSharedReceiveQueueDepth: %lu\n", adapterInfo.MaxSharedReceiveQueueDepth); 168 | printf("MaxCompletionQueueDepth: %lu\n", adapterInfo.MaxCompletionQueueDepth); 169 | printf("InlineRequestThreshold: %lu\n", adapterInfo.InlineRequestThreshold); 170 | printf("LargeRequestThreshold: %lu\n", adapterInfo.LargeRequestThreshold); 171 | printf("MaxCallerData: %lu\n", adapterInfo.MaxCallerData); 172 | printf("MaxCalleeData: %lu\n", adapterInfo.MaxCalleeData); 173 | printf("AdapterFlags: %s\n", TranslateAdapterInfoFlags(adapterInfo.AdapterFlags).c_str()); 174 | 175 | pAdapter->Release(); 176 | hr = NdCleanup(); 177 | if (FAILED(hr)) 178 | { 179 | LOG_FAILURE_HRESULT_AND_EXIT(hr, L"NdCleanup failed with %08x", __LINE__); 180 | } 181 | 182 | _fcloseall(); 183 | WSACleanup(); 184 | return 0; 185 | } 186 | 187 | -------------------------------------------------------------------------------- /src/examples/ndadapterinfo/ndadapterinfo.rc: -------------------------------------------------------------------------------- 1 | #define RC_FILE_TYPE VFT_APP 2 | #define RC_VERSION_INTERNAL_NAME "ndadapterinfo\0" 3 | #define RC_VERSION_ORIGINAL_FILE_NAME "ndadapterinfo.exe\0" 4 | #define RC_VERSION_FILE_DESCRIPTION "NetworkDirect Adapter Info Test\0" 5 | 6 | #include 7 | -------------------------------------------------------------------------------- /src/examples/ndadapterinfo/ndadapterinfo.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15.0 6 | {8D8C0B5F-A47C-46BE-A3D4-54E39F0F88B8} 7 | Win32Proj 8 | ndadapterinfo 9 | 10 | 11 | 12 | Application 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | _CONSOLE;%(PreprocessorDefinitions) 21 | 22 | 23 | Console 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/examples/ndcat/NuGetAssetsLock.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | 6 | 7 | 8 | 9 | [1.0.0] 10 | imbNHw4hg7nnbLjFuagxR1oc7TJv058rCclt+DmqJrvYYKJ10R/tGuKjne1nq94y0FTM1zd4j9v9v9n5A9Va6w== 11 | vc150/1.0.0 12 | vc150.1.0.0.nupkg.sha512 13 | 14 | 15 | [1.0.3] 16 | SeyxBzNqK/4Mh0yqD7LrJKxKu7b8Bja+iJFivyUu09B45brU4gOwTYFO7hSgk6Ll+OCjl9pA5RZYmtyy2aU0DA== 17 | wk10/1.0.3 18 | wk10.1.0.3.nupkg.sha512 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/examples/ndcat/ndcat.cpp: -------------------------------------------------------------------------------- 1 | // Copyright(c) Microsoft Corporation.All rights reserved. 2 | // Licensed under the MIT License. 3 | // 4 | // ndcat.cpp - NetworkDirect catalog test 5 | // 6 | // This test checks that the input IP address is a valid NetworkDirect 7 | // address, and that all addresses returned by QueryAddressList are 8 | // valid NetworkDirect addresses. If there are no addresses the test 9 | // generates an error. 10 | 11 | #include "ndcommon.h" 12 | #include 13 | 14 | void ShowUsage() 15 | { 16 | printf("ndcat [options] \n" 17 | "Options:\n" 18 | "\t-l,--logFile Log output to a given file\n" 19 | "\t-h,--help Show this message\n"); 20 | } 21 | 22 | int __cdecl _tmain(int argc, TCHAR* argv[]) 23 | { 24 | WSADATA wsaData; 25 | int ret = ::WSAStartup(MAKEWORD(2, 2), &wsaData); 26 | if (ret != 0) 27 | { 28 | printf("Failed to initialize Windows Sockets: %d\n", ret); 29 | exit(__LINE__); 30 | } 31 | 32 | for (int i = 1; i < argc; i++) 33 | { 34 | TCHAR *arg = argv[i]; 35 | if ((wcscmp(arg, L"-l") == 0) || (wcscmp(arg, L"--logFile") == 0)) 36 | { 37 | RedirectLogsToFile(argv[++i]); 38 | } 39 | else if ((wcscmp(arg, L"-h") == 0) || (wcscmp(arg, L"--help") == 0)) 40 | { 41 | ShowUsage(); 42 | exit(0); 43 | } 44 | } 45 | 46 | TCHAR *ipAddress = argv[argc - 1]; 47 | struct sockaddr_in v4 = { 0 }; 48 | int addrLen = sizeof(v4); 49 | WSAStringToAddress( 50 | ipAddress, 51 | AF_INET, 52 | nullptr, 53 | reinterpret_cast(&v4), 54 | &addrLen 55 | ); 56 | 57 | if (v4.sin_addr.s_addr == 0) 58 | { 59 | printf("Bad address.\n"); 60 | ShowUsage(); 61 | exit(__LINE__); 62 | } 63 | 64 | HRESULT hr = NdStartup(); 65 | if (FAILED(hr)) 66 | { 67 | LOG_FAILURE_HRESULT_AND_EXIT(hr, L"NdStartup failed with %08x", __LINE__); 68 | } 69 | 70 | hr = NdCheckAddress(reinterpret_cast(&v4), sizeof(v4)); 71 | if (FAILED(hr)) 72 | { 73 | LOG_FAILURE_HRESULT_AND_EXIT(hr, L"NdCheckAddress for input address returned %08x", __LINE__); 74 | } 75 | 76 | SIZE_T len = 0; 77 | hr = NdQueryAddressList(0, nullptr, &len); 78 | if (hr != ND_BUFFER_OVERFLOW) 79 | { 80 | LOG_FAILURE_HRESULT_AND_EXIT(hr, L"NdQueryAddressList returned %08x", __LINE__); 81 | } 82 | 83 | if (len == 0) 84 | { 85 | LOG_FAILURE_AND_EXIT(L"NdQueryAddressList returned zero-length list", __LINE__); 86 | } 87 | 88 | SOCKET_ADDRESS_LIST* pList = static_cast(HeapAlloc(GetProcessHeap(), 0, len)); 89 | if (pList == nullptr) 90 | { 91 | LOG_FAILURE_AND_EXIT(L"Failed to allocate address list", __LINE__); 92 | } 93 | 94 | printf("Retrieving the full Addresslist"); 95 | hr = NdQueryAddressList(0, pList, &len); 96 | if (FAILED(hr)) 97 | { 98 | LOG_FAILURE_HRESULT_AND_EXIT(hr, L"NdQueryAddressList returned %08x", __LINE__); 99 | } 100 | 101 | // pList is already checked for nullptr 102 | #pragma warning(suppress: 6011) 103 | if (pList->iAddressCount == 0) 104 | { 105 | LOG_FAILURE_AND_EXIT(L"NdQueryAddressList returned zero-length list", __LINE__); 106 | } 107 | 108 | for (int i = 0; i < pList->iAddressCount; i++) 109 | { 110 | hr = NdCheckAddress(pList->Address[i].lpSockaddr, pList->Address[i].iSockaddrLength); 111 | if (FAILED(hr)) 112 | { 113 | LOG_FAILURE_HRESULT_AND_EXIT(hr, L"NdCheckAddress returned %08x", __LINE__); 114 | } 115 | } 116 | printf("\nValidation of full Addresslist passed"); 117 | hr = NdCleanup(); 118 | if (FAILED(hr)) 119 | { 120 | LOG_FAILURE_HRESULT_AND_EXIT(hr, L"NdCleanup failed with %08x", __LINE__); 121 | } 122 | HeapFree(GetProcessHeap(), 0, pList); 123 | 124 | _fcloseall(); 125 | WSACleanup(); 126 | return 0; 127 | } 128 | 129 | -------------------------------------------------------------------------------- /src/examples/ndcat/ndcat.rc: -------------------------------------------------------------------------------- 1 | #define RC_FILE_TYPE VFT_APP 2 | #define RC_VERSION_INTERNAL_NAME "ndcat\0" 3 | #define RC_VERSION_ORIGINAL_FILE_NAME "ndcat.exe\0" 4 | #define RC_VERSION_FILE_DESCRIPTION "NetworkDirect catalog test\0" 5 | 6 | #include 7 | -------------------------------------------------------------------------------- /src/examples/ndcat/ndcat.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15.0 6 | {8DC2234B-0FFD-492B-817E-C81DC04EFF86} 7 | Win32Proj 8 | ndcat 9 | 10 | 11 | 12 | Application 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Console 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/examples/ndcommon.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) Microsoft Corporation.All rights reserved. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | #ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. 9 | #define _WIN32_WINNT 0x0502 // Change this to the appropriate value to target other versions of Windows. 10 | #endif 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | 21 | 22 | class Timer 23 | { 24 | private: 25 | LARGE_INTEGER m_Start; 26 | LARGE_INTEGER m_Split; 27 | LARGE_INTEGER m_End; 28 | LARGE_INTEGER m_Freq; 29 | public: 30 | Timer() 31 | { 32 | m_Start.QuadPart = 0; 33 | m_End.QuadPart = 0; 34 | m_Freq.QuadPart = 0; 35 | m_Split.QuadPart = 0; 36 | ::QueryPerformanceFrequency( &m_Freq ); 37 | } 38 | 39 | void Start() 40 | { 41 | ::QueryPerformanceCounter( &m_Start ); 42 | } 43 | 44 | void Split() 45 | { 46 | ::QueryPerformanceCounter( &m_Split ); 47 | } 48 | 49 | void End() 50 | { 51 | ::QueryPerformanceCounter( &m_End ); 52 | } 53 | 54 | double Report() const 55 | { 56 | return ElapsedMicrosec( m_Start, m_End ); 57 | } 58 | 59 | double ReportPreSplit() const 60 | { 61 | return ElapsedMicrosec( m_Start, m_Split ); 62 | } 63 | 64 | double ReportPostSplit() const 65 | { 66 | return ElapsedMicrosec( m_Split, m_End ); 67 | } 68 | 69 | static LONGLONG Frequency() 70 | { 71 | LARGE_INTEGER m_Freq; 72 | ::QueryPerformanceFrequency( &m_Freq ); 73 | return m_Freq.QuadPart; 74 | } 75 | 76 | private: 77 | double ElapsedMicrosec( 78 | _In_ LARGE_INTEGER start, 79 | _In_ LARGE_INTEGER end 80 | ) const 81 | { 82 | return ( end.QuadPart - start.QuadPart ) * 1000000.0 / (double)m_Freq.QuadPart; 83 | } 84 | }; 85 | 86 | 87 | class CpuMonitor 88 | { 89 | private: 90 | double m_StartCpu; 91 | double m_SplitCpu; 92 | double m_EndCpu; 93 | LONGLONG m_StartIdle; 94 | LONGLONG m_SplitIdle; 95 | LONGLONG m_EndIdle; 96 | 97 | public: 98 | CpuMonitor() : 99 | m_StartCpu( 0 ), 100 | m_SplitCpu( 0 ), 101 | m_EndCpu( 0 ), 102 | m_StartIdle( 0 ), 103 | m_SplitIdle( 0 ), 104 | m_EndIdle( 0 ) 105 | { 106 | } 107 | 108 | void Start() 109 | { 110 | LONGLONG kernelTime; 111 | LONGLONG userTime; 112 | GetSystemTimes( 113 | reinterpret_cast(&m_StartIdle), 114 | reinterpret_cast(&kernelTime), 115 | reinterpret_cast(&userTime) 116 | ); 117 | m_StartCpu = (double)(userTime + kernelTime); 118 | } 119 | 120 | void End() 121 | { 122 | LONGLONG kernelTime; 123 | LONGLONG userTime; 124 | GetSystemTimes( 125 | reinterpret_cast(&m_EndIdle), 126 | reinterpret_cast(&kernelTime), 127 | reinterpret_cast(&userTime) 128 | ); 129 | m_EndCpu = (double)(userTime + kernelTime); 130 | } 131 | 132 | void Split() 133 | { 134 | LONGLONG kernelTime; 135 | LONGLONG userTime; 136 | GetSystemTimes( 137 | reinterpret_cast(&m_SplitIdle), 138 | reinterpret_cast(&kernelTime), 139 | reinterpret_cast(&userTime) 140 | ); 141 | m_SplitCpu = (double)(userTime + kernelTime); 142 | } 143 | 144 | double Report() const 145 | { 146 | return GetCpuTime( m_StartIdle, m_EndIdle, m_StartCpu, m_EndCpu ); 147 | } 148 | 149 | double ReportPreSplit() const 150 | { 151 | return GetCpuTime( m_StartIdle, m_SplitIdle, m_StartCpu, m_SplitCpu ); 152 | } 153 | 154 | double ReportPostSplit() const 155 | { 156 | return GetCpuTime( m_SplitIdle, m_EndIdle, m_SplitCpu, m_EndCpu ); 157 | } 158 | 159 | static DWORD CpuCount() 160 | { 161 | SYSTEM_INFO SystemInfo; 162 | GetSystemInfo(&SystemInfo); 163 | return SystemInfo.dwNumberOfProcessors; 164 | } 165 | 166 | private: 167 | static double GetCpuTime( 168 | _In_ LONGLONG startIdle, 169 | _In_ LONGLONG endIdle, 170 | _In_ double startCpu, 171 | _In_ double endCpu 172 | ) 173 | { 174 | return (100.0 - (((endIdle - startIdle) * 100) / (endCpu - startCpu))) * CpuCount(); 175 | } 176 | }; 177 | 178 | -------------------------------------------------------------------------------- /src/examples/ndmrlat/NuGetAssetsLock.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | 6 | 7 | 8 | 9 | [1.0.0] 10 | imbNHw4hg7nnbLjFuagxR1oc7TJv058rCclt+DmqJrvYYKJ10R/tGuKjne1nq94y0FTM1zd4j9v9v9n5A9Va6w== 11 | vc150/1.0.0 12 | vc150.1.0.0.nupkg.sha512 13 | 14 | 15 | [1.0.3] 16 | SeyxBzNqK/4Mh0yqD7LrJKxKu7b8Bja+iJFivyUu09B45brU4gOwTYFO7hSgk6Ll+OCjl9pA5RZYmtyy2aU0DA== 17 | wk10/1.0.3 18 | wk10.1.0.3.nupkg.sha512 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/examples/ndmrlat/ndmrlat.rc: -------------------------------------------------------------------------------- 1 | #define RC_FILE_TYPE VFT_APP 2 | #define RC_VERSION_INTERNAL_NAME "ndmrlat\0" 3 | #define RC_VERSION_ORIGINAL_FILE_NAME "ndmrlat.exe\0" 4 | #define RC_VERSION_FILE_DESCRIPTION "NetworkDirect memory registration latency test\0" 5 | 6 | #include 7 | -------------------------------------------------------------------------------- /src/examples/ndmrlat/ndmrlat.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15.0 6 | {432cd967-42fa-437a-80a4-61c890e72418} 7 | Win32Proj 8 | ndmrlat 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | _CONSOLE;%(PreprocessorDefinitions) 18 | 19 | 20 | Console 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | Application 31 | Unicode 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/examples/ndmrrate/NuGetAssetsLock.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | 6 | 7 | 8 | 9 | [1.0.0] 10 | imbNHw4hg7nnbLjFuagxR1oc7TJv058rCclt+DmqJrvYYKJ10R/tGuKjne1nq94y0FTM1zd4j9v9v9n5A9Va6w== 11 | vc150/1.0.0 12 | vc150.1.0.0.nupkg.sha512 13 | 14 | 15 | [1.0.3] 16 | SeyxBzNqK/4Mh0yqD7LrJKxKu7b8Bja+iJFivyUu09B45brU4gOwTYFO7hSgk6Ll+OCjl9pA5RZYmtyy2aU0DA== 17 | wk10/1.0.3 18 | wk10.1.0.3.nupkg.sha512 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/examples/ndmrrate/ndmrrate.rc: -------------------------------------------------------------------------------- 1 | #define RC_FILE_TYPE VFT_APP 2 | #define RC_VERSION_INTERNAL_NAME "ndregrate\0" 3 | #define RC_VERSION_ORIGINAL_FILE_NAME "ndregrate.exe\0" 4 | #define RC_VERSION_FILE_DESCRIPTION "NetworkDirect memory registration bandwidth test\0" 5 | 6 | #include 7 | -------------------------------------------------------------------------------- /src/examples/ndmrrate/ndmrrate.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15.0 6 | {8d8e0152-c783-490b-b2a0-50aa4b909934} 7 | Win32Proj 8 | ndmrrate 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | _CONSOLE;%(PreprocessorDefinitions) 18 | 19 | 20 | Console 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | Application 31 | Unicode 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/examples/ndping/NuGetAssetsLock.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | 6 | 7 | 8 | 9 | [1.0.0] 10 | imbNHw4hg7nnbLjFuagxR1oc7TJv058rCclt+DmqJrvYYKJ10R/tGuKjne1nq94y0FTM1zd4j9v9v9n5A9Va6w== 11 | vc150/1.0.0 12 | vc150.1.0.0.nupkg.sha512 13 | 14 | 15 | [1.0.3] 16 | SeyxBzNqK/4Mh0yqD7LrJKxKu7b8Bja+iJFivyUu09B45brU4gOwTYFO7hSgk6Ll+OCjl9pA5RZYmtyy2aU0DA== 17 | wk10/1.0.3 18 | wk10.1.0.3.nupkg.sha512 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/examples/ndping/ndping.rc: -------------------------------------------------------------------------------- 1 | #define RC_FILE_TYPE VFT_APP 2 | #define RC_VERSION_INTERNAL_NAME "ndping\0" 3 | #define RC_VERSION_ORIGINAL_FILE_NAME "ndping.exe\0" 4 | #define RC_VERSION_FILE_DESCRIPTION "NetworkDirect unidirectional send/recv ping test\0" 5 | 6 | #include 7 | -------------------------------------------------------------------------------- /src/examples/ndping/ndping.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15.0 6 | {7523D17D-72E7-4AFE-B176-6A37A3170416} 7 | Win32Proj 8 | ndping 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | _CONSOLE;%(PreprocessorDefinitions) 18 | 19 | 20 | Console 21 | 22 | 23 | ..;%(AdditionalIncludeDirectories) 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | Application 34 | Unicode 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/examples/ndpingpong/NuGetAssetsLock.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | 6 | 7 | 8 | 9 | [1.0.0] 10 | imbNHw4hg7nnbLjFuagxR1oc7TJv058rCclt+DmqJrvYYKJ10R/tGuKjne1nq94y0FTM1zd4j9v9v9n5A9Va6w== 11 | vc150/1.0.0 12 | vc150.1.0.0.nupkg.sha512 13 | 14 | 15 | [1.0.3] 16 | SeyxBzNqK/4Mh0yqD7LrJKxKu7b8Bja+iJFivyUu09B45brU4gOwTYFO7hSgk6Ll+OCjl9pA5RZYmtyy2aU0DA== 17 | wk10/1.0.3 18 | wk10.1.0.3.nupkg.sha512 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/examples/ndpingpong/ndpingpong.rc: -------------------------------------------------------------------------------- 1 | #define RC_FILE_TYPE VFT_APP 2 | #define RC_VERSION_INTERNAL_NAME "ndpingpong\0" 3 | #define RC_VERSION_ORIGINAL_FILE_NAME "ndpingpong.exe\0" 4 | #define RC_VERSION_FILE_DESCRIPTION "NetworkDirect send/recv pingpong test\0" 5 | 6 | #include 7 | -------------------------------------------------------------------------------- /src/examples/ndpingpong/ndpingpong.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15.0 6 | {32A2B4B2-58B0-4878-BFD5-D6FDB8B35AAA} 7 | Win32Proj 8 | ndpingpong 9 | 10 | 11 | 12 | Application 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | _CONSOLE;%(PreprocessorDefinitions) 21 | StdCall 22 | 23 | 24 | Console 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/examples/ndrping/NuGetAssetsLock.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | 6 | 7 | 8 | 9 | [1.0.0] 10 | imbNHw4hg7nnbLjFuagxR1oc7TJv058rCclt+DmqJrvYYKJ10R/tGuKjne1nq94y0FTM1zd4j9v9v9n5A9Va6w== 11 | vc150/1.0.0 12 | vc150.1.0.0.nupkg.sha512 13 | 14 | 15 | [1.0.3] 16 | SeyxBzNqK/4Mh0yqD7LrJKxKu7b8Bja+iJFivyUu09B45brU4gOwTYFO7hSgk6Ll+OCjl9pA5RZYmtyy2aU0DA== 17 | wk10/1.0.3 18 | wk10.1.0.3.nupkg.sha512 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/examples/ndrping/ndrping.rc: -------------------------------------------------------------------------------- 1 | #define RC_FILE_TYPE VFT_APP 2 | #define RC_VERSION_INTERNAL_NAME "ndrping\0" 3 | #define RC_VERSION_ORIGINAL_FILE_NAME "ndrping.exe\0" 4 | #define RC_VERSION_FILE_DESCRIPTION "NetworkDirect unidirectional RDMA ping test\0" 5 | 6 | #include 7 | -------------------------------------------------------------------------------- /src/examples/ndrping/ndrping.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15.0 6 | {e4965852-d42d-4c02-8bf3-f26d521487c5} 7 | Win32Proj 8 | ndrping 9 | 10 | 11 | 12 | Application 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | _CONSOLE;%(PreprocessorDefinitions) 21 | StdCall 22 | 23 | 24 | Console 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/examples/ndrpingpong/NuGetAssetsLock.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | 6 | 7 | 8 | 9 | [1.0.0] 10 | imbNHw4hg7nnbLjFuagxR1oc7TJv058rCclt+DmqJrvYYKJ10R/tGuKjne1nq94y0FTM1zd4j9v9v9n5A9Va6w== 11 | vc150/1.0.0 12 | vc150.1.0.0.nupkg.sha512 13 | 14 | 15 | [1.0.3] 16 | SeyxBzNqK/4Mh0yqD7LrJKxKu7b8Bja+iJFivyUu09B45brU4gOwTYFO7hSgk6Ll+OCjl9pA5RZYmtyy2aU0DA== 17 | wk10/1.0.3 18 | wk10.1.0.3.nupkg.sha512 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/examples/ndrpingpong/ndrpingpong.rc: -------------------------------------------------------------------------------- 1 | #define RC_FILE_TYPE VFT_APP 2 | #define RC_VERSION_INTERNAL_NAME "ndrpingpong\0" 3 | #define RC_VERSION_ORIGINAL_FILE_NAME "ndrpingpong.exe\0" 4 | #define RC_VERSION_FILE_DESCRIPTION "NetworkDirect RDMA write pingpong test\0" 5 | 6 | #include 7 | -------------------------------------------------------------------------------- /src/examples/ndrpingpong/ndrpingpong.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15.0 6 | {104A3A1F-5C55-4FF0-A040-18B8725B3A0A} 7 | Win32Proj 8 | ndrpingpong 9 | 10 | 11 | 12 | Application 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | _CONSOLE;%(PreprocessorDefinitions) 21 | StdCall 22 | 23 | 24 | Console 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/examples/ndsupport.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) Microsoft Corporation.All rights reserved. 3 | // Licensed under the MIT License. 4 | // 5 | // Net Direct Helper Interface 6 | // 7 | 8 | #pragma once 9 | 10 | #ifndef _NETDIRECT_H_ 11 | #define _NETDIRECT_H_ 12 | 13 | #include 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" 18 | { 19 | #endif // __cplusplus 20 | 21 | #define ND_HELPER_API __stdcall 22 | 23 | 24 | // 25 | // Initialization 26 | // 27 | HRESULT ND_HELPER_API 28 | NdStartup( 29 | VOID 30 | ); 31 | 32 | HRESULT ND_HELPER_API 33 | NdCleanup( 34 | VOID 35 | ); 36 | 37 | VOID ND_HELPER_API 38 | NdFlushProviders( 39 | VOID 40 | ); 41 | 42 | // 43 | // Network capabilities 44 | // 45 | #define ND_QUERY_EXCLUDE_EMULATOR_ADDRESSES 0x00000001 46 | #define ND_QUERY_EXCLUDE_NDv1_ADDRESSES 0x00000002 47 | #define ND_QUERY_EXCLUDE_NDv2_ADDRESSES 0x00000004 48 | 49 | HRESULT ND_HELPER_API 50 | NdQueryAddressList( 51 | _In_ DWORD flags, 52 | _Out_opt_bytecap_post_bytecount_(*pcbAddressList, *pcbAddressList) SOCKET_ADDRESS_LIST* pAddressList, 53 | _Inout_ SIZE_T* pcbAddressList 54 | ); 55 | 56 | 57 | HRESULT ND_HELPER_API 58 | NdResolveAddress( 59 | _In_bytecount_(cbRemoteAddress) const struct sockaddr* pRemoteAddress, 60 | _In_ SIZE_T cbRemoteAddress, 61 | _Out_bytecap_(*pcbLocalAddress) struct sockaddr* pLocalAddress, 62 | _Inout_ SIZE_T* pcbLocalAddress 63 | ); 64 | 65 | 66 | HRESULT ND_HELPER_API 67 | NdCheckAddress( 68 | _In_bytecount_(cbAddress) const struct sockaddr* pAddress, 69 | _In_ SIZE_T cbAddress 70 | ); 71 | 72 | 73 | HRESULT ND_HELPER_API 74 | NdOpenAdapter( 75 | _In_ REFIID iid, 76 | _In_bytecount_(cbAddress) const struct sockaddr* pAddress, 77 | _In_ SIZE_T cbAddress, 78 | _Deref_out_ VOID** ppIAdapter 79 | ); 80 | 81 | 82 | HRESULT ND_HELPER_API 83 | NdOpenV1Adapter( 84 | _In_bytecount_(cbAddress) const struct sockaddr* pAddress, 85 | _In_ SIZE_T cbAddress, 86 | _Deref_out_ INDAdapter** ppIAdapter 87 | ); 88 | 89 | #ifdef __cplusplus 90 | } 91 | #endif // __cplusplus 92 | 93 | 94 | #endif // _NETDIRECT_H_ 95 | -------------------------------------------------------------------------------- /src/examples/ndtestutil/NuGetAssetsLock.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | 6 | 7 | 8 | 9 | [1.0.0] 10 | imbNHw4hg7nnbLjFuagxR1oc7TJv058rCclt+DmqJrvYYKJ10R/tGuKjne1nq94y0FTM1zd4j9v9v9n5A9Va6w== 11 | vc150/1.0.0 12 | vc150.1.0.0.nupkg.sha512 13 | 14 | 15 | [1.0.3] 16 | SeyxBzNqK/4Mh0yqD7LrJKxKu7b8Bja+iJFivyUu09B45brU4gOwTYFO7hSgk6Ll+OCjl9pA5RZYmtyy2aU0DA== 17 | wk10/1.0.3 18 | wk10.1.0.3.nupkg.sha512 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/examples/ndtestutil/ndtestutil.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15.0 6 | ndtestutil 7 | {c71f993f-d743-41dd-b1bc-b00f500e2602} 8 | Win32Proj 9 | 10 | 11 | 12 | StaticLibrary 13 | WindowsUserModeDriver10.0 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | _LIB;%(PreprocessorDefinitions) 22 | $(OutIncludePath);.\;..\;%(AdditionalIncludeDirectories); 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | MultiThreadedDebug 38 | 39 | 40 | 41 | 42 | MultiThreaded 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /src/ndutil/NuGetAssetsLock.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | 6 | 7 | 8 | 9 | [1.0.0] 10 | imbNHw4hg7nnbLjFuagxR1oc7TJv058rCclt+DmqJrvYYKJ10R/tGuKjne1nq94y0FTM1zd4j9v9v9n5A9Va6w== 11 | vc150/1.0.0 12 | vc150.1.0.0.nupkg.sha512 13 | 14 | 15 | [1.0.3] 16 | SeyxBzNqK/4Mh0yqD7LrJKxKu7b8Bja+iJFivyUu09B45brU4gOwTYFO7hSgk6Ll+OCjl9pA5RZYmtyy2aU0DA== 17 | wk10/1.0.3 18 | wk10.1.0.3.nupkg.sha512 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/ndutil/assertutil.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) Microsoft Corporation.All rights reserved. 2 | // Licensed under the MIT License. 3 | // 4 | // 5 | // Summary: 6 | // This file contains the assert utility macros. 7 | // Note: the "Invariant" versions that are included in retail. 8 | // 9 | // InvariantAssert/Assert(exp_) : 10 | // This uses interupt 2c, which enables new assert break and skip features. 11 | // If this assert fires, it will raise a fatal error and crash the host process. 12 | // If AeDebug key is set, this will cause the debugger to launch 13 | // When debugger attached, the 'ahi' command can be used to ignore the assertion and continue. 14 | // NOTE: Unlike the CRT assert, the strings for these asserts are stored in the symbols, 15 | // so asserts do not add strings to the image. 16 | // 17 | // InvariantAssertP/AssertP(exp_) : 18 | // This is the same as the InvariantAssert/Assert macro, except that it will only passively fire 19 | // when a debugger is actually attached. 20 | // 21 | // 22 | 23 | #define InvariantAssert(exp_) \ 24 | ((!(exp_)) ? \ 25 | (__annotation(L"Debug", L"AssertFail", L#exp_), \ 26 | __int2c(), FALSE) : \ 27 | TRUE) 28 | 29 | #define InvariantAssertP( exp_ ) \ 30 | ((!(exp_) && IsDebuggerPresent()) ? \ 31 | (__annotation(L"Debug", L"PassiveAssertFail", L#exp_), \ 32 | __int2c(), FALSE) : \ 33 | TRUE) 34 | 35 | #if DBG 36 | # define Assert(exp_) __analysis_assume(exp_);InvariantAssert(exp_) 37 | # define AssertP( exp_ ) __analysis_assume(exp_);InvariantAssertP(exp_) 38 | #else 39 | # define Assert( exp_ ) __analysis_assume(exp_) 40 | # define AssertP( exp_ ) __analysis_assume(exp_) 41 | #endif 42 | -------------------------------------------------------------------------------- /src/ndutil/list.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) Microsoft Corporation.All rights reserved. 3 | // Licensed under the MIT License. 4 | // 5 | // 6 | // List and List::iterator, implements an intrusive double linked list and 7 | // iterator template 8 | // 9 | // List is defined as a circular double linked list. With actions to insert 10 | // and remove entries. 11 | // 12 | // List 13 | // +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ 14 | // -| |<--| |-| |-| |-| |-| | 15 | // | head| | data| | data| | data| | data| | data| 16 | // | |-->| |-| |-| |-| |-| |- 17 | // +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ 18 | // 19 | // Linked list diagram 20 | // 21 | // An iteration is defined for the list using the member type named 22 | // iterator. To declare an interator variable, use fully qualified 23 | // name. e.g., List::iterator. An iterator variable is analogous 24 | // to type T pointer. Dereference '*' and arrow '->' operators are 25 | // overloaded for this type so you can (almost) freely use it as a 26 | // T pointer. 27 | // 28 | // Example: 29 | // 30 | // for(List::iterator p = list.begin(); p != list.end(); ++p) 31 | // { 32 | // p->doSomeThing(); 33 | // } 34 | // 35 | 36 | #pragma once 37 | 38 | #ifndef _MSMQ_LIST_H_ 39 | #define _MSMQ_LIST_H_ 40 | 41 | #ifndef __drv_aliasesMem 42 | #define __drv_aliasesMem 43 | #endif 44 | 45 | //--------------------------------------------------------- 46 | // 47 | // class ListHelper 48 | // 49 | //--------------------------------------------------------- 50 | template 51 | class ListHelper 52 | { 53 | public: 54 | enum { Offset = FIELD_OFFSET(T, m_link) }; 55 | }; 56 | 57 | 58 | //--------------------------------------------------------- 59 | // 60 | // class List 61 | // 62 | //--------------------------------------------------------- 63 | template::Offset> 64 | class List 65 | { 66 | private: 67 | LIST_ENTRY m_head; 68 | 69 | public: 70 | class iterator; 71 | 72 | public: 73 | List(); 74 | 75 | #if DBG 76 | ~List(); 77 | #endif 78 | 79 | iterator begin() const; 80 | iterator end() const; 81 | 82 | bool empty() const; 83 | 84 | T& front() const; 85 | T& back() const; 86 | void push_front(_Inout_ __drv_aliasesMem T* item); 87 | void push_back(_Inout_ __drv_aliasesMem T* item); 88 | void pop_front(); 89 | void pop_back(); 90 | 91 | iterator insert(iterator it, T& item); 92 | iterator erase(iterator it); 93 | void remove(T& item); 94 | 95 | public: 96 | static LIST_ENTRY* item2entry(T&); 97 | static T& entry2item(LIST_ENTRY*); 98 | static void RemoveEntry(LIST_ENTRY*); 99 | static void InsertBefore(LIST_ENTRY* pNext, LIST_ENTRY*); 100 | static void InsertAfter(LIST_ENTRY* pPrev, LIST_ENTRY*); 101 | 102 | private: 103 | List(const List&); 104 | List& operator=(const List&); 105 | 106 | public: 107 | 108 | // 109 | // class List::iterator 110 | // 111 | class iterator 112 | { 113 | private: 114 | LIST_ENTRY * m_current; 115 | 116 | public: 117 | explicit iterator(LIST_ENTRY* pEntry) : 118 | m_current(pEntry) 119 | { 120 | } 121 | 122 | 123 | iterator& operator++() 124 | { 125 | m_current = m_current->Flink; 126 | return *this; 127 | } 128 | 129 | 130 | iterator& operator--() 131 | { 132 | m_current = m_current->Blink; 133 | return *this; 134 | } 135 | 136 | 137 | T& operator*() const 138 | { 139 | return entry2item(m_current); 140 | } 141 | 142 | 143 | T* operator->() const 144 | { 145 | return (&**this); 146 | } 147 | 148 | 149 | bool operator==(const iterator& it) const 150 | { 151 | return (m_current == it.m_current); 152 | } 153 | 154 | 155 | bool operator!=(const iterator& it) const 156 | { 157 | return !(*this == it); 158 | } 159 | }; 160 | // 161 | // end class iterator decleration 162 | // 163 | }; 164 | 165 | 166 | //--------------------------------------------------------- 167 | // 168 | // IMPLEMENTATION 169 | // 170 | //--------------------------------------------------------- 171 | template 172 | inline List::List() 173 | { 174 | m_head.Flink = &m_head; 175 | m_head.Blink = &m_head; 176 | } 177 | 178 | #if DBG 179 | template 180 | inline List::~List() 181 | { 182 | ASSERT_BENIGN(empty()); 183 | } 184 | #endif 185 | 186 | template 187 | inline LIST_ENTRY* List::item2entry(T& item) 188 | { 189 | return ((LIST_ENTRY*)(PVOID)((PCHAR)&item + Offset)); 190 | } 191 | 192 | 193 | template 194 | inline T& List::entry2item(LIST_ENTRY* pEntry) 195 | { 196 | return *((T*)(PVOID)((PCHAR)pEntry - Offset)); 197 | } 198 | 199 | 200 | template 201 | inline void List::InsertBefore(LIST_ENTRY* pNext, LIST_ENTRY* pEntry) 202 | { 203 | pEntry->Flink = pNext; 204 | pEntry->Blink = pNext->Blink; 205 | pNext->Blink->Flink = pEntry; 206 | pNext->Blink = pEntry; 207 | } 208 | 209 | 210 | template 211 | inline void List::InsertAfter(LIST_ENTRY* pPrev, LIST_ENTRY* pEntry) 212 | { 213 | pEntry->Blink = pPrev; 214 | pEntry->Flink = pPrev->Flink; 215 | pPrev->Flink->Blink = pEntry; 216 | pPrev->Flink = pEntry; 217 | } 218 | 219 | 220 | template 221 | inline void List::RemoveEntry(LIST_ENTRY* pEntry) 222 | { 223 | LIST_ENTRY* Blink = pEntry->Blink; 224 | LIST_ENTRY* Flink = pEntry->Flink; 225 | 226 | Blink->Flink = Flink; 227 | Flink->Blink = Blink; 228 | 229 | pEntry->Flink = pEntry->Blink = nullptr; 230 | } 231 | 232 | 233 | template 234 | inline typename List::iterator List::begin() const 235 | { 236 | return iterator(m_head.Flink); 237 | } 238 | 239 | 240 | template 241 | inline typename List::iterator List::end() const 242 | { 243 | return iterator(const_cast(&m_head)); 244 | } 245 | 246 | 247 | template 248 | inline bool List::empty() const 249 | { 250 | return (m_head.Flink == &m_head); 251 | } 252 | 253 | 254 | template 255 | inline T& List::front() const 256 | { 257 | ASSERT(!empty()); 258 | return entry2item(m_head.Flink); 259 | } 260 | 261 | 262 | template 263 | inline T& List::back() const 264 | { 265 | ASSERT(!empty()); 266 | return entry2item(m_head.Blink); 267 | } 268 | 269 | 270 | #pragma prefast(disable:28194, "Linking the item into the list aliases the memory."); 271 | template 272 | inline void List::push_front(_Inout_ __drv_aliasesMem T* item) 273 | { 274 | LIST_ENTRY* pEntry = item2entry(*item); 275 | InsertAfter(&m_head, pEntry); 276 | } 277 | 278 | 279 | #pragma prefast(disable:28194, "Linking the item into the list aliases the memory."); 280 | template 281 | inline void List::push_back(_Inout_ __drv_aliasesMem T* item) 282 | { 283 | LIST_ENTRY* pEntry = item2entry(*item); 284 | InsertBefore(&m_head, pEntry); 285 | } 286 | 287 | 288 | template 289 | inline void List::pop_front() 290 | { 291 | ASSERT(!empty()); 292 | RemoveEntry(m_head.Flink); 293 | } 294 | 295 | 296 | template 297 | inline void List::pop_back() 298 | { 299 | ASSERT(!empty()); 300 | RemoveEntry(m_head.Blink); 301 | } 302 | 303 | 304 | template 305 | inline typename List::iterator List::insert(iterator it, T& item) 306 | { 307 | LIST_ENTRY* pEntry = item2entry(item); 308 | LIST_ENTRY* pNext = item2entry(*it); 309 | InsertBefore(pNext, pEntry); 310 | return iterator(pEntry); 311 | } 312 | 313 | 314 | template 315 | inline typename List::iterator List::erase(iterator it) 316 | { 317 | ASSERT(it != end()); 318 | iterator next = it; 319 | ++next; 320 | remove(*it); 321 | return next; 322 | } 323 | 324 | 325 | template 326 | inline void List::remove(T& item) 327 | { 328 | ASSERT(&item != &*end()); 329 | LIST_ENTRY* pEntry = item2entry(item); 330 | RemoveEntry(pEntry); 331 | } 332 | 333 | #endif // _MSMQ_LIST_H_ 334 | -------------------------------------------------------------------------------- /src/ndutil/ndaddr.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) Microsoft Corporation.All rights reserved. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #include "precomp.h" 7 | #include "ndaddr.h" 8 | 9 | 10 | namespace NetworkDirect 11 | { 12 | 13 | Address::Address( 14 | _In_ const struct sockaddr& addr, 15 | _In_ Provider& provider 16 | ) : 17 | m_pProvider(&provider) 18 | { 19 | m_link.Flink = &m_link; 20 | m_link.Blink = &m_link; 21 | 22 | ASSERT(addr.sa_family == AF_INET || addr.sa_family == AF_INET6); 23 | 24 | switch (addr.sa_family) 25 | { 26 | case AF_INET: 27 | ::CopyMemory(&m_Addr.Ipv4, &addr, sizeof(m_Addr.Ipv4)); 28 | break; 29 | case AF_INET6: 30 | ::CopyMemory(&m_Addr.Ipv6, &addr, sizeof(m_Addr.Ipv6)); 31 | break; 32 | default: 33 | ASSERT(addr.sa_family == AF_INET || 34 | addr.sa_family == AF_INET6); 35 | m_Addr.si_family = AF_UNSPEC; 36 | } 37 | } 38 | 39 | 40 | bool Address::Matches(const struct sockaddr* pAddr) const 41 | { 42 | switch (pAddr->sa_family) 43 | { 44 | case AF_INET: 45 | return reinterpret_cast(pAddr)->sin_addr.S_un.S_addr == 46 | m_Addr.Ipv4.sin_addr.S_un.S_addr; 47 | 48 | case AF_INET6: 49 | return (::memcmp(reinterpret_cast(pAddr)->sin6_addr.u.Byte, 50 | m_Addr.Ipv6.sin6_addr.u.Byte, sizeof(m_Addr.Ipv6.sin6_addr)) == 0); 51 | 52 | default: 53 | return false; 54 | } 55 | } 56 | 57 | 58 | SIZE_T Address::CopySockaddr(_Out_writes_(len) BYTE* pBuf, _In_ SIZE_T len) const 59 | { 60 | switch (m_Addr.si_family) 61 | { 62 | case AF_INET: 63 | if (len < sizeof(m_Addr.Ipv4)) 64 | { 65 | return 0; 66 | } 67 | 68 | ::CopyMemory(pBuf, &m_Addr.Ipv4, sizeof(m_Addr.Ipv4)); 69 | return sizeof(m_Addr.Ipv4); 70 | 71 | case AF_INET6: 72 | if (len < sizeof(m_Addr.Ipv6)) 73 | { 74 | return 0; 75 | } 76 | 77 | ::CopyMemory(pBuf, &m_Addr.Ipv6, sizeof(m_Addr.Ipv6)); 78 | return sizeof(m_Addr.Ipv6); 79 | 80 | default: 81 | return 0; 82 | } 83 | } 84 | 85 | } // namespace NetworkDirect 86 | -------------------------------------------------------------------------------- /src/ndutil/ndaddr.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) Microsoft Corporation.All rights reserved. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | 7 | #pragma once 8 | 9 | 10 | namespace NetworkDirect 11 | { 12 | 13 | class Provider; 14 | 15 | class Address 16 | { 17 | friend class ListHelper
; 18 | 19 | LIST_ENTRY m_link; 20 | Provider* m_pProvider; 21 | SOCKADDR_INET m_Addr; 22 | 23 | public: 24 | Address(_In_ const struct sockaddr& addr, _In_ Provider& provider); 25 | 26 | bool Matches(const struct sockaddr* pMatchAddr) const; 27 | Provider* GetProvider() const { return m_pProvider; } 28 | 29 | short AF() const { return m_Addr.si_family; }; 30 | SIZE_T CopySockaddr(_Out_writes_(len) BYTE* pBuf, _In_ SIZE_T len) const; 31 | 32 | }; 33 | 34 | } // namespace NetworkDirect 35 | 36 | -------------------------------------------------------------------------------- /src/ndutil/nddef.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) Microsoft Corporation.All rights reserved. 3 | // Licensed under the MIT License. 4 | // 5 | // 6 | // Module Name: 7 | // 8 | // nddef.h 9 | // 10 | // Abstract: 11 | // 12 | // NetworkDirect Service Provider structure definitions 13 | // 14 | // Environment: 15 | // 16 | // User mode and kernel mode 17 | // 18 | 19 | 20 | #ifndef _NDDEF_H_ 21 | #define _NDDEF_H_ 22 | 23 | #pragma once 24 | 25 | #define ND_VERSION_1 0x1 26 | #define ND_VERSION_2 0x20000 27 | 28 | #ifndef NDVER 29 | #define NDVER ND_VERSION_2 30 | #endif 31 | 32 | #define ND_ADAPTER_FLAG_IN_ORDER_DMA_SUPPORTED 0x00000001 33 | #define ND_ADAPTER_FLAG_CQ_INTERRUPT_MODERATION_SUPPORTED 0x00000004 34 | #define ND_ADAPTER_FLAG_MULTI_ENGINE_SUPPORTED 0x00000008 35 | #define ND_ADAPTER_FLAG_CQ_RESIZE_SUPPORTED 0x00000100 36 | #define ND_ADAPTER_FLAG_LOOPBACK_CONNECTIONS_SUPPORTED 0x00010000 37 | 38 | #define ND_CQ_NOTIFY_ERRORS 0 39 | #define ND_CQ_NOTIFY_ANY 1 40 | #define ND_CQ_NOTIFY_SOLICITED 2 41 | 42 | #define ND_MR_FLAG_ALLOW_LOCAL_WRITE 0x00000001 43 | #define ND_MR_FLAG_ALLOW_REMOTE_READ 0x00000002 44 | #define ND_MR_FLAG_ALLOW_REMOTE_WRITE 0x00000005 45 | #define ND_MR_FLAG_RDMA_READ_SINK 0x00000008 46 | #define ND_MR_FLAG_DO_NOT_SECURE_VM 0x80000000 47 | 48 | #define ND_OP_FLAG_SILENT_SUCCESS 0x00000001 49 | #define ND_OP_FLAG_READ_FENCE 0x00000002 50 | #define ND_OP_FLAG_SEND_AND_SOLICIT_EVENT 0x00000004 51 | #define ND_OP_FLAG_ALLOW_READ 0x00000008 52 | #define ND_OP_FLAG_ALLOW_WRITE 0x00000010 53 | #if NDVER >= ND_VERSION_2 54 | #define ND_OP_FLAG_INLINE 0x00000020 55 | #endif 56 | 57 | typedef struct _ND2_ADAPTER_INFO { 58 | ULONG InfoVersion; 59 | UINT16 VendorId; 60 | UINT16 DeviceId; 61 | UINT64 AdapterId; 62 | SIZE_T MaxRegistrationSize; 63 | SIZE_T MaxWindowSize; 64 | ULONG MaxInitiatorSge; 65 | ULONG MaxReceiveSge; 66 | ULONG MaxReadSge; 67 | ULONG MaxTransferLength; 68 | ULONG MaxInlineDataSize; 69 | ULONG MaxInboundReadLimit; 70 | ULONG MaxOutboundReadLimit; 71 | ULONG MaxReceiveQueueDepth; 72 | ULONG MaxInitiatorQueueDepth; 73 | ULONG MaxSharedReceiveQueueDepth; 74 | ULONG MaxCompletionQueueDepth; 75 | ULONG InlineRequestThreshold; 76 | ULONG LargeRequestThreshold; 77 | ULONG MaxCallerData; 78 | ULONG MaxCalleeData; 79 | ULONG AdapterFlags; 80 | } ND2_ADAPTER_INFO; 81 | 82 | typedef struct _ND2_ADAPTER_INFO32 { 83 | ULONG InfoVersion; 84 | UINT16 VendorId; 85 | UINT16 DeviceId; 86 | UINT64 AdapterId; 87 | ULONG MaxRegistrationSize; 88 | ULONG MaxWindowSize; 89 | ULONG MaxInitiatorSge; 90 | ULONG MaxReceiveSge; 91 | ULONG MaxReadSge; 92 | ULONG MaxTransferLength; 93 | ULONG MaxInlineDataSize; 94 | ULONG MaxInboundReadLimit; 95 | ULONG MaxOutboundReadLimit; 96 | ULONG MaxReceiveQueueDepth; 97 | ULONG MaxInitiatorQueueDepth; 98 | ULONG MaxSharedReceiveQueueDepth; 99 | ULONG MaxCompletionQueueDepth; 100 | ULONG InlineRequestThreshold; 101 | ULONG LargeRequestThreshold; 102 | ULONG MaxCallerData; 103 | ULONG MaxCalleeData; 104 | ULONG AdapterFlags; 105 | } ND2_ADAPTER_INFO32; 106 | 107 | typedef enum _ND2_REQUEST_TYPE { 108 | Nd2RequestTypeReceive, 109 | Nd2RequestTypeSend, 110 | Nd2RequestTypeBind, 111 | Nd2RequestTypeInvalidate, 112 | Nd2RequestTypeRead, 113 | Nd2RequestTypeWrite 114 | } ND2_REQUEST_TYPE; 115 | 116 | typedef struct _ND2_RESULT { 117 | HRESULT Status; 118 | ULONG BytesTransferred; 119 | VOID* QueuePairContext; 120 | VOID* RequestContext; 121 | ND2_REQUEST_TYPE RequestType; 122 | } ND2_RESULT; 123 | 124 | typedef struct _ND2_SGE { 125 | VOID* Buffer; 126 | ULONG BufferLength; 127 | UINT32 MemoryRegionToken; 128 | } ND2_SGE; 129 | 130 | #endif // _NDDEF_H_ 131 | -------------------------------------------------------------------------------- /src/ndutil/ndfrmwrk.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) Microsoft Corporation.All rights reserved. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | 7 | #pragma once 8 | 9 | namespace NetworkDirect 10 | { 11 | 12 | enum ND_NOTIFY_TYPE 13 | { 14 | ND_NOTIFY_PROVIDER_CHANGE, 15 | ND_NOTIFY_ADDR_CHANGE, 16 | ND_NOTIFY_MAX 17 | }; 18 | 19 | 20 | class Framework 21 | { 22 | // IOCP for provider and address changes. 23 | HANDLE m_hIocp; 24 | HANDLE m_hProviderChange; 25 | // Socket for address list change and address resolution. 26 | SOCKET m_Socket; 27 | OVERLAPPED m_Ov[ND_NOTIFY_MAX]; 28 | 29 | // Lock protecting the provider and address lists. 30 | CRITICAL_SECTION m_lock; 31 | 32 | List m_ProviderList; 33 | List
m_NdAddrList; 34 | List
m_NdV1AddrList; 35 | 36 | volatile LONG m_nRef; 37 | 38 | 39 | public: 40 | Framework(void); 41 | ~Framework(void); 42 | 43 | HRESULT Init(void); 44 | 45 | ULONG AddRef(void); 46 | ULONG Release(void); 47 | 48 | HRESULT QueryAddressList( 49 | _In_ DWORD flags, 50 | _Out_opt_bytecap_post_bytecount_(*pcbAddressList, *pcbAddressList) SOCKET_ADDRESS_LIST* pAddressList, 51 | _Inout_ SIZE_T* pcbAddressList 52 | ); 53 | 54 | HRESULT ResolveAddress( 55 | _In_bytecount_(cbRemoteAddress) const struct sockaddr* pRemoteAddress, 56 | _In_ SIZE_T cbRemoteAddress, 57 | _Out_bytecap_(*pcbLocalAddress) struct sockaddr* pLocalAddress, 58 | _Inout_ SIZE_T* pcbLocalAddress 59 | ); 60 | 61 | HRESULT CheckAddress( 62 | _In_bytecount_(cbAddress) const struct sockaddr* pAddress, 63 | _In_ SIZE_T cbAddress 64 | ); 65 | 66 | HRESULT OpenAdapter( 67 | _In_ REFIID iid, 68 | _In_bytecount_(cbAddress) const struct sockaddr* pAddress, 69 | _In_ SIZE_T cbAddress, 70 | _Deref_out_ VOID** ppIAdapter 71 | ); 72 | 73 | void FlushProvidersForUser(); 74 | 75 | private: 76 | static HRESULT ValidateAddress( 77 | _In_bytecount_(cbAddress) const struct sockaddr* pAddress, 78 | _In_ SIZE_T cbAddress 79 | ); 80 | 81 | static void CountAddresses( 82 | _In_ const List
& list, 83 | _Inout_ SIZE_T* pnV4, 84 | _Inout_ SIZE_T* pnV6 85 | ); 86 | 87 | static void 88 | BuildAddressList( 89 | _In_ Provider& prov, 90 | _In_ const SOCKET_ADDRESS_LIST& addrList, 91 | _Inout_ List
* pList 92 | ); 93 | 94 | static void CopyAddressList( 95 | _In_ const List
& list, 96 | _Inout_ SOCKET_ADDRESS_LIST* pAddressList, 97 | _Inout_ BYTE** ppBuf, 98 | _Inout_ SIZE_T* pcbBuf 99 | ); 100 | 101 | void ProcessUpdates(void); 102 | 103 | void ProcessProviderChange(void); 104 | void ProcessAddressChange(void); 105 | void FlushProviders(void); 106 | }; 107 | 108 | } // namespace NetworkDirect 109 | -------------------------------------------------------------------------------- /src/ndutil/ndprov.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) Microsoft Corporation.All rights reserved. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | 7 | #pragma once 8 | 9 | namespace NetworkDirect 10 | { 11 | 12 | typedef HRESULT 13 | (*DLLGETCLASSOBJECT)( 14 | REFCLSID rclsid, 15 | REFIID rrid, 16 | LPVOID* ppv 17 | ); 18 | 19 | typedef HRESULT 20 | (*DLLCANUNLOADNOW)(void); 21 | 22 | 23 | class Provider 24 | { 25 | friend class ListHelper; 26 | 27 | GUID m_Guid; 28 | LIST_ENTRY m_link; 29 | HMODULE m_hProvider; 30 | DLLGETCLASSOBJECT m_pfnDllGetClassObject; 31 | DLLCANUNLOADNOW m_pfnDllCanUnloadNow; 32 | WCHAR* m_Path; 33 | int m_Version; 34 | bool m_Active; 35 | 36 | public: 37 | Provider(int version); 38 | ~Provider(void); 39 | HRESULT Init(GUID& ProviderGuid); 40 | void MarkActive(void) { m_Active = true; } 41 | void MarkInactive(void) { m_Active = false; } 42 | bool IsActive(void) const { return m_Active; } 43 | int GetVersion(void) const { return m_Version; } 44 | 45 | // 46 | // GetClassObject and TryUnload require the caller to provide 47 | // proper serialization. 48 | // 49 | bool TryUnload(void); 50 | 51 | virtual HRESULT OpenAdapter( 52 | _In_ REFIID iid, 53 | _In_bytecount_(cbAddress) const struct sockaddr* pAddress, 54 | _In_ ULONG cbAddress, 55 | _Deref_out_ VOID** ppIAdapter 56 | ) PURE; 57 | 58 | virtual HRESULT 59 | QueryAddressList( 60 | _Out_opt_bytecap_post_bytecount_(*pcbAddressList, *pcbAddressList) 61 | SOCKET_ADDRESS_LIST* pAddressList, 62 | _Inout_ ULONG* pcbAddressList 63 | ) PURE; 64 | 65 | bool operator ==(const GUID& providerGuid) 66 | { 67 | return InlineIsEqualGUID(m_Guid, providerGuid) == TRUE; 68 | } 69 | 70 | protected: 71 | // 72 | // GetClassObject and TryUnload require the caller to provide 73 | // proper serialization. 74 | // 75 | HRESULT GetClassObject(_In_ const IID& iid, _Out_ void** ppInterface); 76 | }; 77 | 78 | 79 | class NdV1Provider : public Provider 80 | { 81 | public: 82 | NdV1Provider(); 83 | ~NdV1Provider(); 84 | 85 | HRESULT OpenAdapter( 86 | _In_ REFIID iid, 87 | _In_bytecount_(cbAddress) const struct sockaddr* pAddress, 88 | _In_ ULONG cbAddress, 89 | _Deref_out_ VOID** ppIAdapter 90 | ) override; 91 | 92 | HRESULT QueryAddressList( 93 | _Out_opt_bytecap_post_bytecount_(*pcbAddressList, *pcbAddressList) SOCKET_ADDRESS_LIST* pAddressList, 94 | _Inout_ ULONG* pcbAddressList 95 | ) override; 96 | 97 | private: 98 | HRESULT GetProvider(INDProvider** ppIProvider); 99 | }; 100 | 101 | 102 | class NdProvider : public Provider 103 | { 104 | public: 105 | NdProvider(); 106 | ~NdProvider(); 107 | 108 | HRESULT OpenAdapter( 109 | _In_ REFIID iid, 110 | _In_bytecount_(cbAddress) const struct sockaddr* pAddress, 111 | _In_ ULONG cbAddress, 112 | _Deref_out_ VOID** ppIAdapter 113 | ) override; 114 | 115 | HRESULT QueryAddressList( 116 | _Out_opt_bytecap_post_bytecount_(*pcbAddressList, *pcbAddressList) SOCKET_ADDRESS_LIST* pAddressList, 117 | _Inout_ ULONG* pcbAddressList 118 | ) override; 119 | }; 120 | 121 | } // namespace NetworkDirect 122 | -------------------------------------------------------------------------------- /src/ndutil/ndstatus.mc: -------------------------------------------------------------------------------- 1 | ;/*++ 2 | ; 3 | ;Copyright (c) Microsoft Corporation. All rights reserved. 4 | ; 5 | ;ndstatus.h - NetworkDirect Status Codes 6 | ; 7 | ;Status codes with a facility of System map to NTSTATUS codes 8 | ;of similar names. 9 | ; 10 | ;--*/ 11 | ; 12 | ;#ifndef _NDSTATUS_ 13 | ;#define _NDSTATUS_ 14 | ; 15 | ;#pragma once 16 | ; 17 | ; 18 | 19 | MessageIdTypedef=HRESULT 20 | 21 | SeverityNames=(Success=0x0:STATUS_SEVERITY_SUCCESS 22 | Informational=0x1:STATUS_SEVERITY_INFORMATIONAL 23 | Warning=0x2:STATUS_SEVERITY_WARNING 24 | Error=0x3:STATUS_SEVERITY_ERROR 25 | ) 26 | 27 | FacilityNames=(System=0x0 28 | ) 29 | 30 | MessageId=0x0000 Facility=System Severity=Success SymbolicName=ND_SUCCESS 31 | Language=English 32 | . 33 | 34 | MessageId=0x0102 Facility=System Severity=Success SymbolicName=ND_TIMEOUT 35 | Language=English 36 | . 37 | 38 | MessageId=0x0103 Facility=System Severity=Success SymbolicName=ND_PENDING 39 | Language=English 40 | . 41 | 42 | MessageId=0x0005 Facility=System Severity=Warning SymbolicName=ND_BUFFER_OVERFLOW 43 | Language=English 44 | . 45 | 46 | MessageId=0x0011 Facility=System Severity=Warning SymbolicName=ND_DEVICE_BUSY 47 | Language=English 48 | . 49 | 50 | MessageId=0x001A Facility=System Severity=Warning SymbolicName=ND_NO_MORE_ENTRIES 51 | Language=English 52 | . 53 | 54 | MessageId=0x0001 Facility=System Severity=Error SymbolicName=ND_UNSUCCESSFUL 55 | Language=English 56 | . 57 | 58 | MessageId=0x0005 Facility=System Severity=Error SymbolicName=ND_ACCESS_VIOLATION 59 | Language=English 60 | . 61 | 62 | MessageId=0x0008 Facility=System Severity=Error SymbolicName=ND_INVALID_HANDLE 63 | Language=English 64 | . 65 | 66 | MessageId=0x0010 Facility=System Severity=Error SymbolicName=ND_INVALID_DEVICE_REQUEST 67 | Language=English 68 | . 69 | 70 | MessageId=0x000D Facility=System Severity=Error SymbolicName=ND_INVALID_PARAMETER 71 | Language=English 72 | . 73 | 74 | MessageId=0x0017 Facility=System Severity=Error SymbolicName=ND_NO_MEMORY 75 | Language=English 76 | . 77 | 78 | MessageId=0x0030 Facility=System Severity=Error SymbolicName=ND_INVALID_PARAMETER_MIX 79 | Language=English 80 | . 81 | 82 | MessageId=0x003C Facility=System Severity=Error SymbolicName=ND_DATA_OVERRUN 83 | Language=English 84 | . 85 | 86 | MessageId=0x0043 Facility=System Severity=Error SymbolicName=ND_SHARING_VIOLATION 87 | Language=English 88 | . 89 | 90 | MessageId=0x009A Facility=System Severity=Error SymbolicName=ND_INSUFFICIENT_RESOURCES 91 | Language=English 92 | . 93 | 94 | MessageId=0x00A3 Facility=System Severity=Error SymbolicName=ND_DEVICE_NOT_READY 95 | Language=English 96 | . 97 | 98 | MessageId=0x00B5 Facility=System Severity=Error SymbolicName=ND_IO_TIMEOUT 99 | Language=English 100 | . 101 | 102 | MessageId=0x00BB Facility=System Severity=Error SymbolicName=ND_NOT_SUPPORTED 103 | Language=English 104 | . 105 | 106 | MessageId=0x00E5 Facility=System Severity=Error SymbolicName=ND_INTERNAL_ERROR 107 | Language=English 108 | . 109 | 110 | MessageId=0x00EF Facility=System Severity=Error SymbolicName=ND_INVALID_PARAMETER_1 111 | Language=English 112 | . 113 | 114 | MessageId=0x00F0 Facility=System Severity=Error SymbolicName=ND_INVALID_PARAMETER_2 115 | Language=English 116 | . 117 | 118 | MessageId=0x00F1 Facility=System Severity=Error SymbolicName=ND_INVALID_PARAMETER_3 119 | Language=English 120 | . 121 | 122 | MessageId=0x00F2 Facility=System Severity=Error SymbolicName=ND_INVALID_PARAMETER_4 123 | Language=English 124 | . 125 | 126 | MessageId=0x00F3 Facility=System Severity=Error SymbolicName=ND_INVALID_PARAMETER_5 127 | Language=English 128 | . 129 | 130 | MessageId=0x00F4 Facility=System Severity=Error SymbolicName=ND_INVALID_PARAMETER_6 131 | Language=English 132 | . 133 | 134 | MessageId=0x00F5 Facility=System Severity=Error SymbolicName=ND_INVALID_PARAMETER_7 135 | Language=English 136 | . 137 | 138 | MessageId=0x00F6 Facility=System Severity=Error SymbolicName=ND_INVALID_PARAMETER_8 139 | Language=English 140 | . 141 | 142 | MessageId=0x00F7 Facility=System Severity=Error SymbolicName=ND_INVALID_PARAMETER_9 143 | Language=English 144 | . 145 | 146 | MessageId=0x00F8 Facility=System Severity=Error SymbolicName=ND_INVALID_PARAMETER_10 147 | Language=English 148 | . 149 | 150 | MessageId=0x0120 Facility=System Severity=Error SymbolicName=ND_CANCELED 151 | Language=English 152 | . 153 | 154 | MessageId=0x013D Facility=System Severity=Error SymbolicName=ND_REMOTE_ERROR 155 | Language=English 156 | . 157 | 158 | MessageId=0x0141 Facility=System Severity=Error SymbolicName=ND_INVALID_ADDRESS 159 | Language=English 160 | . 161 | 162 | MessageId=0x0184 Facility=System Severity=Error SymbolicName=ND_INVALID_DEVICE_STATE 163 | Language=English 164 | . 165 | 166 | MessageId=0x0206 Facility=System Severity=Error SymbolicName=ND_INVALID_BUFFER_SIZE 167 | Language=English 168 | . 169 | 170 | MessageId=0x0209 Facility=System Severity=Error SymbolicName=ND_TOO_MANY_ADDRESSES 171 | Language=English 172 | . 173 | 174 | MessageId=0x020A Facility=System Severity=Error SymbolicName=ND_ADDRESS_ALREADY_EXISTS 175 | Language=English 176 | . 177 | 178 | MessageId=0x0236 Facility=System Severity=Error SymbolicName=ND_CONNECTION_REFUSED 179 | Language=English 180 | . 181 | 182 | MessageId=0x023A Facility=System Severity=Error SymbolicName=ND_CONNECTION_INVALID 183 | Language=English 184 | . 185 | 186 | MessageId=0x023B Facility=System Severity=Error SymbolicName=ND_CONNECTION_ACTIVE 187 | Language=English 188 | . 189 | 190 | MessageId=0x023C Facility=System Severity=Error SymbolicName=ND_NETWORK_UNREACHABLE 191 | Language=English 192 | . 193 | 194 | MessageId=0x023D Facility=System Severity=Error SymbolicName=ND_HOST_UNREACHABLE 195 | Language=English 196 | . 197 | 198 | MessageId=0x0241 Facility=System Severity=Error SymbolicName=ND_CONNECTION_ABORTED 199 | Language=English 200 | . 201 | 202 | MessageId=0x02B6 Facility=System Severity=Error SymbolicName=ND_DEVICE_REMOVED 203 | Language=English 204 | . 205 | 206 | ;#endif // _NDSTATUS_ 207 | -------------------------------------------------------------------------------- /src/ndutil/ndsupport.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) Microsoft Corporation.All rights reserved. 3 | // Licensed under the MIT License. 4 | // 5 | // Net Direct Helper Interface 6 | // 7 | 8 | #pragma once 9 | 10 | #ifndef _NETDIRECT_H_ 11 | #define _NETDIRECT_H_ 12 | 13 | #include 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" 18 | { 19 | #endif // __cplusplus 20 | 21 | #define ND_HELPER_API __stdcall 22 | 23 | 24 | // 25 | // Initialization 26 | // 27 | HRESULT ND_HELPER_API 28 | NdStartup( 29 | VOID 30 | ); 31 | 32 | HRESULT ND_HELPER_API 33 | NdCleanup( 34 | VOID 35 | ); 36 | 37 | VOID ND_HELPER_API 38 | NdFlushProviders( 39 | VOID 40 | ); 41 | 42 | // 43 | // Network capabilities 44 | // 45 | #define ND_QUERY_EXCLUDE_EMULATOR_ADDRESSES 0x00000001 46 | #define ND_QUERY_EXCLUDE_NDv1_ADDRESSES 0x00000002 47 | #define ND_QUERY_EXCLUDE_NDv2_ADDRESSES 0x00000004 48 | 49 | HRESULT ND_HELPER_API 50 | NdQueryAddressList( 51 | _In_ DWORD flags, 52 | _Out_opt_bytecap_post_bytecount_(*pcbAddressList, *pcbAddressList) SOCKET_ADDRESS_LIST* pAddressList, 53 | _Inout_ SIZE_T* pcbAddressList 54 | ); 55 | 56 | 57 | HRESULT ND_HELPER_API 58 | NdResolveAddress( 59 | _In_bytecount_(cbRemoteAddress) const struct sockaddr* pRemoteAddress, 60 | _In_ SIZE_T cbRemoteAddress, 61 | _Out_bytecap_(*pcbLocalAddress) struct sockaddr* pLocalAddress, 62 | _Inout_ SIZE_T* pcbLocalAddress 63 | ); 64 | 65 | 66 | HRESULT ND_HELPER_API 67 | NdCheckAddress( 68 | _In_bytecount_(cbAddress) const struct sockaddr* pAddress, 69 | _In_ SIZE_T cbAddress 70 | ); 71 | 72 | 73 | HRESULT ND_HELPER_API 74 | NdOpenAdapter( 75 | _In_ REFIID iid, 76 | _In_bytecount_(cbAddress) const struct sockaddr* pAddress, 77 | _In_ SIZE_T cbAddress, 78 | _Deref_out_ VOID** ppIAdapter 79 | ); 80 | 81 | 82 | HRESULT ND_HELPER_API 83 | NdOpenV1Adapter( 84 | _In_bytecount_(cbAddress) const struct sockaddr* pAddress, 85 | _In_ SIZE_T cbAddress, 86 | _Deref_out_ INDAdapter** ppIAdapter 87 | ); 88 | 89 | #ifdef __cplusplus 90 | } 91 | #endif // __cplusplus 92 | 93 | 94 | #endif // _NETDIRECT_H_ 95 | -------------------------------------------------------------------------------- /src/ndutil/ndutil.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) Microsoft Corporation.All rights reserved. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #pragma once 7 | 8 | namespace NetworkDirect 9 | { 10 | #ifndef ASSERT 11 | #define ASSERT Assert 12 | #if DBG 13 | #define ASSERT_BENIGN( exp ) (void)(!(exp)?OutputDebugStringA("Assertion Failed:" #exp "\n"),FALSE:TRUE) 14 | #else 15 | #define ASSERT_BENIGN( exp ) 16 | #endif // DBG 17 | #endif // ASSERT 18 | 19 | 20 | //--------------------------------------------------------- 21 | // Lock wrapper. 22 | // 23 | class Lock 24 | { 25 | CRITICAL_SECTION* m_pLock; 26 | 27 | public: 28 | Lock(CRITICAL_SECTION* pLock) { m_pLock = pLock; EnterCriticalSection(m_pLock); } 29 | 30 | _Releases_lock_(*this->m_pLock) 31 | ~Lock() { LeaveCriticalSection(m_pLock); } 32 | }; 33 | //--------------------------------------------------------- 34 | 35 | extern HANDLE ghHeap; 36 | } // namespace NetworkDirect 37 | -------------------------------------------------------------------------------- /src/ndutil/ndutil.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 15.0 7 | {6955ED94-3B21-4835-838A-A797AFF63183} 8 | Win32Proj 9 | ndutil 10 | 11 | 12 | 13 | $(MSBuildProjectName) 14 | *.lib 15 | 16 | 17 | 18 | 19 | StaticLibrary 20 | WindowsUserModeDriver10.0 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | Use 31 | _LIB;%(PreprocessorDefinitions) 32 | precomp.h 33 | .;$(OutIncludePath);%(AdditionalIncludeDirectories) 34 | $(IntDir)$(TargetName).pch 35 | 36 | 37 | 38 | 39 | if not exist $(OutIncludePath) mkdir $(OutIncludePath) 40 | Create Include folder 41 | 42 | 43 | robocopy .\ $(OutIncludePath)\ nddef.h ndioctl.h ndspi.h 44 | set rc=%errorlevel% 45 | if not %rc%==1 exit %rce% else exit 0 46 | 47 | 48 | Copy header files to include folder 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | Create 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | true 73 | $(OutIncludePath) 74 | true 75 | . 76 | 77 | 78 | 79 | 80 | 81 | 82 | MultiThreadedDebug 83 | 84 | 85 | 86 | 87 | 88 | MultiThreaded 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /src/ndutil/precomp.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) Microsoft Corporation.All rights reserved. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "assertutil.h" 12 | #include "ndutil.h" 13 | #include "list.h" 14 | #include "initguid.h" 15 | #include "ndspi.h" 16 | -------------------------------------------------------------------------------- /src/src.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | Win32 15 | 16 | 17 | Release 18 | Win32 19 | 20 | 21 | Debug 22 | x64 23 | 24 | 25 | Release 26 | x64 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/unittests/dirs.proj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/unittests/ndconn/NuGetAssetsLock.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | 6 | 7 | 8 | 9 | [1.0.0] 10 | imbNHw4hg7nnbLjFuagxR1oc7TJv058rCclt+DmqJrvYYKJ10R/tGuKjne1nq94y0FTM1zd4j9v9v9n5A9Va6w== 11 | vc150/1.0.0 12 | vc150.1.0.0.nupkg.sha512 13 | 14 | 15 | [1.0.3] 16 | SeyxBzNqK/4Mh0yqD7LrJKxKu7b8Bja+iJFivyUu09B45brU4gOwTYFO7hSgk6Ll+OCjl9pA5RZYmtyy2aU0DA== 17 | wk10/1.0.3 18 | wk10.1.0.3.nupkg.sha512 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/unittests/ndconn/ndconn.rc: -------------------------------------------------------------------------------- 1 | #define RC_FILE_TYPE VFT_APP 2 | #define RC_VERSION_INTERNAL_NAME "ndconn\0" 3 | #define RC_VERSION_ORIGINAL_FILE_NAME "ndconn.exe\0" 4 | #define RC_VERSION_FILE_DESCRIPTION "NetworkDirect connection scalability test\0" 5 | 6 | #include <..\examples\bldver.rc> 7 | -------------------------------------------------------------------------------- /src/unittests/ndconn/ndconn.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15.0 6 | {c4c6c8c3-5299-4a0c-a1f6-ede1a653f462} 7 | Win32Proj 8 | ndconn 9 | 10 | 11 | 12 | Application 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | _CONSOLE;%(PreprocessorDefinitions) 21 | 22 | 23 | Console 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/unittests/ndcq/NuGetAssetsLock.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | 6 | 7 | 8 | 9 | [1.0.0] 10 | imbNHw4hg7nnbLjFuagxR1oc7TJv058rCclt+DmqJrvYYKJ10R/tGuKjne1nq94y0FTM1zd4j9v9v9n5A9Va6w== 11 | vc150/1.0.0 12 | vc150.1.0.0.nupkg.sha512 13 | 14 | 15 | [1.0.3] 16 | SeyxBzNqK/4Mh0yqD7LrJKxKu7b8Bja+iJFivyUu09B45brU4gOwTYFO7hSgk6Ll+OCjl9pA5RZYmtyy2aU0DA== 17 | wk10/1.0.3 18 | wk10.1.0.3.nupkg.sha512 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/unittests/ndcq/ndcq.rc: -------------------------------------------------------------------------------- 1 | #define RC_FILE_TYPE VFT_APP 2 | #define RC_VERSION_INTERNAL_NAME "ndcq\0" 3 | #define RC_VERSION_ORIGINAL_FILE_NAME "ndcq.exe\0" 4 | #define RC_VERSION_FILE_DESCRIPTION "NetworkDirect completion queue test\0" 5 | 6 | #include <..\examples\bldver.rc> 7 | -------------------------------------------------------------------------------- /src/unittests/ndcq/ndcq.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15.0 6 | {64b7369b-6981-4f34-8f2a-f029bc61f01e} 7 | Win32Proj 8 | ndcq 9 | 10 | 11 | 12 | Application 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | _CONSOLE;%(PreprocessorDefinitions) 21 | 22 | 23 | Console 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/unittests/ndmemorytest/NuGetAssetsLock.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | 6 | 7 | 8 | 9 | [1.0.0] 10 | imbNHw4hg7nnbLjFuagxR1oc7TJv058rCclt+DmqJrvYYKJ10R/tGuKjne1nq94y0FTM1zd4j9v9v9n5A9Va6w== 11 | vc150/1.0.0 12 | vc150.1.0.0.nupkg.sha512 13 | 14 | 15 | [1.0.3] 16 | SeyxBzNqK/4Mh0yqD7LrJKxKu7b8Bja+iJFivyUu09B45brU4gOwTYFO7hSgk6Ll+OCjl9pA5RZYmtyy2aU0DA== 17 | wk10/1.0.3 18 | wk10.1.0.3.nupkg.sha512 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/unittests/ndmemorytest/ndconnectlistenerclosing.cpp: -------------------------------------------------------------------------------- 1 | // Copyright(c) Microsoft Corporation.All rights reserved. 2 | // Licensed under the MIT License. 3 | // 4 | // ndconnectlistenerclosing.cpp - Test connect to listener that is 5 | // closing/ has closed expecting ND_CONNECTION_REFUSED event 6 | 7 | 8 | #include "ndmemorytest.h" 9 | 10 | void NdConnectListenerClosingServer::RunTest( 11 | _In_ const struct sockaddr_in& v4Src, 12 | _In_ DWORD queueDepth, 13 | _In_ DWORD nSge 14 | ) 15 | { 16 | //prep 17 | NdTestBase::Init(v4Src); 18 | NdTestBase::CreateMR(); 19 | NdTestBase::RegisterDataBuffer(x_HdrLen + x_MaxXfer + 1, ND_MR_FLAG_ALLOW_LOCAL_WRITE); 20 | NdTestBase::CreateCQ(nSge); 21 | NdTestBase::CreateConnector(); 22 | NdTestBase::CreateQueuePair(queueDepth, nSge); 23 | 24 | //listen 25 | NdTestServerBase::CreateListener(); 26 | NdTestServerBase::Listen(v4Src); 27 | 28 | //close listener 29 | m_pListen->Release(); 30 | m_pListen = nullptr; 31 | //wait 5 seconds 32 | Sleep(5 * 1000); 33 | printf("NdConnListenClosing: passed\n"); 34 | } 35 | 36 | void NdConnectListenerClosingClient::RunTest( 37 | _In_ const struct sockaddr_in& v4Src, 38 | _In_ const struct sockaddr_in& v4Dst, 39 | _In_ DWORD queueDepth, 40 | _In_ DWORD nSge 41 | ) 42 | { 43 | //prep 44 | NdTestBase::Init(v4Src); 45 | NdTestBase::CreateMR(); 46 | NdTestBase::RegisterDataBuffer(x_MaxXfer, ND_MR_FLAG_ALLOW_LOCAL_WRITE, ND_SUCCESS); 47 | NdTestBase::CreateCQ(nSge, ND_SUCCESS); 48 | NdTestBase::CreateConnector(); 49 | NdTestBase::CreateQueuePair(queueDepth, nSge); 50 | 51 | //wait 1 second 52 | Sleep(1000); 53 | 54 | //connect shoud get connection refused, because the other side has closed the listener 55 | NdTestClientBase::Connect(v4Src, v4Dst, 1, 1, nullptr, 0, 56 | ND_CONNECTION_REFUSED, "Connecting to closed/closing listener should get connection refused"); 57 | printf("NdConnListenClosing: passed\n"); 58 | } 59 | -------------------------------------------------------------------------------- /src/unittests/ndmemorytest/ndconnrejectclose.cpp: -------------------------------------------------------------------------------- 1 | // Copyright(c) Microsoft Corporation.All rights reserved. 2 | // Licensed under the MIT License. 3 | // 4 | // ndconnectlistenerclosing.cpp - Test client reject connection 5 | // after server accepts connection. Client get ND_SUCCESS, and 6 | // server get ND_CONNECTION_REFUSED in CQ 7 | 8 | 9 | #include "ndmemorytest.h" 10 | 11 | void NdConnRejectCloseServer::RunTest( 12 | _In_ const struct sockaddr_in& v4Src, 13 | _In_ DWORD queueDepth, 14 | _In_ DWORD nSge 15 | ) 16 | { 17 | //prep 18 | NdTestBase::Init(v4Src); 19 | NdTestBase::CreateMR(); 20 | NdTestBase::RegisterDataBuffer(x_HdrLen + x_MaxXfer, ND_MR_FLAG_ALLOW_LOCAL_WRITE); 21 | NdTestBase::CreateCQ(nSge); 22 | NdTestBase::CreateConnector(); 23 | NdTestBase::CreateQueuePair(queueDepth, nSge); 24 | 25 | //accept connection 26 | NdTestServerBase::CreateListener(); 27 | NdTestServerBase::Listen(v4Src); 28 | NdTestServerBase::GetConnectionRequest(); 29 | 30 | //expect connection refused, because the other side has rejected the connection 31 | NdTestServerBase::Accept(0, 0, nullptr, 0, ND_CONNECTION_REFUSED, "Expecting ND_CONNECTION_REFUSED in CQ"); 32 | 33 | //tear down 34 | NdTestBase::Shutdown(); 35 | printf("%S: passed\n", m_testName); 36 | } 37 | 38 | void NdConnRejectClient::RunTest( 39 | _In_ const struct sockaddr_in& v4Src, 40 | _In_ const struct sockaddr_in& v4Dst, 41 | _In_ DWORD queueDepth, 42 | _In_ DWORD nSge 43 | ) 44 | { 45 | //prep 46 | NdTestBase::Init(v4Src); 47 | NdTestBase::CreateMR(); 48 | NdTestBase::RegisterDataBuffer(x_MaxXfer, ND_MR_FLAG_ALLOW_LOCAL_WRITE); 49 | NdTestBase::CreateCQ(nSge, ND_SUCCESS); 50 | NdTestBase::CreateConnector(); 51 | NdTestBase::CreateQueuePair(queueDepth, nSge); 52 | 53 | //connect 54 | NdTestClientBase::Connect(v4Src, v4Dst, 1, 1); 55 | 56 | //rejcts connection 57 | NdTestBase::Reject(nullptr, 0); 58 | 59 | //Wait 5 seconds 60 | Sleep(5 * 1000); 61 | 62 | //tear down 63 | NdTestBase::Shutdown(); 64 | printf("NdConnReject: passed\n"); 65 | } 66 | 67 | void NdConnCloseClient::RunTest( 68 | _In_ const struct sockaddr_in& v4Src, 69 | _In_ const struct sockaddr_in& v4Dst, 70 | _In_ DWORD queueDepth, 71 | _In_ DWORD nSge 72 | ) 73 | { 74 | //prep 75 | NdTestBase::Init(v4Src); 76 | NdTestBase::CreateMR(); 77 | NdTestBase::RegisterDataBuffer(x_MaxXfer, ND_MR_FLAG_ALLOW_LOCAL_WRITE, ND_SUCCESS); 78 | NdTestBase::CreateCQ(nSge, ND_SUCCESS); 79 | NdTestBase::CreateConnector(); 80 | NdTestBase::CreateQueuePair(queueDepth, nSge); 81 | 82 | //connect 83 | NdTestClientBase::Connect(v4Src, v4Dst, 1, 1); 84 | 85 | //close connector by releasing it 86 | HRESULT hr = m_pConnector->Release(); 87 | LogIfErrorExit(hr, ND_SUCCESS, "Closing connector should return ND_SCUCESS", __LINE__); 88 | m_pConnector = nullptr; 89 | //Wait 5 seconds 90 | Sleep(5 * 1000); 91 | printf("NdConnClose: passed\n"); 92 | } -------------------------------------------------------------------------------- /src/unittests/ndmemorytest/nddualconnection.cpp: -------------------------------------------------------------------------------- 1 | // Copyright(c) Microsoft Corporation.All rights reserved. 2 | // Licensed under the MIT License. 3 | // 4 | // ndconnectlistenerclosing.cpp - Test connect when another connect 5 | // event is in progress. Client should get ND_CONNECTION_ACTIVE event. 6 | 7 | 8 | #include "ndmemorytest.h" 9 | 10 | void NdDualConnectionServer::RunTest( 11 | _In_ const struct sockaddr_in& v4Src, 12 | _In_ DWORD queueDepth, 13 | _In_ DWORD nSge 14 | ) 15 | { 16 | //prep 17 | NdTestBase::Init(v4Src); 18 | NdTestBase::CreateMR(); 19 | NdTestBase::RegisterDataBuffer(x_HdrLen + x_MaxXfer, ND_MR_FLAG_ALLOW_LOCAL_WRITE); 20 | NdTestBase::CreateCQ(nSge); 21 | NdTestBase::CreateConnector(); 22 | NdTestBase::CreateQueuePair(queueDepth, nSge); 23 | 24 | //establish connection 25 | NdTestServerBase::CreateListener(); 26 | NdTestServerBase::Listen(v4Src); 27 | NdTestServerBase::GetConnectionRequest(); 28 | 29 | //accept connection, expecting to be refused, since the peer has corrupted it 30 | NdTestServerBase::Accept(1, 1, nullptr, 0, STATUS_CONNECTION_REFUSED, 31 | "Expecting remote peer to refuse connection"); 32 | printf("NdDualConnection: passed\n"); 33 | } 34 | 35 | void NdDualConnectionClient::RunTest( 36 | _In_ const struct sockaddr_in& v4Src, 37 | _In_ const struct sockaddr_in& v4Dst, 38 | _In_ DWORD queueDepth, 39 | _In_ DWORD nSge 40 | ) 41 | { 42 | //prep 43 | NdTestBase::Init(v4Src); 44 | NdTestBase::CreateMR(); 45 | NdTestBase::RegisterDataBuffer(x_MaxXfer, ND_MR_FLAG_ALLOW_LOCAL_WRITE); 46 | NdTestBase::CreateCQ(nSge, ND_SUCCESS); 47 | NdTestBase::CreateConnector(); 48 | NdTestBase::CreateQueuePair(queueDepth, nSge); 49 | 50 | //do first connection 51 | NdTestClientBase::Connect(v4Src, v4Dst, 1, 1); 52 | 53 | //try another connection, should get ND_CONNECTION_ACTIVE 54 | HRESULT hr = m_pConnector->Bind( 55 | reinterpret_cast(&v4Src), 56 | sizeof(v4Src) 57 | ); 58 | LogIfErrorExit(hr, STATUS_ADDRESS_ALREADY_ASSOCIATED, 59 | "Another connection is in progress, current connection should get ND_CONNECTION_ACTIVE", __LINE__); 60 | 61 | //wait 5 seconds 62 | Sleep(5 * 1000); 63 | 64 | hr = m_pConnector->Connect(m_pQp, reinterpret_cast(&v4Dst), sizeof(v4Dst), 65 | 0, 0, nullptr, 0, &m_Ov); 66 | if (hr == ND_PENDING) 67 | { 68 | hr = m_pConnector->GetOverlappedResult(&m_Ov, TRUE); 69 | } 70 | LogIfErrorExit(hr, ND_CONNECTION_ACTIVE,"Unexpected event, expected ND_CONNECTION_ACTIVE", __LINE__); 71 | printf("NdDualConnection: passed\n"); 72 | } 73 | -------------------------------------------------------------------------------- /src/unittests/ndmemorytest/ndduallisten.cpp: -------------------------------------------------------------------------------- 1 | // Copyright(c) Microsoft Corporation.All rights reserved. 2 | // Licensed under the MIT License. 3 | // 4 | // nddualisten.cpp - Open two adaptors listening to the same endpoint, 5 | // second listen should fail 6 | 7 | #include "ndmemorytest.h" 8 | #include 9 | 10 | void NdDualListenServer::RunTest( 11 | _In_ const struct sockaddr_in& v4Src, 12 | _In_ DWORD queueDepth, 13 | _In_ DWORD nSge 14 | ) 15 | { 16 | //prep 17 | NdTestBase::Init(v4Src); 18 | NdTestServerBase::CreateListener(); 19 | NdTestServerBase::Listen(v4Src); 20 | 21 | //open another adaptor listening to the same endpoint 22 | IND2Adapter* pAdapter; 23 | IND2Listener* pListen; 24 | HRESULT hr = NdOpenAdapter( 25 | IID_IND2Adapter, 26 | reinterpret_cast(&v4Src), 27 | sizeof(v4Src), 28 | reinterpret_cast(&pAdapter) 29 | ); 30 | if (FAILED(hr)) 31 | { 32 | LOG_FAILURE_HRESULT_AND_EXIT(hr, L"Failed to open adapter", __LINE__); 33 | } 34 | 35 | hr = m_pAdapter->CreateListener( 36 | IID_IND2Listener, 37 | m_hAdapterFile, 38 | reinterpret_cast(&pListen) 39 | ); 40 | if (FAILED(hr)) 41 | { 42 | LOG_FAILURE_HRESULT_AND_EXIT(hr, L"Failed to create listener", __LINE__); 43 | } 44 | 45 | hr = m_pListen->Bind( 46 | reinterpret_cast(&v4Src), 47 | sizeof(v4Src) 48 | ); 49 | //second bind should fail 50 | LogIfErrorExit(hr, STATUS_ADDRESS_ALREADY_ASSOCIATED, "Second listen should fail", __LINE__); 51 | 52 | hr = m_pListen->Listen(0); 53 | if (hr == ND_SUCCESS) 54 | { 55 | LogErrorExit("Expected second listen to fail, but succeeded\n", __LINE__); 56 | } 57 | 58 | printf("NdDualListen: passed\n"); 59 | } 60 | 61 | void NdDualListenClient::RunTest( 62 | _In_ const struct sockaddr_in& /*v4Src*/, 63 | _In_ const struct sockaddr_in& /*v4Dst*/, 64 | _In_ DWORD /*queueDepth*/, 65 | _In_ DWORD /*nSge*/ 66 | ) 67 | { 68 | printf("NdDualListen is server-only test\n"); 69 | } 70 | -------------------------------------------------------------------------------- /src/unittests/ndmemorytest/ndinvalidip.cpp: -------------------------------------------------------------------------------- 1 | // Copyright(c) Microsoft Corporation.All rights reserved. 2 | // Licensed under the MIT License. 3 | // 4 | // ndinvalidip.cpp - Test connector using invalid IP address 5 | 6 | 7 | #include "ndmemorytest.h" 8 | #include 9 | 10 | void NdInvalidIPServer::RunTest( 11 | _In_ const struct sockaddr_in& /*v4Src*/, 12 | _In_ DWORD /*queueDepth*/, 13 | _In_ DWORD /*nSge*/ 14 | ) 15 | { 16 | printf("NdInvalidIP is client-only test\n"); 17 | } 18 | 19 | void NdInvalidIPClient::RunTest( 20 | _In_ const struct sockaddr_in& v4Src, 21 | _In_ const struct sockaddr_in& v4Dst, 22 | _In_ DWORD queueDepth, 23 | _In_ DWORD nSge 24 | ) 25 | { 26 | // prep 27 | NdTestBase::Init(v4Src); 28 | NdTestBase::CreateMR(); 29 | NdTestBase::RegisterDataBuffer(x_MaxXfer, ND_MR_FLAG_ALLOW_LOCAL_WRITE); 30 | NdTestBase::CreateCQ(nSge, ND_SUCCESS); 31 | NdTestBase::CreateConnector(); 32 | NdTestBase::CreateQueuePair(queueDepth, nSge); 33 | 34 | // connect to invalid ip address (address has been changed outside) 35 | NdTestClientBase::Connect(v4Src, v4Dst, 0, 0, nullptr, 0, STATUS_BAD_NETWORK_NAME, 36 | "Expecting STATUS_BAD_NETWORK_NAME when destination IP is invalid"); 37 | printf("NdInvalidIP: passed\n"); 38 | } 39 | -------------------------------------------------------------------------------- /src/unittests/ndmemorytest/ndinvalidreadwrite.cpp: -------------------------------------------------------------------------------- 1 | // Copyright(c) Microsoft Corporation.All rights reserved. 2 | // Licensed under the MIT License. 3 | // 4 | // ndinvalidip.cpp - Test read/write to invalidates memory window 5 | 6 | 7 | #include "ndmemorytest.h" 8 | 9 | void NdInvalidReadServer::RunTest( 10 | _In_ const struct sockaddr_in& v4Src, 11 | _In_ DWORD /*queueDepth*/, 12 | _In_ DWORD /*nSge*/ 13 | ) 14 | { 15 | //prep 16 | NdTestBase::Init(v4Src); 17 | NdTestBase::CreateMR(); 18 | NdTestBase::RegisterDataBuffer(x_HdrLen + x_MaxXfer, ND_MR_FLAG_ALLOW_LOCAL_WRITE); 19 | 20 | NdTestBase::CreateCQ(2); 21 | NdTestBase::CreateConnector(); 22 | NdTestBase::CreateQueuePair(1, 1); 23 | NdTestServerBase::CreateListener(); 24 | NdTestServerBase::Listen(v4Src); 25 | NdTestServerBase::GetConnectionRequest(); 26 | 27 | // Pre-post receive request. 28 | ND2_SGE Sge; 29 | const MemoryWindowDesc* ndmd = reinterpret_cast(m_Buf); 30 | Sge.Buffer = m_Buf; 31 | Sge.BufferLength = sizeof(*ndmd); 32 | Sge.MemoryRegionToken = m_pMr->GetLocalToken(); 33 | NdTestBase::PostReceive(&Sge, 1); 34 | 35 | //accept connection 36 | NdTestServerBase::Accept(1, 1); 37 | 38 | //Get result for the pre-posted receive 39 | NdTestBase::WaitForCompletion(ND_SUCCESS); 40 | //get remote address and token 41 | UINT64 addr = ndmd->base; 42 | UINT32 token = ndmd->token; 43 | 44 | //Wait 5 seconds for memory window to be invalidated 45 | Sleep(5 * 1000); 46 | 47 | //try to read from the remote MW, should get error 48 | Sge.BufferLength = x_HdrLen + x_MaxXfer + 1; 49 | NdTestBase::Read(&Sge, 1, addr, token, 0); 50 | //wait for read completion, expecting error 51 | NdTestBase::WaitForCompletion( 52 | ND_ACCESS_VIOLATION, 53 | "Read from memory window when it's being invalidated should result in error" 54 | ); 55 | 56 | //tear down 57 | NdTestBase::Shutdown(); 58 | printf("NdInvalidRead: passed\n"); 59 | } 60 | 61 | void NdInvalidWriteServer::RunTest( 62 | _In_ const struct sockaddr_in& v4Src, 63 | _In_ DWORD /*queueDepth*/, 64 | _In_ DWORD /*nSge*/ 65 | ) 66 | { 67 | //prep 68 | NdTestBase::Init(v4Src); 69 | NdTestBase::CreateMR(); 70 | NdTestBase::RegisterDataBuffer(x_MaxXfer, ND_MR_FLAG_ALLOW_LOCAL_WRITE); 71 | 72 | NdTestBase::CreateCQ(2); 73 | NdTestBase::CreateConnector(); 74 | NdTestBase::CreateQueuePair(1, 1); 75 | NdTestServerBase::CreateListener(); 76 | NdTestServerBase::Listen(v4Src); 77 | NdTestServerBase::GetConnectionRequest(); 78 | 79 | // Pre-post receive request. 80 | ND2_SGE Sge; 81 | const MemoryWindowDesc* ndmd = reinterpret_cast(m_Buf); 82 | Sge.Buffer = m_Buf; 83 | Sge.BufferLength = sizeof(*ndmd); 84 | Sge.MemoryRegionToken = m_pMr->GetLocalToken(); 85 | NdTestBase::PostReceive(&Sge, 1); 86 | 87 | //accept connection 88 | NdTestServerBase::Accept(1, 1); 89 | 90 | //Get result for the pre-posted receive 91 | NdTestBase::WaitForCompletion(ND_SUCCESS); 92 | 93 | //get remote address and token 94 | UINT64 addr = ndmd->base; 95 | UINT32 token = ndmd->token; 96 | 97 | //Wait 5 seconds for memory window to be invalidated 98 | Sleep(5 * 1000); 99 | 100 | //try to write to the remote MW, should get error 101 | Sge.BufferLength = x_HdrLen + x_MaxXfer + 1; 102 | NdTestBase::Write(&Sge, 1, addr, token, 0); 103 | //wait for write completion,expecting error 104 | NdTestBase::WaitForCompletion( 105 | ND_ACCESS_VIOLATION, 106 | "Write to memory window when it's being invalidated should result in error" 107 | ); 108 | 109 | //tear down 110 | NdTestBase::Shutdown(); 111 | printf("NdInvalidWrite: passed\n"); 112 | } 113 | 114 | 115 | void NdInvalidReadWriteClient::RunTest( 116 | _In_ const struct sockaddr_in& v4Src, 117 | _In_ const struct sockaddr_in& v4Dst, 118 | _In_ DWORD /*queueDepth*/, 119 | _In_ DWORD /*nSge*/ 120 | ) 121 | { 122 | //prep 123 | NdTestBase::Init(v4Src); 124 | NdTestBase::CreateMR(); 125 | NdTestBase::RegisterDataBuffer(x_HdrLen + x_MaxXfer, 126 | ND_MR_FLAG_ALLOW_REMOTE_READ | ND_MR_FLAG_ALLOW_REMOTE_WRITE); 127 | 128 | NdTestBase::CreateCQ(2, ND_SUCCESS); 129 | NdTestBase::CreateConnector(); 130 | NdTestBase::CreateQueuePair(2, 1); 131 | NdTestClientBase::Connect(v4Src, v4Dst, 1, 1); 132 | NdTestClientBase::CompleteConnect(); 133 | NdTestBase::CreateMW(); 134 | NdTestBase::Bind(x_MaxXfer, ND_OP_FLAG_ALLOW_WRITE | ND_OP_FLAG_ALLOW_READ); 135 | 136 | //create memory descriptor 137 | MemoryWindowDesc* ndmd = (MemoryWindowDesc*)m_Buf; 138 | ndmd->base = (UINT64)m_Buf; 139 | ndmd->token = m_pMw->GetRemoteToken(); 140 | ndmd->length = x_MaxXfer; 141 | 142 | //prepare Sge 143 | ND2_SGE Sge; 144 | Sge.Buffer = ndmd; 145 | Sge.BufferLength = sizeof(*ndmd); 146 | Sge.MemoryRegionToken = m_pMr->GetLocalToken(); 147 | 148 | //post receive to capture connection teardown 149 | NdTestBase::PostReceive(nullptr, 0); 150 | 151 | //send it over 152 | NdTestBase::Send(&Sge, 1, 0); 153 | 154 | //wait for send completion 155 | NdTestBase::WaitForCompletion(); 156 | 157 | //invalidate memory window 158 | NdTestBase::InvalidateMW(); 159 | 160 | //wait for invalidation completion 161 | NdTestBase::WaitForCompletion(); 162 | 163 | //wait for receive be flushed 164 | NdTestBase::WaitForCompletion( 165 | ND_CANCELED, 166 | "Receive should have been cancelled because the peer is writing to invalid MW" 167 | ); 168 | 169 | printf("%S: passed\n", m_testName); 170 | } 171 | -------------------------------------------------------------------------------- /src/unittests/ndmemorytest/ndlargeprivatedata.cpp: -------------------------------------------------------------------------------- 1 | // Copyright(c) Microsoft Corporation.All rights reserved. 2 | // Licensed under the MIT License. 3 | // 4 | // ndlargeprivatedata.cpp - Test Connect/Accept with the length of private 5 | // data exceeding the limit of the hardware, verify with ND_INVALID_BUFFER_SIZE 6 | 7 | #include "ndmemorytest.h" 8 | 9 | void NdLargePrivateDataServer::RunTest( 10 | _In_ const struct sockaddr_in& v4Src, 11 | _In_ DWORD queueDepth, 12 | _In_ DWORD nSge 13 | ) 14 | { 15 | //prep 16 | NdTestBase::Init(v4Src); 17 | NdTestBase::CreateMR(); 18 | NdTestBase::RegisterDataBuffer(x_HdrLen + x_MaxXfer, ND_MR_FLAG_ALLOW_LOCAL_WRITE); 19 | 20 | NdTestBase::CreateCQ(nSge); 21 | NdTestBase::CreateConnector(); 22 | NdTestBase::CreateQueuePair(queueDepth, nSge); 23 | NdTestServerBase::CreateListener(); 24 | NdTestServerBase::Listen(v4Src); 25 | NdTestServerBase::GetConnectionRequest(); 26 | 27 | // Pre-post receive request. 28 | NdTestBase::PostReceive(nullptr, 0); 29 | 30 | //get the max supported length of private data on 31 | ND2_ADAPTER_INFO adaptorInfo; 32 | adaptorInfo.InfoVersion = ND_VERSION_2; 33 | ULONG infoSize = sizeof(ND2_ADAPTER_INFO); 34 | HRESULT hr = m_pAdapter->Query(&adaptorInfo, &infoSize); 35 | LogIfErrorExit(hr, ND_SUCCESS, "Querying dataptor info failed!", __LINE__); 36 | DWORD maxCalleeData = adaptorInfo.MaxCalleeData; 37 | 38 | 39 | // give it the correct private data size/buffer size, but larger than what the hardware can support 40 | void* data = new (std::nothrow) char[maxCalleeData + 1LL]; 41 | NdTestServerBase::Accept(1, 1, data, maxCalleeData + 1, 42 | ND_INVALID_BUFFER_SIZE, "Expecting Access violation when data exceeds MaxCalleeData"); 43 | delete[] data; 44 | 45 | //try with just enough data 46 | data = new (std::nothrow) char[maxCalleeData]; 47 | NdTestServerBase::Accept(1, 1, data, maxCalleeData, 48 | ND_SUCCESS, "Expecting ND_SUCCESS when privata data size is just MaxCalleeData"); 49 | 50 | //Get result for the pre-posted receive 51 | NdTestBase::WaitForCompletion(ND_SUCCESS); 52 | 53 | //tear down 54 | NdTestBase::Shutdown(); 55 | delete[] data; 56 | printf("NdLargePrivateData: passed\n"); 57 | } 58 | 59 | void NdLargePrivateDataClient::RunTest( 60 | _In_ const struct sockaddr_in& v4Src, 61 | _In_ const struct sockaddr_in& v4Dst, 62 | _In_ DWORD queueDepth, 63 | _In_ DWORD nSge 64 | ) 65 | { 66 | //prep 67 | NdTestBase::Init(v4Src); 68 | NdTestBase::CreateMR(); 69 | NdTestBase::RegisterDataBuffer(x_MaxXfer, ND_MR_FLAG_ALLOW_REMOTE_READ | ND_MR_FLAG_ALLOW_REMOTE_WRITE); 70 | 71 | NdTestBase::CreateCQ(nSge, ND_SUCCESS); 72 | NdTestBase::CreateConnector(); 73 | NdTestBase::CreateQueuePair(queueDepth, nSge); 74 | 75 | //get the max supported length of private data 76 | ND2_ADAPTER_INFO adaptorInfo; 77 | adaptorInfo.InfoVersion = ND_VERSION_2; 78 | ULONG infoSize = sizeof(ND2_ADAPTER_INFO); 79 | HRESULT hr = m_pAdapter->Query(&adaptorInfo, &infoSize); 80 | LogIfErrorExit(hr, ND_SUCCESS, "Querying dataptor info failed!", __LINE__); 81 | DWORD maxCallerData = adaptorInfo.MaxCallerData; 82 | 83 | //attempt to connect with larger private data 84 | const void* data = new (std::nothrow) char[maxCallerData + 1LL]; 85 | NdTestClientBase::Connect(v4Src, v4Dst, 1, 1, data, maxCallerData + 1, 86 | ND_INVALID_BUFFER_SIZE, "Expecting Access violation when data size is bigger than maxCallerData"); 87 | delete[] data; 88 | 89 | //try with just enough data, should get ND_SUCCESS 90 | data = new (std::nothrow) char[maxCallerData]; 91 | NdTestClientBase::Connect(v4Src, v4Dst, 1, 1, data, maxCallerData, 92 | ND_SUCCESS, "Expecting ND_SUCCESS when data size is just maxCallerData"); 93 | delete[] data; 94 | 95 | //complete connect event 96 | NdTestClientBase::CompleteConnect(); 97 | 98 | //send a packet to signal tear down 99 | NdTestBase::Send(nullptr, 0, 0); 100 | NdTestBase::WaitForCompletion(); 101 | 102 | //tear down 103 | NdTestBase::Shutdown(); 104 | printf("NdLargePrivateData: passed\n"); 105 | } 106 | -------------------------------------------------------------------------------- /src/unittests/ndmemorytest/ndlargeqpdepth.cpp: -------------------------------------------------------------------------------- 1 | // Copyright(c) Microsoft Corporation.All rights reserved. 2 | // Licensed under the MIT License. 3 | // 4 | // ndlargeprivatedata.cpp - Test creation of QP that exceeds 5 | // maxReceiveQueueDepth advertised, CreateQueuePair() should fail 6 | 7 | 8 | #include "ndmemorytest.h" 9 | 10 | void NdLargeQPDepthServer::RunTest( 11 | _In_ const struct sockaddr_in& v4Src, 12 | _In_ DWORD queueDepth, 13 | _In_ DWORD /*nSge*/ 14 | ) 15 | { 16 | //prep 17 | NdTestBase::Init(v4Src); 18 | NdTestBase::CreateCQ(2); 19 | 20 | //get the max supported depth QP 21 | ND2_ADAPTER_INFO adaptorInfo; 22 | adaptorInfo.InfoVersion = ND_VERSION_2; 23 | ULONG infoSize = sizeof(ND2_ADAPTER_INFO); 24 | HRESULT hr = m_pAdapter->Query(&adaptorInfo, &infoSize); 25 | LogIfErrorExit(hr, ND_SUCCESS, "Querying dataptor info failed!", __LINE__); 26 | 27 | //create QP with depth exceeding max-supported depth 28 | queueDepth = adaptorInfo.MaxReceiveQueueDepth + 1; 29 | 30 | hr = m_pAdapter->CreateQueuePair( 31 | IID_IND2QueuePair, 32 | m_pCq, 33 | m_pCq, 34 | nullptr, 35 | queueDepth, 36 | 1, 37 | 2, 38 | 2, 39 | 0, 40 | reinterpret_cast(&m_pQp) 41 | ); 42 | 43 | LogIfNoErrorExit(hr, "Receiving queue depth exceeding max value should error!", __LINE__); 44 | printf("NdLargeQPDepth: passed\n"); 45 | } 46 | 47 | void NdLargeQPDepthClient::RunTest( 48 | _In_ const struct sockaddr_in& /* v4Src */, 49 | _In_ const struct sockaddr_in& /* v4Dst */, 50 | _In_ DWORD /* queueDepth */, 51 | _In_ DWORD /* nSge */ 52 | ) 53 | { 54 | printf("NdLargeQPDepth is server-only\n"); 55 | } 56 | -------------------------------------------------------------------------------- /src/unittests/ndmemorytest/ndmemorytest.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15.0 6 | {ffd1d086-e7e1-4506-8957-4e083ef2acb5} 7 | Win32Proj 8 | ndMemoryTest 9 | ndmemorytest 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | _CONSOLE;%(PreprocessorDefinitions) 19 | StdCall 20 | 21 | 22 | Console 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | Application 49 | Unicode 50 | 51 | 52 | -------------------------------------------------------------------------------- /src/unittests/ndmemorytest/ndmrderegister.cpp: -------------------------------------------------------------------------------- 1 | // Copyright(c) Microsoft Corporation.All rights reserved. 2 | // Licensed under the MIT License. 3 | // 4 | // ndmrderegister.cpp - Test memory region deregisteration when memory 5 | // window is bound to it 6 | 7 | #include "ndmemorytest.h" 8 | 9 | //test cases for Memory region deregisteration when memory window is bound to it 10 | void NdMRDeregisterServer::RunTest( 11 | _In_ const struct sockaddr_in& v4Src, 12 | _In_ DWORD queueDepth, 13 | _In_ DWORD nSge 14 | ) 15 | { 16 | //prep 17 | NdTestBase::Init(v4Src); 18 | NdTestBase::CreateMR(); 19 | NdTestBase::RegisterDataBuffer(x_HdrLen + x_MaxXfer, ND_MR_FLAG_ALLOW_LOCAL_WRITE); 20 | NdTestBase::CreateCQ(nSge); 21 | NdTestBase::CreateConnector(); 22 | NdTestBase::CreateQueuePair(queueDepth, nSge); 23 | 24 | //connect 25 | NdTestServerBase::CreateListener(); 26 | NdTestServerBase::Listen(v4Src); 27 | NdTestServerBase::GetConnectionRequest(); 28 | 29 | //accept connection 30 | NdTestServerBase::Accept(1, 1); 31 | 32 | //create MW and bind it to memory 33 | NdTestBase::CreateMW(); 34 | NdTestBase::Bind(x_MaxXfer, 0); 35 | 36 | //this call should fail, because there's still memory window bound to it 37 | HRESULT hr = m_pMr->Deregister(&m_Ov); 38 | LogIfErrorExit(hr, ND_DEVICE_BUSY, 39 | "Deregistering memory region with memory window bound it should get ND_DEVICE_BUSY!", __LINE__); 40 | 41 | //tear down 42 | NdTestBase::Shutdown(); 43 | printf("NdMRDeregister: passed\n"); 44 | } 45 | 46 | void NdMRDeregisterClient::RunTest( 47 | _In_ const struct sockaddr_in& v4Src, 48 | _In_ const struct sockaddr_in& v4Dst, 49 | _In_ DWORD queueDepth, 50 | _In_ DWORD nSge 51 | ) 52 | { 53 | //prep 54 | NdTestBase::Init(v4Src); 55 | NdTestBase::CreateMR(); 56 | NdTestBase::RegisterDataBuffer(x_MaxXfer, ND_MR_FLAG_ALLOW_LOCAL_WRITE); 57 | NdTestBase::CreateCQ(nSge, ND_SUCCESS); 58 | NdTestBase::CreateConnector(); 59 | NdTestBase::CreateQueuePair(queueDepth, nSge); 60 | 61 | //connect 62 | NdTestClientBase::Connect(v4Src, v4Dst, 1, 1); 63 | NdTestClientBase::CompleteConnect(); 64 | 65 | //sleep 5 seconds to let the other end deregister memory 66 | Sleep(5 * 1000); 67 | 68 | NdTestBase::Shutdown(); 69 | printf("NdMRDeregister: passed\n"); 70 | } -------------------------------------------------------------------------------- /src/unittests/ndmemorytest/ndmrinvalidbuffer.cpp: -------------------------------------------------------------------------------- 1 | // Copyright(c) Microsoft Corporation.All rights reserved. 2 | // Licensed under the MIT License. 3 | // 4 | // ndmrinvalidbuffer.cpp - Test register memory with buffer = nullptr(server), 5 | // or buffer size= 0(client), expect Get ND_ACCESS_VIOLATION 6 | 7 | 8 | #include "ndmemorytest.h" 9 | 10 | //Try register memory with buffer = nullptr(server), or buffer size= 0(client) 11 | //expect Get ND_ACCESS_VIOLATION 12 | 13 | void NdMRInvalidBufferServer::RunTest( 14 | _In_ const struct sockaddr_in& v4Src, 15 | _In_ DWORD queueDepth, 16 | _In_ DWORD nSge 17 | ) 18 | 19 | { 20 | //prep 21 | NdTestBase::Init(v4Src); 22 | NdTestBase::CreateMR(); 23 | 24 | //register buffer = nullptr 25 | HRESULT hr = m_pMr->Register( 26 | nullptr, 27 | 0, 28 | ND_MR_FLAG_ALLOW_LOCAL_WRITE, 29 | &m_Ov 30 | ); 31 | if (hr == ND_PENDING) 32 | { 33 | hr = m_pMr->GetOverlappedResult(&m_Ov, TRUE); 34 | } 35 | 36 | LogIfErrorExit(hr, ND_INVALID_PARAMETER, "register empty buffer should error", __LINE__); 37 | printf("NdMRInvalidBuffer: passed\n"); 38 | } 39 | 40 | //client will try the buffersizeRegister( 62 | m_Buf, 63 | 0, 64 | ND_MR_FLAG_ALLOW_LOCAL_WRITE, 65 | &m_Ov 66 | ); 67 | if (hr == ND_PENDING) 68 | { 69 | hr = m_pMr->GetOverlappedResult(&m_Ov, TRUE); 70 | } 71 | 72 | //expect error message 73 | LogIfErrorExit(hr, ND_INVALID_BUFFER_SIZE, "register buffer of size 10 given size 20 should error", __LINE__); 74 | printf("NdMRInvalidBuffer: passed\n"); 75 | } 76 | -------------------------------------------------------------------------------- /src/unittests/ndmemorytest/ndoverreadwrite.cpp: -------------------------------------------------------------------------------- 1 | // Copyright(c) Microsoft Corporation.All rights reserved. 2 | // Licensed under the MIT License. 3 | // 4 | // ndoverreadwrite.cpp - Test server read/write more than 5 | // the size of its buffer 6 | 7 | 8 | #include "ndmemorytest.h" 9 | 10 | void NdOverReadServer::RunTest( 11 | _In_ const struct sockaddr_in& v4Src, 12 | _In_ DWORD /*queueDepth*/, 13 | _In_ DWORD /*nSge*/ 14 | ) 15 | { 16 | //prep 17 | NdTestBase::Init(v4Src); 18 | NdTestBase::CreateMR(); 19 | NdTestBase::RegisterDataBuffer(x_HdrLen + x_MaxXfer + 1, ND_MR_FLAG_ALLOW_LOCAL_WRITE); 20 | 21 | NdTestBase::CreateCQ(2); 22 | NdTestBase::CreateConnector(); 23 | NdTestBase::CreateQueuePair(1, 1); 24 | NdTestServerBase::CreateListener(); 25 | NdTestServerBase::Listen(v4Src); 26 | NdTestServerBase::GetConnectionRequest(); 27 | 28 | // Pre-post receive request. 29 | ND2_SGE Sge; 30 | const MemoryWindowDesc* ndmd = reinterpret_cast(m_Buf); 31 | Sge.Buffer = m_Buf; 32 | Sge.BufferLength = sizeof(*ndmd); 33 | Sge.MemoryRegionToken = m_pMr->GetLocalToken(); 34 | NdTestBase::PostReceive(&Sge, 1); 35 | 36 | //accept connection 37 | NdTestServerBase::Accept(1, 1); 38 | 39 | //Get result for the pre-posted receive 40 | NdTestBase::WaitForCompletion(ND_SUCCESS); 41 | UINT64 addr = ndmd->base; 42 | UINT32 token = ndmd->token; 43 | 44 | //prepare buffer to read/write 45 | 46 | //read more than the remote peer has 47 | Sge.BufferLength = x_HdrLen + x_MaxXfer + 1; 48 | 49 | //read 50 | NdTestBase::Read(&Sge, 1, addr, token, 0); 51 | 52 | //wait for read completion 53 | NdTestBase::WaitForCompletion( 54 | ND_ACCESS_VIOLATION, 55 | "Read from memory region more its size should get error ND_ACCESS_VIOLATION" 56 | ); 57 | 58 | //tear down 59 | NdTestBase::Shutdown(); 60 | printf("NdOverRead: passed\n"); 61 | } 62 | 63 | void NdOverWriteServer::RunTest( 64 | _In_ const struct sockaddr_in& v4Src, 65 | _In_ DWORD /*queueDepth*/, 66 | _In_ DWORD /*nSge*/ 67 | ) 68 | { 69 | 70 | //prep 71 | NdTestBase::Init(v4Src); 72 | NdTestBase::CreateMR(); 73 | NdTestBase::RegisterDataBuffer(x_HdrLen + x_MaxXfer + 1, ND_MR_FLAG_ALLOW_LOCAL_WRITE); 74 | 75 | NdTestBase::CreateCQ(2); 76 | NdTestBase::CreateConnector(); 77 | NdTestBase::CreateQueuePair(1, 1); 78 | NdTestServerBase::CreateListener(); 79 | NdTestServerBase::Listen(v4Src); 80 | NdTestServerBase::GetConnectionRequest(); 81 | 82 | // Pre-post receive request. 83 | ND2_SGE Sge; 84 | const MemoryWindowDesc* ndmd = reinterpret_cast(m_Buf); 85 | Sge.Buffer = m_Buf; 86 | Sge.BufferLength = sizeof(*ndmd); 87 | Sge.MemoryRegionToken = m_pMr->GetLocalToken(); 88 | NdTestBase::PostReceive(&Sge, 1); 89 | 90 | //accept connection 91 | NdTestServerBase::Accept(1, 1); 92 | 93 | //Get result for the pre-posted receive 94 | NdTestBase::WaitForCompletion(ND_SUCCESS); 95 | UINT64 addr = ndmd->base; 96 | UINT32 token = ndmd->token; 97 | 98 | //prepare buffer to read/write 99 | 100 | //write more than the remote peer has 101 | Sge.BufferLength = x_HdrLen + x_MaxXfer + 1; 102 | 103 | //write 104 | NdTestBase::Write(&Sge, 1, addr, token, 0); 105 | 106 | //wait for write completion 107 | NdTestBase::WaitForCompletion( 108 | ND_ACCESS_VIOLATION, 109 | "Write to memory region when it's being invalidated should result in error" 110 | ); 111 | 112 | NdTestBase::Shutdown(); 113 | printf("NdOverWrite: passed\n"); 114 | } 115 | 116 | void NdOverReadWriteClient::RunTest( 117 | _In_ const struct sockaddr_in& v4Src, 118 | _In_ const struct sockaddr_in& v4Dst, 119 | _In_ DWORD /*queueDepth*/, 120 | _In_ DWORD /*nSge*/ 121 | ) 122 | { 123 | //prep 124 | NdTestBase::Init(v4Src); 125 | NdTestBase::CreateMR(); 126 | NdTestBase::RegisterDataBuffer(x_MaxXfer, ND_MR_FLAG_ALLOW_REMOTE_READ | ND_MR_FLAG_ALLOW_REMOTE_WRITE); 127 | 128 | NdTestBase::CreateCQ(2, ND_SUCCESS); 129 | NdTestBase::CreateConnector(); 130 | NdTestBase::CreateQueuePair(2, 1); 131 | NdTestClientBase::Connect(v4Src, v4Dst, 1, 1); 132 | NdTestClientBase::CompleteConnect(); 133 | NdTestBase::CreateMW(); 134 | NdTestBase::Bind(x_MaxXfer, ND_OP_FLAG_ALLOW_WRITE | ND_OP_FLAG_ALLOW_READ); 135 | 136 | //prepare memory descriptor 137 | MemoryWindowDesc* ndmd = (MemoryWindowDesc*)m_Buf; 138 | ndmd->base = (UINT64)m_Buf; 139 | ndmd->token = m_pMw->GetRemoteToken(); 140 | ndmd->length = x_MaxXfer; 141 | 142 | //prepare Sge 143 | ND2_SGE Sge; 144 | Sge.Buffer = ndmd; 145 | Sge.BufferLength = sizeof(*ndmd); 146 | Sge.MemoryRegionToken = m_pMr->GetLocalToken(); 147 | 148 | //send it over 149 | NdTestBase::Send(&Sge, 1, 0); 150 | 151 | //Wait for Send completion 152 | NdTestBase::WaitForCompletion(); 153 | 154 | //wait 5 seconds 155 | Sleep(5 * 1000); 156 | 157 | //tear down 158 | NdTestBase::Shutdown(); 159 | printf("%S: passed\n", m_testName); 160 | } 161 | -------------------------------------------------------------------------------- /src/unittests/ndmemorytest/ndqpmaxall.cpp: -------------------------------------------------------------------------------- 1 | // Copyright(c) Microsoft Corporation.All rights reserved. 2 | // Licensed under the MIT License. 3 | // 4 | // ndqpmaxall.cpp - Test QP creation with all parameters set to 5 | // maximum advertised, shoud get no error message 6 | 7 | 8 | #include "ndmemorytest.h" 9 | 10 | void NdQPMaxAllServer::RunTest( 11 | _In_ const struct sockaddr_in& v4Src, 12 | _In_ DWORD queueDepth, 13 | _In_ DWORD nSge 14 | ) 15 | { 16 | //prep 17 | NdTestBase::Init(v4Src); 18 | NdTestBase::CreateMR(); 19 | NdTestBase::RegisterDataBuffer(x_HdrLen + x_MaxXfer, ND_MR_FLAG_ALLOW_LOCAL_WRITE); 20 | NdTestBase::CreateCQ(nSge); 21 | NdTestBase::CreateConnector(); 22 | 23 | //get the max supported depth QP, and receive Sgn number 24 | ND2_ADAPTER_INFO adaptorInfo; 25 | adaptorInfo.InfoVersion = ND_VERSION_2; 26 | ULONG infoSize = sizeof(ND2_ADAPTER_INFO); 27 | HRESULT hr = m_pAdapter->Query(&adaptorInfo, &infoSize); 28 | LogIfErrorExit(hr, ND_SUCCESS, "Querying dataptor info failed!", __LINE__); 29 | queueDepth = adaptorInfo.MaxReceiveQueueDepth; 30 | nSge = adaptorInfo.MaxReceiveSge; 31 | 32 | //create queue pair, expecting success 33 | NdTestBase::CreateQueuePair(queueDepth, adaptorInfo.MaxInitiatorQueueDepth, nSge, adaptorInfo.MaxInitiatorSge); 34 | 35 | //tear down 36 | NdTestBase::Shutdown(); 37 | printf("NdQpMax: passed\n"); 38 | } 39 | 40 | void NdQPMaxAllClient::RunTest( 41 | _In_ const struct sockaddr_in& /* v4Src */, 42 | _In_ const struct sockaddr_in& /*v4Dst*/, 43 | _In_ DWORD /*queueDepth*/, 44 | _In_ DWORD /*nSge*/ 45 | ) 46 | { 47 | //do nothing on the client 48 | printf("NdQpMax is server-only test\n"); 49 | } 50 | -------------------------------------------------------------------------------- /src/unittests/ndmemorytest/ndreceiveconnectorclosed.cpp: -------------------------------------------------------------------------------- 1 | // Copyright(c) Microsoft Corporation.All rights reserved. 2 | // Licensed under the MIT License. 3 | // 4 | // ndreceiveconnectorclosed.cpp - Test receive with connector closed 5 | // - Post a receive on local CP and close remote connector 6 | // - Verify a CQ notification with ND_CANCELED is generated 7 | 8 | 9 | #include "ndmemorytest.h" 10 | 11 | void NdReceiveConnectorClosedServer::RunTest( 12 | _In_ const struct sockaddr_in& v4Src, 13 | _In_ DWORD queueDepth, 14 | _In_ DWORD nSge 15 | ) 16 | { 17 | //prep 18 | NdTestBase::Init(v4Src); 19 | NdTestBase::CreateMR(); 20 | NdTestBase::RegisterDataBuffer(x_HdrLen + x_MaxXfer + 1, ND_MR_FLAG_ALLOW_LOCAL_WRITE, ND_SUCCESS); 21 | NdTestBase::CreateCQ(nSge); 22 | NdTestBase::CreateConnector(); 23 | NdTestBase::CreateQueuePair(queueDepth, nSge); 24 | NdTestServerBase::CreateListener(); 25 | NdTestServerBase::Listen(v4Src); 26 | NdTestServerBase::GetConnectionRequest(); 27 | 28 | //prepare Sge 29 | ND2_SGE* Sge = new ND2_SGE[nSge]; 30 | Sge[0].Buffer = m_Buf; 31 | Sge[0].BufferLength = x_HdrLen + x_MaxXfer; 32 | Sge[0].MemoryRegionToken = m_pMr->GetLocalToken(); 33 | 34 | //Post receive - should succeed 35 | NdTestBase::PostReceive(Sge, 1); 36 | 37 | //Accept connection 38 | NdTestServerBase::Accept(1, 1); 39 | 40 | //sleep 5 seconds to let client close the remote connector 41 | Sleep(5 * 1000); 42 | 43 | //expect 1 message for the posted receive 44 | WaitForCompletion(ND_CANCELED); 45 | 46 | //tear down 47 | NdTestBase::Shutdown(); 48 | printf("NdReceiveConnClosed: passed\n"); 49 | } 50 | 51 | void NdReceiveConnectorClosedClient::RunTest( 52 | _In_ const struct sockaddr_in& v4Src, 53 | _In_ const struct sockaddr_in& v4Dst, 54 | _In_ DWORD queueDepth, 55 | _In_ DWORD nSge 56 | ) 57 | { 58 | //prep 59 | NdTestBase::Init(v4Src); 60 | NdTestBase::CreateMR(); 61 | NdTestBase::RegisterDataBuffer(x_MaxXfer, ND_MR_FLAG_ALLOW_LOCAL_WRITE, ND_SUCCESS); 62 | NdTestBase::CreateCQ(nSge, ND_SUCCESS); 63 | NdTestBase::CreateConnector(); 64 | NdTestBase::CreateQueuePair(queueDepth, nSge); 65 | 66 | //connect 67 | NdTestClientBase::Connect(v4Src, v4Dst, 1, 1); 68 | NdTestClientBase::CompleteConnect(); 69 | 70 | //shutdown immediately 71 | NdTestBase::Shutdown(); 72 | printf("NdReceiveConnClosed: passed\n"); 73 | } 74 | -------------------------------------------------------------------------------- /src/unittests/ndmemorytest/ndreceiveflushqp.cpp: -------------------------------------------------------------------------------- 1 | // Copyright(c) Microsoft Corporation.All rights reserved. 2 | // Licensed under the MIT License. 3 | // 4 | // ndreceiveflushqp.cpp - Test Flush QP 5 | // - Post two receives on local QP and flush the QP. 6 | // - Verify one CQ notification is generated 7 | // - Verify the next two receive requests completed with cancelled status 8 | // due to QP flush 9 | 10 | 11 | #include "ndmemorytest.h" 12 | 13 | void NdReceiveFlushQPServer::RunTest( 14 | _In_ const struct sockaddr_in& v4Src, 15 | _In_ DWORD queueDepth, 16 | _In_ DWORD nSge 17 | ) 18 | { 19 | //prep 20 | NdTestBase::Init(v4Src); 21 | NdTestBase::CreateMR(); 22 | NdTestBase::RegisterDataBuffer(x_HdrLen + x_MaxXfer + 1, ND_MR_FLAG_ALLOW_LOCAL_WRITE, ND_SUCCESS); 23 | NdTestBase::CreateCQ(nSge); 24 | NdTestBase::CreateConnector(); 25 | NdTestBase::CreateQueuePair(queueDepth, nSge); 26 | NdTestServerBase::CreateListener(); 27 | NdTestServerBase::Listen(v4Src); 28 | 29 | // Pre-post 2 receive requests. 30 | NdTestBase::PostReceive(nullptr, 0); 31 | NdTestBase::PostReceive(nullptr, 0); 32 | 33 | //flush QP 34 | NdTestBase::FlushQP(); 35 | 36 | //Expect 1 generated notification due to flush 37 | ND2_RESULT pResult[2]; 38 | HRESULT hr = m_pCq->Notify(ND_CQ_NOTIFY_ANY, &m_Ov); 39 | if (hr == ND_PENDING) 40 | { 41 | hr = m_pCq->GetOverlappedResult(&m_Ov, TRUE); 42 | } 43 | 44 | //expecting two results,both being ND_CANCELED 45 | int numResults = m_pCq->GetResults(pResult, 2); 46 | if (numResults != 2) { 47 | printf("Expecting 2 results, but only getting %d", numResults); 48 | LogErrorExit("Error in CompletionQueue::GetResults", __LINE__); 49 | } 50 | else 51 | { 52 | LogIfErrorExit(pResult[0].Status, ND_CANCELED, 53 | "Expecting receive cancelled due to QP flush", __LINE__); 54 | LogIfErrorExit(pResult[1].Status, ND_CANCELED, 55 | "Expecting receive cancelled due to QP flush", __LINE__); 56 | } 57 | NdTestBase::Shutdown(); 58 | printf("NdReceiveFlushQP: passed\n"); 59 | } 60 | 61 | void NdReceiveFlushQPClient::RunTest( 62 | _In_ const struct sockaddr_in& /*v4Src*/, 63 | _In_ const struct sockaddr_in& /*v4Dst*/, 64 | _In_ DWORD /*queueDepth*/, 65 | _In_ DWORD /*nSge*/ 66 | ) 67 | { 68 | //do nothing on the client 69 | printf("NdReceiveFlushQP is server-only\n"); 70 | } 71 | 72 | -------------------------------------------------------------------------------- /src/unittests/ndmemorytest/ndsendnoreceive.cpp: -------------------------------------------------------------------------------- 1 | // Copyright(c) Microsoft Corporation.All rights reserved. 2 | // Licensed under the MIT License. 3 | // 4 | // ndsendnoreceive.cpp - Test send with no posted recv 5 | // - Post a send on local QP without posting receive on remote QP. 6 | // - Verify a CQ notification is generated 7 | 8 | 9 | #include "ndmemorytest.h" 10 | #include 11 | 12 | void NdSendNoReceiveServer::RunTest( 13 | _In_ const struct sockaddr_in& v4Src, 14 | _In_ DWORD queueDepth, 15 | _In_ DWORD nSge 16 | ) 17 | { 18 | //prep 19 | NdTestBase::Init(v4Src); 20 | NdTestBase::CreateMR(); 21 | NdTestBase::RegisterDataBuffer(x_HdrLen + x_MaxXfer + 1, ND_MR_FLAG_ALLOW_LOCAL_WRITE, ND_SUCCESS); 22 | NdTestBase::CreateCQ(nSge); 23 | NdTestBase::CreateConnector(); 24 | NdTestBase::CreateQueuePair(queueDepth, nSge); 25 | NdTestServerBase::CreateListener(); 26 | NdTestServerBase::Listen(v4Src); 27 | NdTestServerBase::GetConnectionRequest(); 28 | 29 | // accept connection 30 | NdTestServerBase::Accept(1, 1); 31 | 32 | // sleep 5 seconds 33 | Sleep(5 * 1000); 34 | 35 | // we are not expecting any CQ notification, because a connection is not established 36 | ND2_RESULT ndResult; 37 | if (m_pCq->GetResults(&ndResult, 1) != 0) 38 | { 39 | LOG_FAILURE_AND_EXIT(L"Unexpected completion\n", __LINE__); 40 | } 41 | 42 | //tear down 43 | NdTestBase::Shutdown(); 44 | printf("NdSendNoReceive: passed\n"); 45 | } 46 | 47 | 48 | void NdSendNoReceiveClient::RunTest( 49 | _In_ const struct sockaddr_in& v4Src, 50 | _In_ const struct sockaddr_in& v4Dst, 51 | _In_ DWORD queueDepth, 52 | _In_ DWORD nSge 53 | ) 54 | { 55 | //prep 56 | NdTestBase::Init(v4Src); 57 | NdTestBase::CreateMR(); 58 | NdTestBase::RegisterDataBuffer(x_MaxXfer, ND_MR_FLAG_ALLOW_LOCAL_WRITE, ND_SUCCESS); 59 | NdTestBase::CreateCQ(nSge, ND_SUCCESS); 60 | NdTestBase::CreateConnector(); 61 | NdTestBase::CreateQueuePair(queueDepth, nSge); 62 | NdTestClientBase::Connect(v4Src, v4Dst, 1, 1); 63 | NdTestClientBase::CompleteConnect(); 64 | 65 | //prepare Sge 66 | ND2_SGE Sge[1]; 67 | Sge[0].Buffer = m_Buf; 68 | Sge[0].BufferLength = x_MaxXfer; 69 | Sge[0].MemoryRegionToken = m_pMr->GetLocalToken(); 70 | 71 | //send it over 72 | NdTestBase::Send(Sge, 1, 0); 73 | 74 | // There's no receive posted on the other side, the test case should not 75 | // wait indefinitely because we should get a notification in the CQ. 76 | 77 | //expect failure to of the send in the completion queue 78 | NdTestBase::WaitForCompletion(ND_IO_TIMEOUT); 79 | NdTestBase::Shutdown(); 80 | printf("NdSendNoReceive: passed\n"); 81 | } 82 | -------------------------------------------------------------------------------- /src/unittests/ndmemorytest/ndwriteviolation.cpp: -------------------------------------------------------------------------------- 1 | // Copyright(c) Microsoft Corporation.All rights reserved. 2 | // Licensed under the MIT License. 3 | // 4 | // ndwriteviolation.cpp - Test invalid write 5 | 6 | 7 | #include "ndmemorytest.h" 8 | 9 | void NdWriteViolationServer::RunTest( 10 | _In_ const struct sockaddr_in& v4Src, 11 | _In_ DWORD /*queueDepth*/, 12 | _In_ DWORD /*nSge*/ 13 | ) 14 | { 15 | //prep 16 | NdTestBase::Init(v4Src); 17 | NdTestBase::CreateMR(); 18 | NdTestBase::RegisterDataBuffer(x_HdrLen + x_MaxXfer, ND_MR_FLAG_ALLOW_LOCAL_WRITE); 19 | 20 | NdTestBase::CreateCQ(2); 21 | NdTestBase::CreateConnector(); 22 | NdTestBase::CreateQueuePair(1, 1); 23 | NdTestServerBase::CreateListener(); 24 | NdTestServerBase::Listen(v4Src); 25 | NdTestServerBase::GetConnectionRequest(); 26 | 27 | // Pre-post receive request. 28 | ND2_SGE Sge; 29 | const MemoryWindowDesc* ndmd = reinterpret_cast(m_Buf); 30 | Sge.Buffer = m_Buf; 31 | Sge.BufferLength = sizeof(*ndmd); 32 | Sge.MemoryRegionToken = m_pMr->GetLocalToken(); 33 | NdTestBase::PostReceive(&Sge, 1); 34 | 35 | //accept connection 36 | NdTestServerBase::Accept(1, 1); 37 | 38 | //Get result for the pre-posted receive 39 | NdTestBase::WaitForCompletion(ND_SUCCESS); 40 | UINT64 addr = ndmd->base; 41 | UINT32 token = ndmd->token; 42 | 43 | //try to write to the remote MW, should get error 44 | Sge.BufferLength = x_MaxXfer; 45 | 46 | //write 47 | NdTestBase::Write(&Sge, 1, addr, token, 0); 48 | 49 | //wait for write completion 50 | NdTestBase::WaitForCompletion( 51 | ND_ACCESS_VIOLATION, 52 | "Write to nonwriteable memory region should result in error" 53 | ); 54 | 55 | //tear down 56 | NdTestBase::Shutdown(); 57 | printf("NdWriteViolation: passed\n"); 58 | } 59 | 60 | void NdWriteViolationClient::RunTest( 61 | _In_ const struct sockaddr_in& v4Src, 62 | _In_ const struct sockaddr_in& v4Dst, 63 | _In_ DWORD /*queueDepth*/, 64 | _In_ DWORD /*nSge*/ 65 | ) 66 | { 67 | //prep 68 | NdTestBase::Init(v4Src); 69 | NdTestBase::CreateMR(); 70 | NdTestBase::RegisterDataBuffer(x_MaxXfer, ND_MR_FLAG_ALLOW_LOCAL_WRITE); 71 | 72 | NdTestBase::CreateCQ(2, ND_SUCCESS); 73 | NdTestBase::CreateConnector(); 74 | NdTestBase::CreateQueuePair(2, 1); 75 | NdTestClientBase::Connect(v4Src, v4Dst, 1, 1); 76 | NdTestClientBase::CompleteConnect(); 77 | NdTestBase::CreateMW(); 78 | NdTestBase::Bind(x_MaxXfer, ND_OP_FLAG_ALLOW_READ); 79 | 80 | //prepare memory descriptor 81 | MemoryWindowDesc* ndmd = (MemoryWindowDesc*)m_Buf; 82 | ndmd->base = (UINT64)m_Buf; 83 | ndmd->token = m_pMw->GetRemoteToken(); 84 | ndmd->length = x_MaxXfer; 85 | 86 | //prepare Sge 87 | ND2_SGE Sge; 88 | Sge.Buffer = ndmd; 89 | Sge.BufferLength = sizeof(*ndmd); 90 | Sge.MemoryRegionToken = m_pMr->GetLocalToken(); 91 | 92 | //post receive so we'll know when the peer fails 93 | NdTestBase::PostReceive(nullptr, 0); 94 | 95 | //send it over 96 | NdTestBase::Send(&Sge, 1, 0); 97 | 98 | //wait for send completion 99 | NdTestBase::WaitForCompletion(); 100 | 101 | //expect posted receive to be flushed(ND_CANCELLED) 102 | NdTestBase::WaitForCompletion( 103 | ND_CANCELED, 104 | "Receive should have been cancelled because the peer is writing to a non-writable MW" 105 | ); 106 | 107 | //tear down 108 | NdTestBase::Shutdown(); 109 | printf("NdWriteViolation: passed\n"); 110 | } 111 | -------------------------------------------------------------------------------- /src/unittests/ndmpic/NuGetAssetsLock.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | 6 | 7 | 8 | 9 | [1.0.0] 10 | imbNHw4hg7nnbLjFuagxR1oc7TJv058rCclt+DmqJrvYYKJ10R/tGuKjne1nq94y0FTM1zd4j9v9v9n5A9Va6w== 11 | vc150/1.0.0 12 | vc150.1.0.0.nupkg.sha512 13 | 14 | 15 | [1.0.3] 16 | SeyxBzNqK/4Mh0yqD7LrJKxKu7b8Bja+iJFivyUu09B45brU4gOwTYFO7hSgk6Ll+OCjl9pA5RZYmtyy2aU0DA== 17 | wk10/1.0.3 18 | wk10.1.0.3.nupkg.sha512 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/unittests/ndmpic/ndmpic.rc: -------------------------------------------------------------------------------- 1 | #define RC_FILE_TYPE VFT_APP 2 | #define RC_VERSION_INTERNAL_NAME "ndmpic\0" 3 | #define RC_VERSION_ORIGINAL_FILE_NAME "ndmpic.exe\0" 4 | #define RC_VERSION_FILE_DESCRIPTION "NetworkDirect MS-MPI connection emulator test\0" 5 | 6 | #include <..\examples\bldver.rc> 7 | -------------------------------------------------------------------------------- /src/unittests/ndmpic/ndmpic.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15.0 6 | {bf2f3362-1023-4f95-a8fb-68fe7f34049d} 7 | Win32Proj 8 | ndmpic 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | _CONSOLE;%(PreprocessorDefinitions) 18 | 19 | 20 | Console 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | Application 31 | Unicode 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/unittests/ndmval/NuGetAssetsLock.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | 6 | 7 | 8 | 9 | [1.0.0] 10 | imbNHw4hg7nnbLjFuagxR1oc7TJv058rCclt+DmqJrvYYKJ10R/tGuKjne1nq94y0FTM1zd4j9v9v9n5A9Va6w== 11 | vc150/1.0.0 12 | vc150.1.0.0.nupkg.sha512 13 | 14 | 15 | [1.0.3] 16 | SeyxBzNqK/4Mh0yqD7LrJKxKu7b8Bja+iJFivyUu09B45brU4gOwTYFO7hSgk6Ll+OCjl9pA5RZYmtyy2aU0DA== 17 | wk10/1.0.3 18 | wk10.1.0.3.nupkg.sha512 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/unittests/ndmval/ndmval.rc: -------------------------------------------------------------------------------- 1 | #define RC_FILE_TYPE VFT_APP 2 | #define RC_VERSION_INTERNAL_NAME "ndmval\0" 3 | #define RC_VERSION_ORIGINAL_FILE_NAME "ndmval.exe\0" 4 | #define RC_VERSION_FILE_DESCRIPTION "NetworkDirect memory validation test\0" 5 | 6 | #include <..\examples\bldver.rc> 7 | -------------------------------------------------------------------------------- /src/unittests/ndmval/ndmval.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15.0 6 | {591adbbe-9343-4393-920b-2c969e7afeda} 7 | Win32Proj 8 | ndmval 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | _CONSOLE;%(PreprocessorDefinitions) 18 | 19 | 20 | Console 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | Application 31 | Unicode 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/unittests/ndmw/NuGetAssetsLock.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | 6 | 7 | 8 | 9 | [1.0.0] 10 | imbNHw4hg7nnbLjFuagxR1oc7TJv058rCclt+DmqJrvYYKJ10R/tGuKjne1nq94y0FTM1zd4j9v9v9n5A9Va6w== 11 | vc150/1.0.0 12 | vc150.1.0.0.nupkg.sha512 13 | 14 | 15 | [1.0.3] 16 | SeyxBzNqK/4Mh0yqD7LrJKxKu7b8Bja+iJFivyUu09B45brU4gOwTYFO7hSgk6Ll+OCjl9pA5RZYmtyy2aU0DA== 17 | wk10/1.0.3 18 | wk10.1.0.3.nupkg.sha512 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/unittests/ndmw/ndmw.rc: -------------------------------------------------------------------------------- 1 | #define RC_FILE_TYPE VFT_APP 2 | #define RC_VERSION_INTERNAL_NAME "ndmw\0" 3 | #define RC_VERSION_ORIGINAL_FILE_NAME "ndmw.exe\0" 4 | #define RC_VERSION_FILE_DESCRIPTION "NetworkDirect memory window test\0" 5 | 6 | #include <..\examples\bldver.rc> 7 | -------------------------------------------------------------------------------- /src/unittests/ndmw/ndmw.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15.0 6 | {6707722c-4371-48a4-a3a2-40d126059690} 7 | Win32Proj 8 | ndmw 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | _CONSOLE;%(PreprocessorDefinitions) 18 | 19 | 20 | Console 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | Application 31 | Unicode 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/unittests/unittests.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | ..\..\examples;..\..\examples\ndtestutil\;$(OutIncludePath);%(AdditionalIncludeDirectories) 8 | 9 | 10 | kernel32.lib;ws2_32.lib;uuid.lib;Iphlpapi.lib;%(AdditionalDependencies) 11 | $(OutDir)\..\ndutil\;%(AdditionalLibraryDirectories) 12 | 13 | 14 | ..;%(AdditionalIncludeDirectories) 15 | 16 | 17 | 18 | 19 | unittests 20 | *.exe 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | --------------------------------------------------------------------------------