├── .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 |
--------------------------------------------------------------------------------