Steamworks 문서
Steam 데이터그램 릴레이
Steam 데이터그램 릴레이(SDR)는 Valve의 온라인 비공개 게이밍 네트워크입니다. 저희 API를 사용하면, 게임의 트래픽을 Valve의 게임 콘텐츠 전용 백본에 전달할 수 있을 뿐 아니라, 릴레이 네트워크에 접근할 수도 있습니다. 트래픽을 릴레이하면 IP 주소가 노출되지 않기 때문에 귀사의 서버 및 플레이어들을 DoS 공격으로부터 보호할 수 있습니다. 수신하는 모든 트래픽은 인증되고 암호화되며 속도 제한이 적용됩니다. 또한, 예상치 못할 정도로 플레이어가 많은 경우, 저희의 네트워크를 통해 더 빠른 경로를 검색할 수 있으며, 이를 통해 실제로 플레이어의 핑 시간이 개선됩니다.

본 릴레이 네트워크는 P2P 트래픽 및 전용 서버 모두에 사용 가능합니다.

기존 네트워크 코드 포팅을 위한 일반 요구 사항 및 관련 팁

다음은 알아 두어야 할 P2P와 전용 서버 연결에 모두 적용되는 몇 가지 일반적인 사항입니다.

먼저, 네트워크 호스트가 공용 IP로 식별되는 모든 곳(대부분 게임 서버의 경우)은 해당 IP 대신 다른 식별자를 사용하도록 변경해야 합니다. 이를 위한 몇 가지 옵션이 있습니다.
  • Steam에 로그인하는 클라이언트와 게임 서버의 경우, 일반적으로 SteamID를 사용합니다.
  • 귀사의 게임 서버가 Steam에 로그인하지 않으며 티켓 기반 인증 흐름을 사용하는 경우, 귀사에게 의미 있는 다른 식별자를 사용할 수 있습니다. SteamNetworkingIdentity를 참고하세요.
  • 일부 코드베이스에서는 네트워크 호스트와 게임 서버를 IPv4 주소를 사용하여 식별한다는 가정이 보편적이며, 이 가정을 변경하려면 상당히 많은 작업이 필요합니다. 실제로 Steamworks ISteamMatchmakingISteamMatchmakingServers API는 Team Fortress 2와 같은 일부 저희 게임과 마찬가지로 이러한 속성을 사용합니다. 이러한 경우, Steamworks 'Fake IP' 시스템을 사용하실 수 있습니다. FakeIP는 대부분의 경우 유효한 IPv4 주소처럼 보이지만, 인터넷에서 사용되지 않는 예약된 주소 공간에서 가져온 IP입니다. 서버에 FakeIP를 지정하면, IPv4 주소를 계속해서 서버의 주소로 사용할 수 있으며 거의 모든 것이 '정상적으로 작동'합니다. ISteamNetworkingSocketsISteamMatchmakingServers 시스템은 이런 특수 IP를 인식하고 적절한 작업을 진행합니다. 이러한 IP는 라우팅할 수 없으며 일반 인터넷 목적(예: 핑 불가능)으로 사용할 수 없습니다. 자세한 정보는 ISteamNetworkingSockets::BeginAsyncRequestFakeIP 문서를 참고하세요.

또한, 연결을 위해서 Steamworks API 중 하나를 사용하려면 하위 수준 소켓 코드를 수정해야 합니다.
  • 이상적으로는 HSteamNetConnection을 반환하는 연결 지향 API ISteamNetworkingSockets 인터페이스 중 하나를 사용할 수 있습니다.
    (이러한 API는 테스팅에 매우 유용한 일반 UDP 전송도 지원한다는 점을 참고하세요. 또한, 오픈 소스 버전도 있습니다.)
  • 일부 코드베이스는 UDP와 비슷한 방식으로 작성되어 필요에 따라 언제든지 패킷을 원격 호스트로 보낼 수 있으며, 모든 메시지가 설정된 '연결'로 전송되지는 않습니다. 이러한 상황에서 도움이 될 수 있는 2가지 Steamworks 기능이 있습니다.
    • ISteamNetworkingMessages를 사용하여 SteamID와 같은 SteamNetworkingIdentity 유형을 통해 식별된 호스트와 통신하세요.
    • ISteamNetworkingFakeUDPPort를 사용하여 FakeIP를 통해 식별된 호스트와 통신하세요.

Requirements for using SDR on other platforms and stores

게임이 하나의 플랫폼에서만 작동한다면 교차 플랫폼 게임을 위한 네트워킹 API 및 DDoS 솔루션은 의미가 없습니다. 대부분의 경우, 게임이 일부 기본 조건을 충족하면 다른 플랫폼과 상점에 있는 플레이어들은 릴레이 네트워크를 사용할 수 있습니다.
  • 게임의 한 버전을 Steam에 출시하세요.
  • 버그 수정 또는 보안 패치를 배포해야 할 필요가 있는지에 대한 질문을 받으면 적절한 기간(예: 몇 개월) 내에 게임을 업데이트하기로 동의합니다.
  • 계속해서 이 서비스가 비 Steam 플레이어들에게 제공될 것인지는 확실하지 않다는 점을 참고해 주세요. 만약 이 서비스에 대한 다운그레이드가 필요할 경우, 계획을 세울 수 있는 시간을 드리는 것 이외에도 플레이어들에게 방해를 끼치지 않도록 가능한 한 모든 지원을 제공해 드리겠습니다. SDK는 클라이언트를 직접 UDP 연결로 변경하거나 NAT 펀치를 시도하도록 지시할 수 있는 기본 메커니즘을 사용하지만, 이에 대한 가능성도 염두에 두어야 합니다.
  • 인증 자격 증명을 발급할 수 있는 일종의 매치메이킹 서비스(SDR은 이를 귀사의 '게임 코디네이터'라고 함)를 제공하세요. 저희는 이를 위한 별도의 SDK를 제공합니다. 아래를 참고하세요.

관련 SDK 및 세부 내용에 관해 질문이 있으시면 저희에게 문의해 주세요. We're still working through details of how to distribute this code, and at this time we might not be able to make cross-platform support available to all partners and all games.

See below for more technical information on implementing SDR on other platforms and stores.

If you don't meet the criteria above, feel free to use the opensource version of the API for whatever you want. Note that the opensource code does not support accessing the relay network.

P2P 게임

Steam의 P2P 트래픽의 경우, ISteamNetworkingSockets::CreateListenSocketP2PISteamNetworkingSockets::ConnectP2P와 같은 API를 사용하기만 하면 SDR을 활용할 수 있습니다. 나머지 작업은 Steam이 처리합니다. For other platforms and stores, read more about additional technical requirements below.

알려진 데이터 센터의 전용 서버

P2P API는 하나의 '피어'가 전용 서버일 경우 문제 없이 작동합니다! 고려해야 할 중요한 사항: 전용 서버가 릴레이를 실행하는 데이터 센터에 가깝지 않은 경우, 최적의 릴레이 경로가 일반 IP 경로보다 느릴 수 있으며, 일부 플레이어는 원래 속도보다 더 악화된 지연 시간을 경험할 수 있습니다.

For the optimal dedicated server experience, the server should be run in a known data center that is part of the SDR network. We make sure that relays are running nearby and the relayed route is never too much slower than the default IP route. Servers running in these known data centers connect using a special API. This use case is referred to in the SDK as "Hosted Dedicated Server". Note that this doesn't necessarily mean that Valve is hosting the servers or the relays -- it could be a third party data center that we have established a relationship with, and is known to the Steam Datagram Relay system.

If you are running game servers in a major hosting provider and are interested in using SDR, please get in touch with us. We'll try to work with your hosting company to run relays in the data center. That's the ideal situation, but even if this is not possible we may be able to add the data center to our network configuration system and just use Valve relays that are nearby.

If you are a dedicated server hosting company and want to join our network so that your customers can take advantage of SDR, please get in touch with us! We have not yet deployed relays in any third party hosting companies, however we are interested in doing this.

게임 코디네이터를 사용하지 않는 전용 서버에 대한 간단한 연결 흐름

플레이어에게 서버를 할당하는 자체 중앙 매치메이킹/로그인 서비스('게임 코디네이터'라고도 지칭)를 보유하지 않거나 가능한 한 간단하게 유지하고 싶은 경우, ISteamNetworkingSockets::CreateListenSocketP2PISteamNetworkingSockets::ConnectP2P API를 사용하여 알려진 데이터 센터에 있는 전용 서버에 연결할 수 있습니다. 이 경우, 연결은 일반 P2P 연결과 마찬가지로 클라이언트에서 시작됩니다. Rendezvous 메시지는 Steam을 통해 전송되므로, 플레이어 또는 서버 측에서 Steam 연결이 끊어지면 연결이 이루어지지 않습니다. 또한, Steam은 플레이어가 Steam에 로그인하였으며 게임을 소유하고 있다는 것을 확인하는 것 외에 누가 연결을 시도할 수 있는지에 대한 제한을 두지 않습니다.

게임 코디네이터 SDK

자체 게임 코디네이터 서비스가 있다면, 티켓 기반 연결 흐름을 사용하는 것이 좋습니다. 간단한 P2P 유형의 연결 흐름과 비교하면 약간의 작업이 더 필요하며 두 가지 중요한 장점을 제공합니다.
  • 연결 시도가 허용된 플레이어에게만 티켓을 제공할 수 있으므로, 허용되지 않은 플레이어의 원치 않은 연결 시도가 서버에 접속되지 않습니다.
  • SDR_IP: 서버에는 릴레이로부터 '요청하지 않은' 트래픽을 수신할 수 있는 공용 IP가 반드시 있어야 합니다. 서버에 공용 IP가 있는 인터페이스가 단 하나만 있다면, 이 IP가 사용됩니다.

A ticket-based connection to a dedicated server over SDR works like this:
  • 게임 서버가 게임 코디네이터에 로그인하면, 물리적 라우팅 정보를 포함한 불투명한 BLOB인 자체 SteamDatagramHostedAddress를 보냅니다. 자세한 정보는 ISteamNetworkingSockets::GetHostedDedicatedServerAddress에서 확인하세요. 참고로 저희는 게임 코디네이터에 로그인 인증 방식을 지원하는 몇 가지 도구를 제공하고 있습니다.
  • PingLocation_t 문자열을 분석하여 객체 간의 핑 시간을 계산합니다.
  • 다른 특정 고급 기능을 활용합니다.
  • 클라이언트는 ISteamNetworkingUtils 인터페이스에 있는 방식을 사용하여 데이터 센터로의 핑 시간을 얻고 연결을 확인할 수 있습니다. 그 후 클라이언트가 이 정보를 게임 코디네이터에게 전송하도록 하면 게임 코디네이터가 플레이어를 데이터 센터에 할당하는 데 적절한 결정을 내릴 수 있습니다.
  • 게임 코디네이터가 클라이언트의 서버 연결을 승인할 준비가 되면, SteamDatagramRelayAuthTicket을 생성하고 비밀 키로 서명합니다. 이 티켓은 한정된 시간 동안 특정 클라이언트가 특정 게임 서버와 통신하는 것을 승인합니다. 여기에는 암호화된 라우팅 정보도 포함됩니다. 게임 코디네이터는 티켓을 클라이언트에게 보냅니다.
  • 클라이언트는 티켓을 로컬 캐시에 캐싱합니다. 캐싱이 복잡하지만 유용한 이유와 더불어 더 자세한 정보는 ISteamNetworkingSockets::ReceivedRelayAuthTicket에서 확인하실 수 있습니다.
  • 클라이언트는 ISteamNetworkingSockets::ConnectToHostedDedicatedServer를 사용하여 서버에 연결합니다. 메시지 송수신 방법에 대한 자세한 내용은 ISteamNetworkingSockets에서 확인하실 수 있습니다.

At this time, the ticket-based authentication is not available in combination with the FakeIP system.

게임 코디네이터 SDK

'게임 코디네이터'란 백엔드/매치메이킹 서비스를 지칭할 때 사용하는 용어입니다. 게임 코디네이터와 연결할 수 있는 별도의 소규모 SDK가 있으며, 사용 용도는 다음과 같습니다.
  • SDR을 사용해 호스팅되는 게임 서버에 클라이언트가 접근하도록 티켓을 발행합니다.
  • Parse PingLocation_t strings and calculate ping times between these objects
  • 플레이어에게 다른 플랫폼 및 상점을 위한 신분 인증서 발행
  • 다른 특정 고급 기능을 활용합니다

The SDK is available here

인증

SDR은 두 가지 인증 메커니즘을 사용합니다.

  • 호스트 서버 티켓은 게임 코디네이터에 의해 발행되며, 일정 시간 동안 특정 클라이언트가 특정 전용 서버와 통신하도록 허가합니다. 릴레이 티켓은 전용 서버를 사용하는 경우에만 사용됩니다. SteamDatagramRelayAuthTicket을 확인하세요.
  • 인증서는 전통적인 인증 방식으로 사용되며, DH 키 교환을 수행하여 암호화된 채널을 구축합니다. 인증서는 엔드 투 엔드 개념이며, 직접 UDP 연결 또는 P2P와 같은 모든 형태의 SteamNetworkingSockets 통신에 사용됩니다. 게임 코디네이터 SDK에서 SteamDatagram_CreateCert와 ISteamNetworkingSockets::GetCertificateRequest를 확인하세요.

We use a proprietary public key infrastructure (PKI) to authenticate clients and servers. Players are issued individual, short-term certificates, tied to their specific player identity. Steam takes care of this. For gameservers, we typically use longer term certificates that authorize an entire data center for a particular AppID. You will issue those certificates.

Before you can issue tickets and certificates, you'll need to generate a keypair and send us your public key. We will publish a certificate signed by our master CA key that marks your key as trusted for your app(s). Then, offline you will generate a certificate for each data center where you want to run servers, using our certificate tool, and sign it with your private key. You'll distribute those certificates to your gameservers over a secure channel, passing it to your server in the environment (see below).

You'll also use your key to generate tickets, each time a player connects to a gameserver.

Keep your CA private key and the private keys of your certificates safe! If your key leaks and needs to be revoked and replaced, it could lead to a disruption.

Implementing SDR on other platforms and stores


Your clients on other platforms and stores will not sign into Steam, and so you will need to provide a few services for those players that Steam provides for Steam players.

Game coordinator initialization

  • Your matchmaking service (referred to as the "game coordinator") will need to link with the game coordinator SDK. The header file steamdatagram_gamecoordinator.h has more details. The game coordinator SDK uses a plain C API, so it should be relatively easy to integrate with other languages.
  • Download the network config at initialization time, and check for updates approximately once an hour. (See SteamDatagram_GameCoordinator_GetNetworkConfigURL and SteamDatagram_GameCoordinator_SetNetworkConfig.) The network configuration is a small JSON file, at the time of this writing, about 26K (9K compressed). This URL has very high availability, however if you wish to handle the possibility of failure, you can use a recently downloaded version.
  • You'll need a keypair authenticated for your game. Send us the public key, and initialize the game coordinator SDK with your private key. (See SteamDatagram_SetPrivateKey_Ed25519 for more information.)

Client signon

  • The client will call ISteamNetworkingSockets::GetCertificateRequest to get a blob and send it along with the signon request message to your game coordinator.
  • When the game coordinator receives the signon request, generate a certificate for the client using SteamDatagram_CreateCert.
  • Send the generated certificate back to the client in the logon response. The client should install their certificate using ISteamNetworkingSockets::SetCertificate
  • It is highly recommended that you also distribute the network configuration to clients at this time as well. The client will apply the network configuration using SteamDatagram_SetNetworkConfig.

Certificates have an expiry, and we recommend that you use an expiry of 48-hours. If clients might be connected for longer than 48 hours, then you will need to periodically renew the certificate. It is acceptable to apply a new certificate at any time, and so if you want to issue certificates more often, for example at the start of every match, that is OK.

Every client must have a unique identity. If possible, use the platform-specific identities. (For Steam clients, this is a requirement.) However, if this is not possible, you can use a "generic string" identity that is meaningful to your matchmaker. See SteamNetworkingIdentity.

Peer-to-peer games

P2P connections require a "signaling" service. This is a low-bandwidth, non-latency-sensitive, best-effort-delivery channel capable of forwarding occasional rendezvous messages used to negotiate routing. This requires clients to have a persistent connection to your matchmaking service, such that you can push messages to them, such as a websocket or TCP connection. If clients only talk to your game coordinator using a request/response pattern, for example through http, that won't work. You only need to provide "best effort" delivery, meaning that the library is tolerant of messages dropping or being delivered multiple times.

  • To initiate a connection, use ISteamNetworkingSockets::ConnectP2PCustomSignaling. You will need to implement a subclass of ISteamNetworkingConnectionSignaling, and when SendSignal is called, the client should send the message to your backend, and your backend should make its best effort to deliver the message to the peer. When a connection is first created, a initial exchange 4-10 messages is typical. Thereafter, you might be called to deliver a signal for an established connection if routing conditions change.
  • When a client receives a signal, call ISteamNetworkingSockets::ReceivedP2PCustomSignal. The library will decode the message. If it is concerning an existing connection, the signal will be processed internally. If the signal is for a new connection, ISteamNetworkingSignalingRecvContext::OnConnectRequest will be called.

See steamnetworkingcustomsignaling.h for more details.

Running servers in known data centers

This section documents some technical details involved in running dedicated servers in known data centers.

Environment variables

The dedicated server gets its configuration from environment variables. Note that in Valve data centers, all of these values will be set automatically for you.
  • SDR_LISTEN_PORT: The UDP port where your server will receive traffic from relays. The dedicated server only uses a single socket. (But you can have more than one logical "listen socket" by using "virtual ports". See ISteamNetworkingSockets::CreateHostedDedicatedServerListenSocket.) In our data centers, we typically use the 30xxx range.
  • SDR_IP: Your server must have a public IP that can receive "unsolicited" traffic from relays. If the server only has one interface with a public IP, then this will be used. Otherwise, you will need to tell the gameserver what IP to use. The SDR socket will be bound to INADDR_ANY, but this information is needed to fill out the server's SteamDatagramHostedAddress. Note in particular that this will usually need to be set in dev environments, where your server is behind a corporate firewall. (See below.) You can also specify a port, if the public port differs from SDR_LISTEN_PORT.
  • SDR_POPID: The 3- or 4-letter alphanumeric code (SteamNetworkingPOPID) of the data center, in production. In development environment, leave this blank.
  • SDR_PRIVATE_KEY: The private key from your certificate. It's an OpenSSH PEM block that begins with "-----BEGIN OPENSSH PRIVATE KEY-----".
  • SDR_CERT: Your signed certificate. It's a proprietary format PEM-like block that begins with "-----BEGIN STEAMDATAGRAM CERT-----".
  • SDR_NETWORK_CONFIG: Full path to a local, recent copy of the SDR network configuration file for your app. If this variable is not set, then to obtain the network configuration the server will fetch the copy using HTTP at boot time. For optimal performance you can periodically (e.g. once an hour) download the latest configuration and save it locally, so that a network hiccup doesn't cause any disruption. This is how Valve servers are configured.

Running in a dev environment

Because ISteamNetworkingSockets supports plain UDP connectivity, it's usually best to start by getting your code working through this interface over UDP, without worrying about relays.

We suggest that your server code use the presence of the SDR_LISTEN_PORT environment variable to decide whether your server should listen for SDR. You can use ISteamNetworkingSockets::GetHostedDedicatedServerPort to fetch the value.

In development, you will leave SDR_POPID blank. When SDR_LISTEN_PORT and SDR_POPID is blank, the POPID is set to the special 3-character code "dev".

In general, authentication is disabled for servers in the "dev" environment. (Clients and relays will both allow connections to "dev" servers without a signed cert, as long as they have a signed ticket.) You will need another mechanism to authenticate with your game coordinator. And your game coordinator needs to be careful when it issues tickets to any servers claiming to be in "dev"!

Your server needs to be able to receive unsolicited public traffic, which means that if it doesn't have a public IP, you'll need to setup a port forward in your firewall. And you'll probably need to set SDR_IP with the proper public IP (and port, if it differs from SDR_LISTEN_PORT).