NAME

connectionSetLimit - sets the limit value for a statistic.

SYNOPSIS

#include <game-carrier/server.h>

typedef GCT_INT (GC_CORE_API *ConnectionSetLimit)(
    GCT_INTPTR conn_handle,
    GCT_INT level,
    GCT_INT id,
    GCT_COUNTER_VALUE value);

typedef struct connectionSetLimit {
    /* ... Some fields ... */
    ConnectionSetLimit connectionSetLimit;
    /* ... Some fields ... */
}

Parameters:

  • conn_handle GCT_INTPTR Connection handle.
  • level GCT_INT Alarm level, GC_STAT_STATUS_YELLOW or GC_STAT_STATUS_RED.
  • id GCT_INT Identifies the statistic id.
  • value GCT_COUNTER_VALUE New limit value.

RETURN VALUE

Returns 0 on success and -1 on failure.

Returns an error code, such as EINVAL, if there are any invalid arguments in the call.

DESCRIPTION

The connectionSetLimit function is used to set the limit for the statistic.

The conn_handle parameter represents the connection handle, which is obtained from the on_connect call.

The level parameter indicates the alarm level and takes values from the gc_stat_status enum, with the following possibilities:

The id parameter represents the statistic ID, and it corresponds to an element from the gc_conn_stats enum. Possible values for id are:

The value parameter refers to the new limit value that will be set.

Each statistic has two alarm levels: YELLOW and RED. If a statistic enters the RED zone, the default action, usually closing the connection, is executed without any additional conditions. On the other hand, if a statistic enters the YELLOW zone, the on_issue function is called. The application can decide how to handle the connection issue in this case through its return value.

Users have the flexibility to set up the limit values either in a configuration file or via API calls. The conn_critical section is used to set RED zone limits, while the conn_notice section is used to set YELLOW zone limits. Both sections are placed in the root section of a configuration file. Additionally, users can override global settings for specific applications by placing them into the application configuration section. The connectionSetLimit API call allows applications to override default settings.

EXAMPLE

#include <game-carrier/server.h>

#include <stdlib.h>

/**
 * In the following example the application ignores the `max_msg_size`
 * issue for the first message. And closes the connection for the other messages.
 **/

struct core_api api;

struct connection_data {
    GCT_INTPTR handle;
    int message_count;
    /* user data asociated with connection */
};

GC_ADAPTER_EVENT
GCT_INT adapter_initialize(
    GCT_INT id,
    struct core_api * core_api,
    GCT_CPTR load_path)
{
    api = *core_api;
    return 0;
}

GC_ADAPTER_EVENT
GCT_INTPTR on_connect(
    GCT_INT app_id,
    GCT_INTPTR handle,
    GCT_INT pid,
    GCT_CSTR rip,
    GCT_INT rport,
    GCT_CSTR lip,
    GCT_INT lport,
    GCT_CSTR udata)
{
    /* Allocate user data */
    struct connection_data * conn = malloc(sizeof(struct connection_data));

    /* Out of memory, failed */
    if (conn == NULL) {
        return GC_DROP_CONNECTION;
    }

    /* Save connection handle */
    conn->handle = handle;

    /* Initialize message counter */
    conn->message_count = 0;

    /* Set limit for a connection */
    GCT_COUNTER_VALUE one_mb = 1024 * 1024;
    api.connectionSetLimit(conn, GC_STAT_STATUS_YELLOW, GC_CONN_STAT_MAX_MSG_SIZE, one_mb);

    /* initialize other fields */
    return (GCT_INTPTR)conn;
}

GC_ADAPTER_EVENT
void on_message(
    GCT_INTPTR user,
    GCT_PTR data,
    GCT_SIZE len)
{
    struct connection_data * conn = (struct connection_data *)user;

    /* Increase message counter for a connection */
    ++conn->message_count;

    /* Process message here ........... */
}

GC_ADAPTER_EVENT
GCT_INT on_issue(
    GCT_INTPTR user,
    GCT_INT id,
    GCT_COUNTER_VALUE value)
{
    struct connection_data * conn = (struct connection_data *)user;

    if (id != GC_CONN_STAT_MAX_MSG_SIZE) {
        /* Ignore everything that is not related to max_msg_size */
        return GC_STAT_REACTION_DEFAULT;
    }

    /* Check message_count to choose behaviour */
    /* Note that on_message is not called yet! */
    if (conn->message_count <= 0) {
        /* The counter is zero, this is a first message, ignore */
        return GC_STAT_REACTION_IGNORE;
    } else {
        /* The counter is non-zero, this is not a first message, close */
        return GC_STAT_REACTION_CLOSE;
    }
}

SEE ALSO

on_issue, on_connect, on_disconnect, on_message, gc_conn_stats, gc_stat_status