StoneCDN

Game Shield SDK Integration Guide (2025)

14 Jan, 2025 stonecdn

Preparation Steps

Before starting the integration, it is recommended to first review your business operations and confirm which services need to integrate the SDK. Clearly identify the corresponding service endpoints, domain names, and the IP addresses of the business servers (Note: the business server IP must not be publicly resolved or exposed; it should not be obtainable through resolution and preferably should be isolated from other services).

Creating SDK Integration InstanceUpon successful creation, you will receive an AppID and AppKey.

Forwarding Rule Configuration

Each forwarding rule needs to confirm the forwarding key (which uniquely identifies a forwarding rule), the IP/domain of the source server, the port, and the communication protocol (TCP/UDP).

Integration Process

Simply call the following required interfaces.

  • Call the Init interface to initialize, passing in the parameters AppID and AppKey (both parameters are required, and this call must be made). The client should initialize as soon as possible after startup, and it only needs to be initialized once (if the app goes to the background and then returns, the initialization must be called again).
  • Call the GetTCPServerAddr interface to obtain the local TCP proxy IP and port (this is required for TCP forwarding).
  • Call the GetClientIP interface to obtain the client's real IP address (this is optional and should be determined based on business needs).
  • Obtain the client's real IP address through the HTTP header X-Forward-For or by encapsulating it in the business data returned via TCP.
  • Establish a connection with the local proxy and send requests.

Considerations for SDK Integration

  • For Android, iOS, and PC platforms, regardless of whether using HTTP, TCP, or WebSocket, it is essential to call GetTCPServerAddr again for each request, during reconnections, and when the iOS app resumes after being locked. Previous return results should not be cached, as the system may close the local proxy port. Failing to re-invoke the interface and attempting to establish a connection directly may result in connection failure, leading to business exceptions.
  • Android provides dynamic libraries for armeabi-v7a, x86, x86_64, and arm64-v8a architectures, ensuring compatibility with all Android devices. Other third-party SDKs should maintain consistent library files; otherwise, it may lead to application crashes.
  • If you need to block emulators,please contact technical support..
  • For iOS, we provide a .a file for integration (devices prior to iPhone 5 are no longer supported).
  • The network handling on the client side needs to be more robust, including timeout handling and reconnection mechanisms.
  • Given that there are many SDK nodes that may change irregularly, it is recommended to disable source security policies.

Examples of Client Integration

The following examples introduce the essential interfaces for integrating the SDK. For complete implementation, please refer to the full code examples.

  • Android (operating system)

Operating Environment: Android 4.1 and above. Integrate the Android SDK into the project.

Code Example

import com.xshield.jni.ShieldService;boolean succeed = ShieldService.Init("$AppID", " $AppKey "); // If initialization is successful, it returns true.
String addr = ShieldService.GetTcpProxyAddr(“test.com”);
connect(addr);

Establish a connection using the IP and port from the previous step, and send and receive business data (it is recommended to execute this after initialization is complete to avoid blocking the UI thread).
Obtain the IP and port of the secure proxy to avoid blocking the UI thread.
Initialize the SDK by passing the obtained AppID and AppKey into the interface.

  • IOS

Operating Environment:iOS 8.0 and above. Add the iOS SDK to the application project.

Open the application project using Xcode and add libxshield.a to the project.

Code Example

XShieldIOS *sdk = [[XShieldIOS alloc] init];
[sdk init: @"$AppID " appKey: @" $AppKey "]; // Initialization successful returns true
#include "xshield-ios.h"
NSString* addr = [sdk getTCPAddr:@”test.com”];
connect(addr);

Establish a connection using the IP and port from the previous step, and send and receive business data.
Obtain the IP and port of the secure proxy (taking TCP forwarding as an example for configuration).
Initialize the SDK by passing the obtained AppID and AppKey into the interface.

Integration Acceptance

Client Packet Capture Analysis: Check if the source IP is exposed. (You will need a computer with a shareable hotspot network and packet capture software, such as Wireshark). Share the PC's hotspot (using Wi-Fi hotspot software or the built-in hotspot feature of the system), connect your phone to the hotspot network, open the packet capture software, and then start the software. Test all business operations several times to see if the source IP can be captured. Verify if there are any other domain names resolving to the source IP; if there are,it is recommended to isolate the business operations.
Obtain the real IP. Confirm whether the user's real IP is obtained correctly in the business context. If the retrieval fails, the IP obtained may be a high-defense node IPIP confirmation can be provided alongside the technology..
Pre-launch Testing: It is recommended to conduct extensive testing before going live, including a gray release for 2 to 3 days before proceeding with a full-scale update.

SDK Integration.Frequently Asked Questions

Resolve Port Conflicts

After years of observation and statistics, port conflict issues occur only on a few client devices and the probability of occurrence is low. To completely resolve this issue,we still recommend that you utilize the advanced functionality we provide to eliminate this problem entirely.

Since our SDK opens the corresponding ports on client devices based on the 'forwarding rules' you have configured, there is a very low probability of port conflicts occurring on individual client devices.

There are two types of port conflicts:

  • First scenario: A port you configured is already occupied by another application on certain client devices, which prevents the user from using your application normally.
  • Second scenario: You have multiple applications that use the same instance, and users may occasionally open multiple applications simultaneously on the same device. When the first application the user opens occupies all the ports of your instance, the second application will not be able to open those ports.

This issue is not a problem on PC; the second application operates normally because it connects to the SDK through the first application. However, on mobile devices, there will be issues. Initially, the second application can connect to the SDK through the first application. However, when the user switches to using the second application, the first application may go to the background, and after some time, the system may put the first application into a sleep state. At this point, the second application will be unable to connect.

Resolving this issue is also quite simple.The code process is as follows:::

dunSetAutoChangePort(1);//Set it to automatically change the conflicting port; you only need to call it once.

int ret = clinkStart(key);//Start protection; some systems use 'start'—please refer to another document. You only need to call it once.

//Call the following line of code to obtain a new port when a new connection is required

int new_tcpPort = dunGetCurrentTCPPort("127.0.10.21", 600);//Obtain a new TCP corresponding port

//Next, use new_tcpPort to connect to the application

//connect("127.0.10.21", new_tcpPort) For example, this line of pseudocode

Here's another example: For instance, if the forwarding rule is configured to forward 127.0.10.21:600 to 101.21.31.5:600.Comparison pseudocode before integration and after integrating the shield while resolving port conflicts

Connection before integration connect("101.21.31.5",600) 

Connection after SDK Integration connect("127.0.10.21", dunGetCurrentTCPPort("127.0.10.21",600))

1.1Set whether to automatically change conflicting ports

.Effective only if called before invoking the Protection Shield ‘start.

Function prototype: void dunSetAutoChangePort(int val)

  • Parameters:val: Indicates whether to automatically change. 0: Do not change automatically; 1: Automatically change to a new port when this port conflicts.
  • Feature:When val is set to 1, if a certain port is detected to be occupied or cannot be opened for other reasons when the shield is activated, a random available port will be automatically generated. This randomly generated port will be associated with the original port, and your program can obtain the newly generated port through the SDK-provided functions dunGetCurrentTCPPort or dunGetCurrentUDPPort when creating a new connection. By using the new port for the connection, this resolves the port conflict issue.

Below are the SDK function definitions corresponding to each system.For specific usage examples, please refer to the projects in 'Demo Advanced Features::

Windows: 
extern "C" CLINKAPI_API void dunSetAutoChangePort(int val).

android: 
Class:cn.ay.clinkapi.Api

public native void dunSetAutoChangePort(int val);

iOS Static Library: 
 Class:ClinkAPI
void dunSetAutoChangePort(int val);

iOS Dynamic Library:extern "C" void dunSetAutoChangePort(int val)
 extern "C" void dunSetAutoChangePort(int val);.

Unity 
Class:ClinkSDKForUnity 
 public static void dunSetAutoChangePort(int val)

Uni-app 
Plugin Name: ayClinkApiForUni
Plugin Function: dunSetAutoChangePort(val)

1.2.Get the current TCP corresponding port

Before establishing a new TCP connection, you need to call this function to get the new port corresponding to the port you are going to connect to, as your original port may have a conflict. The SDK has replaced this port with another port.

  • Function Prototype: int dunGetCurrentTCPPort(const char* ip, int port)
  • Parameters:Ip: The client connection IP in the forwarding rules, which is the IP starting with 127. port: The client connection port in the forwarding rules, which is the corresponding port of the IP starting with 127.
  • Return:The newly obtained port will be the same as the input port if there is no conflict or if the forwarding rules do not exist. If there is a conflict, the returned port will be the changed new port.

Below are the SDK function definitions corresponding to each system. For specific usage examples, please refer to the documentationDemo Advanced FeaturesThe code inside

Windows:
extern "C" CLINKAPI_API int dunGetCurrentTCPPort(const char* ip, int port);

android:
Class:cn.ay.clinkapi.Api
public native int dunGetCurrentTCPPort(String ip,int port);

iOS Static Library:
Class:ClinkAPI
int dunGetCurrentTCPPort(const char* ip, int port);

iOS Dynamic Library
extern "C" void dunGetCurrentTCPPort(int val).

Unity
Class:ClinkSDKForUnity
public static int dunGetCurrentTCPPort(string ip, int port)

Uni-app
Plugin Name: ayClinkApiForUni
Plugin Function: dunGetCurrentTCPPort(ip, port)

Get the current UDP corresponding port

Before establishing a new UDP connection, you need to call this function to get the new port corresponding to the port you are going to connect to, as your original port may have a conflict. The SDK has replaced this port with another port.

  • Function Prototype: int dunGetCurrentUDPPort(const char* ip, int port)
  • Parameters:Ip: The client connection IP in the forwarding rules, which is the IP starting with 127. port: The client connection port in the forwarding rules, which is the corresponding port of the IP starting with 127.
  • ReturnThe newly obtained port will be the same as the input port if there is no conflict or if the forwarding rules do not exist. If there is a conflict, the returned port will be the modified new port.

Below are the SDK function definitions corresponding to each system. For specific usage examples, please refer to the documentationDemo Advanced FeaturesThe code inside

Windows: 
extern "C" CLINKAPI_API int dunGetCurrentUDPPort(const char* ip, int port);

android: 
Class:cn.ay.clinkapi.Api
public native int dunGetCurrentUDPPort(String ip,int port);

iOS Static Library: 
 Class:ClinkAPI
int dunGetCurrentUDPPort(const char* ip, int port);

iOS Dynamic Library 
 extern "C" void dunGetCurrentUDPPort(int val).

Unity 
Class:ClinkSDKForUnity 
 public static int dunGetCurrentUDPPort(string ip, int port)

Uni-app 
Plugin Name: ayClinkApiForUni
Plugin Function: dunGetCurrentUDPPort(ip, port)

2. Other Functions

2.1 Get Client IP

This is used to obtain the client's current IP on the client side. The 'Get IP Method' in the forwarding rules is effective regardless of how it is set, as this interface retrieves the IP on the client side, while the forwarding rules are intended for the server side.They are unrelated, the obtained client IPs are the same.

For example, you can send the login information along with the client IP to the login server when the user logs in. This way, if your backend server has multiple forwarding instances, you can still obtain the client's real IP.

  • Function Prototype: long long dunGetClientIP()
  • Returns: A signed 64-bit little-endian integer IP value, which can be converted to a string format IP using other functions. A return value of 0 indicates that the shield has not been started or failed to start. Converts the integer IP to a string format IP. The algorithm code is as follows:::
string ipstr = ip / 256 / 256 / 256 % 256 + "." + ip / 256 / 256 % 256 + "." + ip / 256 % 256 + "." + ip % 256.

Below are the SDK function definitions corresponding to each system. For specific usage examples, please refer to the documentationDemo Advanced FeaturesThe code inside

Windows:
extern "C" CLINKAPI_API long long dunGetClientIP();

android:
Class:cn.ay.clinkapi.Api
public native long dunGetClientIP();

iOS Static Library:
Class:ClinkAPI
long long dunGetClientIP();

iOS Dynamic Library
extern "C" long long dunGetClientIP();

Unity
Class:ClinkSDKForUnity
public static long dunGetClientIP()

Uni-app
Plugin Name: ayClinkApiForUni
Plugin Function: dunGetClientIP()

Leave a Reply

Your email address will not be published. Required fields are marked *