[CSHARP-4287] Socket.IOControl handles Windows-specific control codes and is not supported on this platform. Created: 01/Aug/22  Updated: 28/Oct/23  Resolved: 11/Aug/22

Status: Closed
Project: C# Driver
Component/s: None
Affects Version/s: None
Fix Version/s: 2.18.0

Type: Improvement Priority: Unknown
Reporter: Kaio Henrique Assignee: James Kovacs
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: PNG File image-2022-07-31-21-37-13-912.png    
Backwards Compatibility: Minor Change

 Description   

We are running a mission-critical application in a Linux container and PlatformNotSupported is being thrown frequently. 

Looking at C# Driver code, seems we are first trying socket.IOControl and if an exception happens, we try socket.SetSocketOption (reference), but according to .Net Runtime code, this would always be the case (reference), as IOControlCode KeepAlive is only supported for windows (reference)

For top performance, shouldn't we check for Platform in order to switch between IOControl or SetSocketOption methods?

 



 Comments   
Comment by James Kovacs [ 11/Aug/22 ]

Suggested change implemented. We plan to make it available in the 2.18.0 release.

Comment by Githook User [ 11/Aug/22 ]

Author:

{'name': 'James Kovacs', 'email': 'jkovacs@post.harvard.edu', 'username': 'JamesKovacs'}

Message: CSHARP-4287: Only call Socket.IOControl with IOControlCode.KeepAliveValues on Windows. (#863)
Branch: master
https://github.com/mongodb/mongo-csharp-driver/commit/fbf97723b5105cd1c4b172acf15f1c2b4b5aefc2

Comment by James Kovacs [ 02/Aug/22 ]

Hi, kaio3henriquemelo@gmail.com,

Thank you for reporting this issue.

Reading through Socket.IOControl on MSDN, it makes no mention that it should only be used on Windows. Reading through the source code, I can clearly see that it will throw a PlatformNotSupportedException in almost all cases on non-Windows operating systems and that this method should not be used in cross-platform applications. Unfortunately there does not appear to be a way to ascertain whether Socket.IOControl and/or Socket.SetSocketOption is supported on a particular platform with a particular parameters except by attempting to call the API and catching PlatformNotSupportedException. In theory Microsoft could start supporting these API on non-Windows operating systems in a future .NET version.

All that said, using exception handling for flow control is not desirable. I'll investigate further whether we can place a platform check around Socket.IOControl (which is a very Windows-specific API) instead of the try/catch block. I'll update this issue as I learn more.

In the meantime you can minimize the impact of this behaviour in your application by effective connection pooling as Socket.IOControl and Socket.SetSocketOption are only called once per connection when the underlying socket is opened.

Sincerely,
James

Generated at Wed Feb 07 21:47:47 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.