I’ve hacked together a first shot at a 3.0 redesign of SDL_net.
Nothing is final, so feedback is welcome here (including “this is terrible, don’t do this at all.”)
The general idea:
opened 12:55AM - 19 Jun 23 UTC
To be clear, this isn't something I plan to work on any time soon, but it would … be nice if we had an idea of what to aim towards if we're finally breaking API/ABI for SDL_net.
SDL_net is not my favorite thing in the world, but I'm willing to be optimistic and say with the correct changes, I could certainly learn to love it.
Here are some wishlist items.
- IPv6 support, but maybe better said...
- ...any network support, really, since this can be abstracted, I think.
- Resolved addresses live in an opaque structure and there will be a function to return a somewhat-human-readable string (like `127.0.0.1` or `2259:1700:2760:bab8:2a20:562b:e796:143d`).
- Simplify what's there: remove the select()-like API (SDLNet_SocketSet), and just accept an array of sockets to check for available data during SDLNet_CheckSockets(). Or just make everything non-blocking...
- Make everything non-blocking. Spin a thread for DNS lookups, set O_NONBLOCK on socket handles, etc.
- Split SDLNet_TCP_Open into client and server operations (one becomes a connect() call, the other becomes a listen() and bind()).
- The "server socket" (something you can accept() connections on) is confusing, I'd replace it with some sort of abstraction for answering connections that doesn't use the same TCPsocket type externally (even if it's just the same sort of file descriptor internally)
- Replace references to "TCP" and "UDP" with "Stream" and "Datagram" (or "Reliable" and "Unreliable" or whatever).
- "Binding" a socket to a "channel" is pretty confusing, both because it confuses the lower-level concept of "binding" a datagram socket to a port number, and it makes it look like a socket needs to bind to a single "channel," which will cause people to try to create multiple sockets on the same port for different channels.
- I kind of want to dump all the explicit allocation of UDP packets, and instead just have the send/recv functions handle this internally. The app just provides a buffer to send or a buffer to receive data and be done with it.
- Remove SDL_FORCE_INLINE functions and macros from SDL_net.h, make them real functions in the library.
- Add a way to convert a TCP stream into an SDL_RWops...? That might be stupid, idk.
- Someone asked for built-in encryption, but adding an OpenSSL or whatever dependency is a huge hassle, doubly-so if that may or may not be available in the build on the other end of the connection.
90% of the reason SDL_net exists at all was to manage differences between BSD Sockets, Winsock, and a few other wierdo platforms, but BSD Sockets won out, modulo a few WinSock differences that can be papered over with a handful of `#define`s, so that need doesn't really exist any more.
So the only reason for an SDL3_net to exist, if we're going to do an SDL3_net, is to make it _easier_ to do these common socket things from a programming point of view, or _add features_ that are less trivial to slot into an app, like encryption or NAT hole punching. There really isn't anything that integrates with SDL3 that needs to be updated from an SDL2 interface, etc.
All I'm talking about here is how to streamline what's there to be a better API, but the question still lingers: is this worth doing? Or should we retire this with SDL2 and tell people to use BSD Sockets?
The pull request with the current state of this:
libsdl-org:main
← icculus:sdlnet3-redesign
opened 11:47PM - 18 Jul 23 UTC
This is a complete redesign and rewrite of SDL_net for a 3.0 release. It has dif… ferent goals and functionality than SDL2_net, of which I have retained no pieces.
See discussion in #77 for details.
Feel free to comment here, or the issue link or the PR link, I’ll see them all.
5 Likes
icculus:
feedback is welcome
As you know I can’t migrate to SDL3 for other reasons (principally the loss of an OpenGLES 1 backend) but I’m very supportive of this.
I note the comment “Someone asked for built-in encryption, but adding an OpenSSL or whatever dependency is a huge hassle ”. I expect that was me!.
It’s precisely because it’s a hassle that having it available in a cross-platform library would be so valuable! Insecure net communication is increasingly uncommon.
icculus
September 30, 2023, 11:58pm
3
The redesigned SDL3_net has been merged!
Brief discussion of the history and motivations are on my Patreon .
This new API is not locked down until we make some sort of official release, so if you play around with it, and hate it, definitely let me know!
The wiki has a pretty good start on documentation . The SDL2_net docs are still available , too.
I totally agree, and building this into the library (and I mean building it , not just slapping OpenSSL into there) is a big, audacious goal of mine, for when I’m not buried under SDL3 work…but this first shot is meant to be a humble improvement over the previous version, which is good enough for now.
1 Like
yataro
October 1, 2023, 8:26pm
5
How about adding TLS support with SDLNet_CreateTLSClient
/ SDLNet_CreateTLSServer
api that will accept a context struct
with TLS callbacks (handshake/verify/encrypt/decrypt/etc), where the end user has to implement this themselves using any suitable backend?
I don’t think encryption can be applicable for datagram streams due to the complexity of implementing handshake requiring reliable packets.