Skip to content

Conversation

dNechita
Copy link
Contributor

@dNechita dNechita commented Sep 3, 2025

PR Description

It has been observed that creating a network iio context with a wrong IP (that doesn't point to a system with iio devices) will cause a crash when executed in a Windows environment.
This happens because:

  • the windows implementation of do_create_socket() returns WSA error
  • the WSA error has value -10060 which is outside of [-4095, -1]
  • WSA error code is returned by network_create_context()
  • iio_create_context() treats -10060 as a valid context address
  • iio_create_context() calls iio_context_update_scale_offset() causing the crash (access violation).

Fix this by translating a few common WSA error codes to POSIX codes that are know to be in the range of [1, 4095].

PR Type

  • Bug fix (a change that fixes an issue)
  • New feature (a change that adds new functionality)
  • Breaking change (a change that affects other repos or cause CIs to fail)

PR Checklist

  • I have conducted a self-review of my own code changes
  • I have commented new code, particularly complex or unclear areas
  • I have checked that I did not introduce new warnings or errors (CI output)
  • I have checked that components that use libiio did not get broken
  • I have updated the documentation accordingly (GitHub Pages, READMEs, etc)

@rgetz
Copy link
Contributor

rgetz commented Sep 5, 2025

This is a good catch, but I think this points out a larger issue. We can't just fix the bugs we can see :)

We need something like:

#ifdef _WIN32
static int translate_wsa_error_to_posix(int wsa_err)
{
    switch (wsa_err) {
    case WSAEACCES:        return -EACCES;
    case WSAEADDRINUSE:    return -EADDRINUSE;
    case WSAEADDRNOTAVAIL: return -EADDRNOTAVAIL;
    case WSAEAFNOSUPPORT:  return -EAFNOSUPPORT;
    case WSAEALREADY:      return -EALREADY;
    case WSAECONNREFUSED:  return -ECONNREFUSED;
    case WSAEFAULT:        return -EFAULT;
    case WSAEINPROGRESS:   return -EINPROGRESS;
    case WSAEISCONN:       return -EISCONN;
    case WSAEMFILE:        return -EMFILE;
    case WSAENETDOWN:      return -ENETDOWN;
    case WSAENETUNREACH:   return -ENETUNREACH;
    case WSAENOBUFS:       return -ENOBUFS;
    case WSAENOTSOCK:      return -ENOTSOCK;
    case WSAEPROTONOSUPPORT:return -EPROTONOSUPPORT;
    case WSAETIMEDOUT:     return -ETIMEDOUT;
    case WSAEHOSTUNREACH:  return -EHOSTUNREACH;
    case WSAEINVAL:        return -EINVAL;
    // Optional extras you might hit:
    case WSAEWOULDBLOCK:   return -EAGAIN;
    case WSAESHUTDOWN:     return -ESHUTDOWN;
    default:               return -EIO;   // generic fallback
    }
}
#endif

Anywhere we propagate the result of network_get_error() or a raw SO_ERROR value, you should run it through the translation layer on Windows. that would include connect and socket interfaces.

ret = network_get_error();
#ifdef _WIN32
ret = translate_wsa_error_to_posix(-ret);  // pass positive WSA code
#endif

or wrap in a helper iio_network_get_error to keep it cleaner...

Functions with the same names as POSIX (socket, connect, bind, listen, accept, send, recv, etc.) are actually Winsock shims, not true POSIX. When they fail, they don’t set errno — instead they set an internal Winsock error value, which you must fetch with WSAGetLastError(), which is what network_get_error() does. Those error values are WSA* codes (100xx), not POSIX errno values, and need to be translated.

And there are others - getsockopt(..., SO_ERROR, ...)

  • On Linux/macOS: error is filled with a POSIX errno (e.g. ECONNREFUSED = 111).
  • On Windows: error is filled with a WSA error code (e.g. WSAECONNREFUSED = 10061).

@dNechita dNechita force-pushed the fix-ctx-invalid-uri-windows branch from 393ffc6 to 5255ace Compare September 9, 2025 07:09
@dNechita dNechita force-pushed the fix-ctx-invalid-uri-windows branch from 5255ace to 5beefa7 Compare September 10, 2025 12:20
@dNechita
Copy link
Contributor Author

V1:

  • fix handling error code for WSAStartup()
  • Translate more WSA error codes.
  • Do the translation as close as possible to the public API. This is because the internal implementation depends on some WSA error codes. Translating too early would mess up things. So, instead of translating as close as possible to the source of error (WSAGetLastError(), SO_ERROR, recv(), send(), etc.), translate the return value of all API that might return a WSA error code.

WSAStartup() returns 0 on success and positive error codes (WSA error
codes) on failure. Checking if ret < 0 won't catch any error.
https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-wsastartup

Signed-off-by: Dan Nechita <dan.nechita@analog.com>
@dNechita dNechita force-pushed the fix-ctx-invalid-uri-windows branch from 5beefa7 to 637fb20 Compare September 25, 2025 11:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants