You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
152 lines
4.7 KiB
152 lines
4.7 KiB
4 years ago
|
//====== Copyright Valve Corporation, All rights reserved. ====================
|
||
|
//
|
||
|
// Types and utilities for handling steam datagram tickets. These are
|
||
|
// useful for both the client and the backend ticket generating authority.
|
||
|
//
|
||
|
//=============================================================================
|
||
|
|
||
|
#ifndef STEAMDATAGRAM_TICKETS_H
|
||
|
#define STEAMDATAGRAM_TICKETS_H
|
||
|
#ifdef _WIN32
|
||
|
#pragma once
|
||
|
#endif
|
||
|
|
||
|
#ifndef assert
|
||
|
#include <assert.h>
|
||
|
#endif
|
||
|
|
||
|
#include "steamnetworkingtypes.h"
|
||
|
|
||
|
#pragma pack(push)
|
||
|
#pragma pack(8)
|
||
|
|
||
|
#if defined( STEAMDATAGRAM_TICKETGEN_FOREXPORT ) || defined( STEAMDATAGRAMLIB_FOREXPORT )
|
||
|
#define STEAMDATAGRAM_TICKET_INTERFACE DLL_EXPORT
|
||
|
#elif defined( STEAMDATAGRAMLIB_STATIC_LINK )
|
||
|
#define STEAMDATAGRAM_TICKET_INTERFACE extern "C"
|
||
|
#else
|
||
|
#define STEAMDATAGRAM_TICKET_INTERFACE DLL_IMPORT
|
||
|
#endif
|
||
|
|
||
|
/// Max length of serialized auth ticket. This is important so that we
|
||
|
/// can ensure that we always fit into a single UDP datagram (along with
|
||
|
/// other certs and signatures) and kep the implementation simple.
|
||
|
const size_t k_cbSteamDatagramMaxSerializedTicket = 512;
|
||
|
|
||
|
/// Network-routable identifier for a service. In general, clients should
|
||
|
/// treat this as an opaque structure. The only thing that is important
|
||
|
/// is that this contains everything the system needs to route packets to a
|
||
|
/// service.
|
||
|
struct SteamDatagramServiceNetID
|
||
|
{
|
||
|
// Just use the private LAN address to identify the service
|
||
|
uint32 m_unIP;
|
||
|
uint16 m_unPort;
|
||
|
uint16 m__nPad1;
|
||
|
|
||
|
void Clear() { *(uint64 *)this = 0; }
|
||
|
|
||
|
uint64 ConvertToUint64() const { return ( uint64(m_unIP) << 16U ) | uint64(m_unPort); }
|
||
|
void SetFromUint64( uint64 x )
|
||
|
{
|
||
|
m_unIP = uint32(x >> 16U);
|
||
|
m_unPort = uint16(x);
|
||
|
m__nPad1 = 0;
|
||
|
}
|
||
|
|
||
|
inline bool operator==( const SteamDatagramServiceNetID &x ) const { return m_unIP == x.m_unIP && m_unPort == x.m_unPort; }
|
||
|
};
|
||
|
|
||
|
/// Ticket used to gain access to the relay network.
|
||
|
struct SteamDatagramRelayAuthTicket
|
||
|
{
|
||
|
SteamDatagramRelayAuthTicket() { Clear(); }
|
||
|
|
||
|
/// Reset all fields
|
||
|
void Clear() { memset( this, 0, sizeof(*this) ); }
|
||
|
|
||
|
/// Steam ID of the gameserver we want to talk to
|
||
|
CSteamID m_steamIDGameserver;
|
||
|
|
||
|
/// Steam ID of the person who was authorized.
|
||
|
CSteamID m_steamIDAuthorizedSender;
|
||
|
|
||
|
/// SteamID is authorized to send from a particular public IP. If this
|
||
|
/// is 0, then the sender is not restricted to a particular IP.
|
||
|
uint32 m_unPublicIP;
|
||
|
|
||
|
/// Time when the ticket expires.
|
||
|
RTime32 m_rtimeTicketExpiry;
|
||
|
|
||
|
/// Routing information
|
||
|
SteamDatagramServiceNetID m_routing;
|
||
|
|
||
|
/// App ID this is for
|
||
|
uint32 m_nAppID;
|
||
|
|
||
|
struct ExtraField
|
||
|
{
|
||
|
enum EType
|
||
|
{
|
||
|
k_EType_String,
|
||
|
k_EType_Int, // For most small integral values. Uses google protobuf sint64, so it's small on the wire. WARNING: In some places this value may be transmitted in JSON, in which case precision may be lost in backend analytics. Don't use this afor an "identifier", use it for a scalar quantity.
|
||
|
k_EType_Fixed64, // 64 arbitrary bits. This value is treated as an "identifier". In places where JSON format is used, it will be serialized as a string. No aggregation / analytics can be performed on this value.
|
||
|
};
|
||
|
int /* EType */ m_eType;
|
||
|
char m_szName[28];
|
||
|
|
||
|
union {
|
||
|
char m_szStringValue[128];
|
||
|
int64 m_nIntValue;
|
||
|
uint64 m_nFixed64Value;
|
||
|
};
|
||
|
};
|
||
|
enum { k_nMaxExtraFields = 16 };
|
||
|
int m_nExtraFields;
|
||
|
ExtraField m_vecExtraFields[ k_nMaxExtraFields ];
|
||
|
|
||
|
/// Helper to add an extra field in a single call
|
||
|
void AddExtraField_Int( const char *pszName, int64 val )
|
||
|
{
|
||
|
ExtraField *p = AddExtraField( pszName, ExtraField::k_EType_Int );
|
||
|
if ( p )
|
||
|
p->m_nIntValue = val;
|
||
|
}
|
||
|
void AddExtraField_Fixed64( const char *pszName, uint64 val )
|
||
|
{
|
||
|
ExtraField *p = AddExtraField( pszName, ExtraField::k_EType_Fixed64 );
|
||
|
if ( p )
|
||
|
p->m_nFixed64Value = val;
|
||
|
}
|
||
|
void AddExtraField_String( const char *pszName, const char *val )
|
||
|
{
|
||
|
ExtraField *p = AddExtraField( pszName, ExtraField::k_EType_Fixed64 );
|
||
|
if ( p )
|
||
|
V_strcpy_safe( p->m_szStringValue, val );
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
ExtraField *AddExtraField( const char *pszName, ExtraField::EType eType )
|
||
|
{
|
||
|
if ( m_nExtraFields >= k_nMaxExtraFields )
|
||
|
{
|
||
|
assert( false );
|
||
|
return nullptr;
|
||
|
}
|
||
|
ExtraField *p = &m_vecExtraFields[ m_nExtraFields++ ];
|
||
|
p->m_eType = eType;
|
||
|
V_strcpy_safe( p->m_szName, pszName );
|
||
|
return p;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/// Unpack signed ticket. Does not check the signature!
|
||
|
/// Note that it's assumed that you won't need to link with both the client
|
||
|
/// lib and the ticket generating lib in any one project, since this symbol
|
||
|
/// is exposed in both.
|
||
|
STEAMDATAGRAM_TICKET_INTERFACE bool SteamDatagramRelayAuthTicket_Parse( const void *pvTicket, int cbTicket, SteamDatagramRelayAuthTicket *pOutTicket, SteamDatagramErrMsg &errMsg );
|
||
|
|
||
|
#pragma pack(pop)
|
||
|
|
||
|
#endif // STEAMDATAGRAM_TICKETS_H
|