This is used to poll many connections in a single function call. Previously,
this was only possible if all of the connections were those accepted on the
same listen socket. (ReceiveMessagesOnListenSocket). But this left out at
least two important use cases with known users:
- If you create more than one listen socket (because there is more way to
contact your service, e.g. once for P2P and another for direct IP, and
another for relayed connections), then you could not poll all of the
connections efficiently.
- In P2P use cases, we may initiate many connections to peers, and we want
to poll all of them at once.
This change is relevant to: Issue #49, Issue #50, and issue #52. (But I don't
this it really "fixes" any of them.)
This is to try to limit what is exposed in a naive generic interface to allow
users to adjust config values, in a way that doesn't allow the user to break
the security in a trivial way.
Working towards being able to use this object in a new API to send messages
efficiently. (Issue #51.)
- Message objects are actually ref counted now.
- m_sender renamed to m_identityPeer
- Added a flags field. Now you can know if the received message was sent
reliable or not.
- Added inline protected destructor to enforce proper usage.
- Tweaked tons of comments
- When receiving a fragmented unreliable message, I found a place where we
were doing more memory allocations and memcpying than necessary and
optimized that.
Delete a #ifdef __cplusplus block. This whole file is using tons of C++
features. It was weird to have that one block have that #ifdef
Also: In ConnectionState_ProblemDetectedLocally and ConnectionState_FinWait,
don't try to take any action immediately. Just trigger an immediate wake up
call, and we will take that action back out in the main loop, where we know
what's higher up on the call stack and what is safe to do.
The only other currently supported cipher is the NULL cipher, which we want
for remote streaming because we don't want to pay cost to encrypt/decrypt
on mobile. But eventually we might want to add other ciphers, and this is
the mechanism to do it.
This required shuffling around the crypto handshake quite a bit, because we
want the app to be able to set configuration options on incoming cnonections
before accepting them.
The connection will be responsible for end to end stuff including encryption,
message fragmentation and reliability, etc. Transports deliver datagrams. A
transport is always associated with a single connection, but a connection may
have more than one transport, and may switch between transports over the course
of the connection lifetime.
The goal here is to have conenction types that can switch transport.
Specifically, we need to support a connection that can detect when peers
are on the same LAN and use ordinary UDP in that case, attempt NAT piercing
using STUN, and if that fails, then relay (either using TURN or SDR).
There is more work to be done here. For example, each transport almost
certainly has its own ping time and quality characeristics, so we probably ought
to track some stats there. (But our stats situation is already getting pretty
crazy, so maybe just track ping seperately).
This change also includes some changes relevant for Steam Remote Play
streaming, which is going to use this protocol for relayed connections.
(And eventualy, hopefully, for all connections.) For example, steam remote
play needs really high bandwidth and packet rate, and the tolerance for
sending the timing data for jitter tracking was too tight. I also need to
pass a "certificate" to a subprocess in a single blob, which actually includes
the private key.
This is a bit more wasteful, but it facilitates forward and backward
compatibility. If one peer is using an identity type that an old
peer doesnt' parse, they can still often communicate. The old peer
often doesn't need to really "understand" what the identity is.
Also fixed some parsing bugs in SteamAPI_SteamNetworkingIdentity_ParseString.
At least in the public header. This maximizes compatibility wth some old
toolchains. We may not support those toolchains for building the code,
but it's nice for them to at least be able to link with us and use our
public header.
Also:
- STEAMNETWORKINGSOCKETS_STEAM now mens "running on steam", not "running using
the steam client". STEAMNETWORKINGSOCKETS_STEAMCLIENT is for that.
- Refactored stats stuff, moved it into the namespace. At one point I thought
I might expose some stuff in a public interface. For now, keeping it internal.
- Removed concept of Steam "universe" from this branch of the code.
- Don't use OVERRIDE, override works.
Added documentation about SteamNetConnectionStatusChangedCallback_t. This is an
important callback, so it's been pretty bad that it was essentially undocumented
until now.
Also use ESteamNetworkingConnectionState instead of int. (I have taken steps
to make sure that the enum is the right size.)
The notes about ISteamNetworkingUtils::InitializeRelayNetworkAccess are not
relevant in the opensource context.
In Steamworks, we want to keep the number of odinary DLL imports to an
absolute minimum, because those come from steam_api.dll, which we do
not update. (The developer needs to take a new one to update their SDK.)
The functions in the interface come from steamclient.dll, which we do
update frequently.
This resulted in the following changes:
* Printing and parsing of SteamNetworkingIPAddr and SteamNetworkingIdentity
were moved to ISteamNetworkingUtils functions. Most C++ code will still
access them through the inline class methods, so they won't really care
where they are implemented.
* Deleted some hashing functions. This is not hard to write, and the
definition of operator= gives you an example of what to do.
* SteamNetworkingMessage::Release will happen through a pointer, so that it
can be dynamiclaly linked.
Other changes:
* Renamed an old name "STEAMDATAGRAMLIB" to "STEAMNETWORKINGSOCKETS" in
a few places.
* Use STEAMNETWORKINGSOCKETS_ENABLE_SDR in a few places, to remove
SDR-specific functionality. (We might opensource the SDR support code
in the future.)
This isn't critical in an environment like this, where we don't have ABI compatibility commitments. But for the Steamworks SDK this will hopefully be useful. Once we release a version of an interface, we must support that ABI indefinitely.
Put essential stuff at the top, less commonly used fields at the bottom. Also, SteamNetworkingIdentity is a large object, so having it in the middle of the object increased the likelihood of touching multiple cache lines.
Moved them to ISteamNetworkingUtils, which is now actually shared Steam (mostly) with a real accessor and and interface, and not a dummy interface object with all static methods.
Connection settings have a system of inheritance, so they can be set globally, per SteamNetworkingSockets interface, per listen socket, or per connection.
Deleted the config variable to simulate fake *message* loss. That is not useful.
Introduced STEAMNETWORKINGSOCKETS_ENABLE_SDR define, to make it more clear why code is being #ifdef'ed out. (E.g. if we open-sourced that code, we would want that included.)
Replaced ESteamNetworkingSendType with a basic flags bitmask.
Cleaned up a bunch of comments.
Changed SteamNetworkingMessage_t release mechanism. Now the callback is only to free the buffer, and it's assumed that this API will manage the actual objects. (This is important because the actual type is a derived type and has extra stuff on the end.) Also laid some groundwork for user management of message objects. (Relevant for issue #51.)
Make it a method of ISteamnetworkingUtils method. This matches Steam.
Make sure ESteamNetworkingSocketsDebugOutputType is 32-bits, and declare the output callback to take an enum instead of int.
Switched AES-GCM IV's to be 96-bit instead of 128-bit.
- This is what TLS uses (RFC5288)
- This is what NIST recommends (https://dl.acm.org/citation.cfm?id=2206251)
- This is more optimal. (Certainly for OpenSSL's implementation; I believe it's true in general for GCM.)
- This is the only value that libsodium supports. Note that we're still using a 32-bit tag, and libsodium only supports the full 128-bit tag (to my knowledge, see #48). But we might decide to use the full 128-bit tag, and that that point libsodium could be used.
Moved the protocol number out of transport-specific handshake packets to be a "crypt parameter", where it will be signed. In the future we might need to allow some clients to connect to older clients that have a known security vulnerability (perhaps only during some temporary transition period). We don't want an attacker to be able to forge the protocol version and force the weaker protocol to be negotiated.
Bumped the protocol version because these are wire-compatibility-breaking changes.
Added a specific error code if a connection fails due to protocol incompatibilities.
* Provide plain C wrappers to the inline functions in SteamNetworkingIPAddr and SteamNetworkingIdentity
* Change names to be consistent with the rest of the Steamworks names.
Also moved a bunch of Steam-specific stuff to other files, which are not included in this repository.
Moved high level init/kill to a seperate file, so that isteamnworkigsockets.h won't be cluttered with
a bunch of #ifdefs.
Added IClient interface layer, which is useless in this context, butneeded in Steam, since we
provide backwards compatibility for all old ISteamXxx interfaces.
This doesn't exist in the Steamworks SDK, so moving it to a seperate file means that the files that are in both branches can have fewer differences.
Deleted the "GameServer" interface. That is a Steamworks thing. I'll add another method to create additional interfaces later, if we need them.
CreateSocketPair now allows you to assign the identities to each end of the pipe.
Fix some really basic irritating issues trying to use ordinary UDP and loopback connections without an identity. Make it more straightforward to just use generic identity with no authentication.