User Programs and Functions

This chapter describes how to modify custom.h, custom.c, and register.c to use the TCP/IP gateway.

1. Overview

Register TCPGW by configuring Tmax environment and then modify custom.h and custom.c to use TCPGW.

  1. In custom.h, modify the msg_header_t struct for TCPGW use.

    Since TCP/IP has no knowledge about the end or the destination of the transmitted data, it is difficult to process variable-length data. TCPGW uses the msg_header_t structure to configure the remote node and the message header so that the length of the actual data can be determined. The struct data includes the message header that is used between TCPGW and the remote node.

    When TCPGW receives data from the remote node, it first receives as much data as the length of msg_header_t. Next, it gets the length of the actual data in the msg_header_t, and then receives the actual data. The msg_header_t must be defined correctly for seamless communication.

    The user-defined msg_header_t information is only used for communication between TCPGW and the remote node and is not sent when the service is called.

  2. After modifying custom.h, modify custom.c accordingly. There are various user-defined functions in custom.c, and each are described in detail in custom.c.

  3. Link and compile the custom.h, custom.c, TCPGW library, and register.c files to complete TCPGW configuration.

    The execution file name created here must be the same as the name registered in the SERVER section of the Tmax environment file.

2. custom.h

custom.h is a file that includes the msg_info_t struct used in TCPGW, and the user can modify message structs or headers that need to be communicated between the remote node and TCPGW.

Member variables, types, length, etc. must not be modified since msg_info_t struct is used within the TCPGW library and between user functions.

  • msg_info_t

    This struct is used in the TCPGW library and the user-defined functions in the custom.c file. In the custom.c file, the struct value must be set in the get_msg_info() function which is called immediately after the message is received from the remote node.

    The data sent to the remote node must be set to the struct value in the put_msg_info() function which is called immediately before the message is sent to the remote node. For detailed information about how to implement the get_msg_info() and put_msg_info() functions, refer to custom.c.

    The msg_info_t struct used in TCPGW is as follows:

    typedef struct msg_info {
        char  svc[20];
        int   err;
        int   len;
        int   uid;
        int   flags;               /* Configure flags, e.g., TPNOREPLY. */
        int   msgtype;
        int   channel_id;
    } msg_info_t;

    The following describes the members of the msg_info struct.

    Member Description

    char svc[20]

    Service name that TCPGW uses to call the service when it is requested from the remote service.

    int err

    Error status during service request or reply data transmission.

    int len

    Length of the sent/received data.

    int uid

    UID generated by TCPGW during synchronous communication.

    int flags

    Used when a service is requested from the remote node to Tmax.

    • NOFLAGS: When receiving reply for the service requested from the remote node.

    • TPNOREPLY: When only requesting the service without receiving the reply. (same as TPNOREPLY for Tmax tpacall).

    int msgtype

    Currently not used.

    int channel_id

    Sending/receiving channel number.

  • msg_header_t

    In custom.h, the message header data struct transmitted between the remote node and TCPGW must be defined.

    The following shows the message header struct used in TCPGW.

    typedef struct msg_header {
        int   length;
    } msg_header_t;

    Since TCPGW first reads data up to the length of msg_header_t when receiving a message, it is not recommended to include excessively large data in this structure. This may exceed the TCPGW’s receive buffer size and may lead to memory corruption in some situations. The msg_header_t struct should define only fields at the message metadata level, if possible.

3. custom.c

The custom.c file must be implemented to allow communication between the remote node and TCPGW. It must be compiled with the TCPGW library (libtcpgw.a, libtcpgw.so). The custom.c file must be implemented according to the following define format.

  • Variables

    The following variables must be defined in custom.c.

    • msg_header_size

      Variable used within the library as the user-defined message header size. It must be set to the user-defined message header size as follows:

      int msg_header_size = sizeof(msg_header_t);
    • comm_header_size

      If msg_header_size is set to 0, this variable is used as the msg_header_size. The msg_header_size overrides this value if they are both defined.

      int comm_header_size = 0;
  • Functions

    The following describes the functions that must be implemented in custom.c.

    Function Description

    init_remote_info

    This function is called before connecting to the remote node.

    remote_connected

    This function is called after connecting to the remote node.

    remote_connected_ipv6

    This function is called after connecting to the remote node in the IPv6 protocol environment.

    remote_closed

    This function is called after disconnecting from the remote node.

    allow_connection

    This function is called before a new connection is made with the remote node. The return value determines whether to allow the requested connection.

    allow_connection_ipv6

    This function is called before the remote node and a new connection is made in the IPv6 protocol environment. Whether to allow the requested connection can be determined by the return value.

    get_msg_length

    When a request or a reply is received from the remote node, this function continuously reads as much data as specified by the return value.

    get_msg_info

    This function references or processes the info used as an interface between the TCPGW library and custom.c after reading request/reply data from the remote node.

    get_channel_num

    This function allows the user to select the channel when sending data from a Tmax service or client to the remote node.

    put_msg_info

    This function is called when a message is sent to the remote node.

    put_msg_complete

    This function is called after a message is sent to the remote node.

    get_service_name

    This function is configured according to the error code of the service name to tpreply() or tpacall() to.

    prepare_shutdown

    This function is called immediately before TCPGW shut downs.

    set_service_timeout

    This function can be called when there is a service timeout.

    chk_end_msg

    This function can be called when there is a bit stream or a special character that indicates the end of data that is received from the remote node.

    inmsg_recovery

    This function is called when an error occurs while processing a request from the remote node.

    outmsg_recovery

    This function is called when an error occurs while sending a request to the remote node.

    get_extmsg_info

    Similar to get_msg_info except for some functionality.

    put_extmsg_info

    Similar to put_msg_info except for some functionality.

    set_ping_msg

    User-defined function that can configure settings, interval, and timeout for messages sent to check for channel errors.

    chk_pong_msg

    User-defined function that checks the channel error monitoring response message status.

    set_extping_msg

    This function configures the message that is sent to detect for channel errors on the server.

    chk_extpong_msg

    This function checks messages received from the server to detect a channel error.

    reset_ping_msg

    This function is called periodically to reset TCP/IP Ping (channel error detection) message and its status.

    reset_extping_msg

    Similar to reset_ping_msg except for some functionality.

    set_error_msg

    This function is automatically called when there’s an error during transaction with the remote node.

    get_msg_security

    This function can process data after get_msg_info is called.

    put_msg_security

    This function can process data before put_msg_info is called.

    Examples of the functions described in this section are described in Examples.

3.1. init_remote_info

The init_remote_info function is called before connecting to the remote node. It is called only once, immediately after TCPGW is initialized. If the shared memory key is configured using the [-k ] option of CLOPT in the Tmax environment file, the logic that creates shared memory to save connection information can be implemented. The implementation can be omitted in some cases.

  • Prototype

    int init_remote_info(char *myname, int mynumber, int num_channel, int key)
  • Parameter

    Parameter Description

    myname

    TCPGW server name.

    mynumber

    TCPGW process number used to identify each process when multiple TCPGW are run simultaneously. The number starts from 0.

    num_channel

    Max number of channels connected to TCPGW. This is the sum of the values set using the [-n], and [-N ] options in the Tmax environment file.

    key

    Shared memory key value set using the [-k ] option in the Tmax environment file.

3.2. remote_connected

The remote_connected function is called after connecting to the remote node, and it implements post connection processing. The function is called as many times as the channel count, and it is also called when the channel is reconnected after being disconnected.

  • Prototype

    int remote_connected(int index, int addr, int portno, int type, int fd)
  • Parameter

    Parameter Description

    index

    Index value of each channel when TCPGW is connected to multiple channels using the [-n] or [-N] option.

    addr

    Remote node address.

    portno

    Port number of the connected server. If TCPGW runs in the client mode, then this is the remote node’s port number. If TCPGW runs in the server mode, then this is the port number of the listening socket.

    type

    Channel type connected to the remote node. Either IN_CHANNEL or OUT_CHANNEL.

    fd

    Socket number connected to the remote node.

3.3. remote_connected_ipv6

The remote_connected_ipv6 function is called after connecting to the remote node in the IPv6 protocol environment, and it implements post connection processing. The function is called as many times as the channel count, and it is also called when the channel is reconnected after being disconnected.

In the IPv6 environment, the remote_connected_ipv6 callback function must be configured instead of the remote_connected callback function. If not, the remote_connected function is called, and the ipaddr is set to a random value and a warning message is recorded in the slog.

  • Prototype

    #include <arpa/inet.h>
    int remote_connected_ipv6(int index, struct sockaddr *saddr, int portno, int type, int fd)
  • Parameter

    Parameter Description

    index

    Index value of each channel when TCPGW is connected to multiple channels using the [-n] or [-N] option.

    saddr

    Remote node address and port number. Must be casted as the sockaddr struct type suitable for the IPv4 or IPv6 protocol environment.

    portno

    Port number of the connected server. If TCPGW runs in the client mode, then this is the remote node’s port number. If TCPGW runs in the server mode, then this is the port number of the listening socket.

    type

    Channel type connected to the remote node. Either IN_CHANNEL or OUT_CHANNEL.

    fd

    Socket number connected to the remote node.

  • Example

    int
    remote_connected_ipv6(int index, struct sockaddr *saddr, int portno, int type, int fd)
    {
        char buf[INET6_ADDRSTRLEN];
        char *ipaddr = NULL;
        int cli_portno;
    
        if (index < 0)
            return -1;
    
        if (saddr->sa_family == AF_INET6) {
            ipaddr = (char *)inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)saddr)->sin6_addr), buf, sizeof(buf));
            cli_portno = ntohs(((struct sockaddr_in6 *)saddr)->sin6_port);
        } else if (saddr->sa_family == AF_INET) {
            ipaddr = (char *)inet_ntop(AF_INET, &(((struct sockaddr_in *)saddr)->sin_addr), buf, sizeof(buf));
            cli_portno = ntohs(((struct sockaddr_in *)saddr)->sin_port);
        }
        if (ipaddr == NULL)
            ipaddr = "unknown";
    
        printf("remote_connected_ipv6, REMOTE[%d] IPADDR[%s] CLIPORT[%d] SVRPORT[%d] TYPE[%d] fd[%d] connected\n",
                index, ipaddr, cli_portno, portno, type, fd);
    
        return 1;
    }

3.4. remote_closed

The remote_closed function is called after disconnecting from the remote node, and it implements post disconnection processing. When the logic that creates the shared memory is implemented in the init_remote_info function, the logic that releases the shared memory is implemented in this function. The function is called as many times as the channel count.

  • Prototype

    int remote_closed(int index, int type)
  • Parameter

    Parameter Description

    index

    Index value for each channel when TCPGW is connected to multiple channels with the [-n] option or the [-N] option.

    type

    Channel type connected to the remote node. Either IN_CHANNEL or OUT_CHANNEL.

3.5. allow_connection

When the remote node attempts to connect to TCPGW or when TCPGW attempts to connect to the remote node and succeeds, the allow_connection function is called before the remote_connected() callback function is called. This function determines whether connection with the remote is allowed.

  • Prototype

    int allow_connection(int addr, int portno, int type, int fd)
  • Parameter

    Parameter Description

    addr

    Remote node address.

    portno

    Port number of the connected server. If TCPGW runs in the client mode, then this is the remote node’s port number. If TCPGW runs in the server mode, then this is the port number of the listening socket.

    type

    Channel type connected to the remote node. Either IN_CHANNEL or OUT_CHANNEL.

    fd

    Socket number connected to the remote node.

  • Return Value

    Value Description

    1

    Allows connection requests with the remote node.

    Negative Number

    Does not allow connection with the remote node.

  • Example

    int allow_connection(int addr, int portno, int type, int fd)
    {
        int i, n, len;
        struct in_addr in;
        char *ipaddr, *endptr;
        char *deny[] = {"10.10.30.1",
                        "121.100.100.*",
                        NULL};
    
        if (addr == -1)
            return -1;
        in.s_addr = addr;
        ipaddr = inet_ntoa(in);
    
        for (i = 0; deny[i] != NULL; i++) {
            if ((endptr = strpbrk(deny[i], "*")) != NULL) {
                if (strncmp(deny[i], ipaddr, (endptr - deny[i])) == 0)
                    return -1;
            } else {
                if (strcmp(deny[i], ipaddr) == 0)
                    return -1;
            }
        }
        return 1;
    }

3.6. allow_connection_ipv6

When the remote node attempts to connect to TCPGW in the IPv6 protocol environment or when TCPGW successfully connects to the remote node, the allow_connection_ipv6 function is called before the remote_connected() callback function is called. This function determines whether to allow connection with the remote.

In the IPv6 environment, the allow_connection_ipv6 callback function must be configured instead of the allow_connection callback function. If not, the allow_connection function is called, and the ipaddr is set to a random value and a warning message is recorded in the slog.

  • Prototype

    #include <arpa/inet.h>
    
    int allow_connection(struct sockaddr *saddr, int portno, int type, int fd)
  • Parameter

    Parameter Description

    saddr

    Remote node address and port number. Must be casted as the sockaddr struct type suitable for the IPv4 or IPv6 protocol environment.

    portno

    Port number of the connected server. If TCPGW runs in the client mode, then this is the remote node’s port number. If TCPGW runs in the server mode, then this is the port number of the listening socket.

    type

    Channel type connected to the remote node. Either IN_CHANNEL or OUT_CHANNEL.

    fd

    Socket number connected to the remote node.

  • Return Value

    Value Description

    1

    Allows connection request with the remote node.

    Negative Number

    Does not allow connection with the remote node.

  • Example

    int
    allow_connection_ipv6(struct sockaddr *saddr, int svr_portno, int type, int fd)
    {
        char buf[INET6_ADDRSTRLEN];
        char *ipaddr;
        int cli_portno;
    
        int i, n, len;
        char *endptr;
        char *allow[] = {"10.10.30.1",
                        "121.100.100.*",
                        NULL};
    
        if (saddr->sa_family == AF_INET6) {
            ipaddr = (char *)inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)saddr)->sin6_addr), buf, sizeof(buf));
            cli_portno = ntohs(((struct sockaddr_in6 *)saddr)->sin6_port);
        } else if (saddr->sa_family == AF_INET) {
            ipaddr = (char *)inet_ntop(AF_INET, &(((struct sockaddr_in *)saddr)->sin_addr), buf, sizeof(buf));
            cli_portno = ntohs(((struct sockaddr_in *)saddr)->sin_port);
        }
        if (ipaddr == NULL)
            ipaddr = "unknown";
    
        for (i = 0; allow[i] != NULL; i++) {
            if ((endptr = strpbrk(allow[i], "*")) != NULL) {
                if (strncmp(allow[i], ipaddr, (endptr - deny[i])) == 0)
                    return 1;
            } else {
                if (strcmp(allow[i], ipaddr) == 0)
                    return 1;
            }
        }
        return -1;
    }

3.7. get_msg_length

The get_msg_length function is called after receiving the msg_header_t part (reads as much data as specified in the msg_header_size or comm_header_size) of a request or reply through the channel from the remote node. As much data as specified by the can be called is read.

  • Prototype

    int get_msg_length(msg_header_t *hp)
  • Parameter

    Parameter Description

    hp

    Pointer to the msg_header_t struct which can be defined in custom.h. As much data as specified by the header size is read in, and then the actual data is read in using the data length defined in the header.

  • Return Value

    Length of the actual data from the remote node. TCPGW reads the actual data from the remote node using the can be called of the function. The header can be checked for errors. If there is an error, return -2 to terminate the channel.

3.8. get_msg_info

The get_msg_info function processes the data received from the remote node before forwarding the request or reply to the Tmax service program. This function can also reference or process the information (uid, len, flags, service name, etc.) required to interface between the TCPGW library and custom.c.

  • Prototype

    int get_msg_info(msg_header_t *hp, char *data,msg_info_t *info)
  • Parameter

    Parameter Description

    hp

    Pointer to the message header read from the remote node. Same as the struct used in get_msg_length.

    data

    Data part read from the remote node.

    info

    Struct that interfaces between the TCPGW library (libtcpgw.a, libtcpgw.so) and custom.c. Set various data to the info struct using the received data.

  • Return Value

    Message type to send to Tmax service. TCPGW uses this value to determine what needs to be processed. For example, REMOTE_REQUEST indicates that there is a request from the remote node, and REMOTE_REPLY is a value that is returned when the remote node sends a response for the request from the Tmax service.

    REMOTE_REPLY_CONT is a value returned when response messages are received in succession, REMOTE_SENDTOCLI is the value returned for an unrequested message.

    If -1 is returned and the -e option is configured in the CLOPT section of the environment file, then the channel is terminated.

    When a response is received from the remote node, the UID value must be set to the uid in the info struct. Other values must also be set appropriately.

3.9. get_channel_num

The get_channel_num function allows the user to select a channel when the data requested from the Tmax service or client is sent to the remote node. The sending channel can be specified according to the characteristics of the data, and it is simply the channel number not the socket number connected to the remote node. TCPGW returns an error if the channel specified by the user cannot be used.

  • Prototype

    int get_channel_num(char *data)
  • Parameter

    Parameter Description

    data

    Data to send to the remote node.

  • Return Value

    Channel number.

3.10. put_msg_info

The put_msg_info function is called when sending a message to the remote node. For synchronous communication, the user must save the UID in the message. The UID can be set to the value of the uid in the info struct, or the user can create a UID and then set it to the uid in the info struct.

The user must set an appropriate value to each member of the msg_header_t struct. Since the struct value can be set to by the user, TCPGW does not store any values in the struct of the msg_header_t.

  • Prototype

    int put_msg_info(msg_header_t *hp, char *data, msg_info_t *info)
  • Parameter

    Parameter Description

    hp

    Message header to send to the remote node.

    data

    Data to send to the remote node.

    info

    Data information to send to the remote node.

  • Return Value

    Total length of the data to send to the remote node, which includes the lengths of the message header and the actual data.

3.11. put_msg_complete

The put_msg_complete function is called after a message is sent to the remote node to notify that the data has been successfully sent to the remote node.

  • Prototype

    int put_msg_complete(msg_header_t *hp, char *data, msg_info_t *info)
  • Parameter

    Parameter Description

    hp

    Message header to send to the remote node.

    data

    Data to send to the remote node.

    info

    Data information to send to the remote node.

3.12. get_service_name

When configuring a non-blocking or asynchronous TCPGW that uses separate servers for sending and receiving a request/request to/from the remote node, this function configures the name of the service to tpreply() or tpacall() according to the error code.

  • Prototype

    int get_service_name(char *header, int err, char *svc)
  • Parameter

    Parameter Description

    header

    Pointer to the user header stored in TCPGW configured using the [-H] or [-h] option.

    err

    Error code.

    svc

    Name of the service that receives tpreply() or tpacall().

3.13. prepare_shutdown

The prepare_shutdown function is called before TCPGW shuts down and it generally releases the shared memory created in the init_remote_info() function.

  • Prototype

    int prepare_shutdown(int code)
  • Parameter

    Parameter Description

    code

    Termination code. Currently not in use.

3.14. set_service_timeout

The set_service_timeout function can be called when a service timeout occurs.

  • Prototype

    int set_service_time_out(int uid, char *header)
  • Parameter

    Parameter Description

    uid

    User ID of the transaction where the service timeout occurred.

    header

    Header of the transaction where the service timeout occurred.

3.15. chk_end_msg

The chk_end_msg function can be called by the user (if the CLOPT -i option is specified) when there is a bit stream or a special character indicating the end of data received from the remote node.

After processing the initial segment of the data, check_end_msg() is called again for the remaining segment. At this time, the user can implement the function to return -1 if the remaining data is incomplete. When additional data is received from the other channel, the previous data and the newly received data are merged and check_end_msg() is called.

  • Prototype

    int chk_end_msg(int len, char *data)
    {
      printf("chk_end_msg len(%d), data(%.*s)\n", len, len, data);
      if (len >= 10)
        return 10;
      else
        return -1;
    }
  • Parameter

    Parameter Description

    len

    Length of the data read from the remote node.

    data

    Data part read from the remote node.

3.16. inmsg_recovery

This function is called when an error is returned because the server is not running when a request from the remote node is processed via tpacall (…​, TPBLOCK). The user can create a new data inside this function and return the data size.

  • Prototype

    int inmsg_recovery(char *data, msg_info_t *info)
  • Parameter

    Parameter Description

    data

    Data part read from the remote node.

    info

    Data information read from the remote node. Meaningful values are as follows.

    • info→svc: Service name that initiated tpacall().

    • info→len: Length of the data for the tpacall().

    • info→err: When there is an error.

    • tperrno info→uid: UID value created during the previous get_msg_info() call.

  • Return Value

    Length of the newly created data.

    Value Description

    Positive Number

    • When a value exists in info→svc: send a tpacall (…​, TPNOREPLY) to the service.

    • Other situations: Send a reply to the remote node.

    Negative Number

    Discard the data.

3.17. outmsg_recovery

The outmsg_recovery function is called when there is an error while sending a request to the remote node. The user can create a new data inside the function, set the desired service name and UID, and return the data size.

  • Prototype

    int inmsg_recovery(char *data, msg_info_t *info)
  • Parameter

    Parameter Description

    data

    User data used in the data argument of the put_msg_info() callback function.

    info

    Data used in the msg_info_t argument of the put_msg_info() callback function. Meaningful values are as follows:

    • info→svc: When calling a callback function, this is set to an empty value. If you specify a service name for this value within the callback function, a message is sent to the specified service in the tpacall(TPNOREPLY) format.

    • info→err: When calling a callback function, the TPESYSTEM error code is set. If this value is set to 0 within the callback function, a normal return is made to the caller. Otherwise, if info→svc is not specified, the TPESVCFAIL error is returned to the caller.

  • Return Value

    Value Description

    Negative Number

    Unconditionally returns a TPESYSTEM error to the caller without checking the settings of the info struct.

    Positive Number

    Checks the settings of the info struct and processes the message in the manner described in the parameter.

3.18. get_extmsg_info

The get_extmsg_info function is similar to the get_msg_info function except that the user can reallocate the buffer memory (realloc) by passing the data buffer as a double pointer type. To use this function with the get_msg_info() function, -D_TCPGW_USE_EXTMSG flags must be configured when compiling TCPGW.

  • Prototype

    int get_extmsg_info(msg_header_t *hp, char **data, int asize, msg_info_t *info)
  • Parameter

    Parameter Description

    hp

    Pointer to the message header data read from the remote node. Same as the struct used in get_msg_length().

    data

    Address of the data buffer read from the remote node.

    asize

    Memory size allocated to the data buffer read from the remote node.

    info

    Struct that interfaces between the TCPGW library (libtcpgw.a, libtcpgw.so) and custom.c. Set various data to the info struct using the received data.

  • Return Value

    Message type to send to Tmax service. TCPGW uses this value to determines what needs to be processed. For example, REMOTE_REQUEST indicates that there is a request from the remote node, and REMOTE_REPLY is a value that is returned when the remote node sends a response for the request from the Tmax service.

    REMOTE_REPLY_CONT is a value returned when response messages are received in succession, REMOTE_SENDTOCLI is the value returned for an unrequested message.

    When a response is received from the remote node, the UID value must be set to the uid in the info struct. Other values must also be set appropriately.

3.19. put_extmsg_info

The put_extmsg_info function is similar to the put_msg_info function except that the user can reallocate the buffer memory (realloc) by passing the data buffer as a double pointer type. To use this function with the put_msg_info() function, -D_TCPGW_USE_EXTMSG flags must be configured when compiling TCPGW.

  • Prototype

    int put_extmsg_info(msg_header_t *hp, char **data, int asize, msg_info_t *info)
  • Parameter

    Parameter Description

    hp

    Pointer to the message header data to send to the remote node. Same as the struct used in put_msg_length().

    data

    Address of the data buffer to send to the remote node.

    asize

    Memory size allocated to the data buffer to send to the remote node.

    info

    Information about the data to send to the remote node.

  • Return Value

    Total length of the data to send to the remote node, which includes the lengths of the message header and the actual data.

3.20. set_ping_msg

The set_ping_msg function is a user-defined function that can configure settings, interval, and timeout for messages sent to check for channel errors. It must be configured when the [-x] option is specified. This function is called only once when the TCPGW program is started.

  • Prototype

    int set_ping_msg(msg_header_t *hp, int *interval, int *binterval, int *timeout,
                     int *mode)
  • Parameter

    Parameter Description

    hp

    Message periodically sent to monitor channel errors. Required.

    interval

    Interval for monitoring channel errors. If set to 0, the channel error monitoring function is disabled. (Unit: seconds)

    binterval

    Interval for checking the main channel status while in the backup channel mode. If set to 0, the status checking function is disabled. (Unit: seconds)

    timeout

    Timeout for channel error monitoring. When a reply is not received within this time, the channel is disconnected. (Unit: seconds). The channel is actually disconnected before reset_ping_msg() is called when sending the ping message at the specified interval.

    If set to 0, only ping message is sent and pong message is ignored (monitors half duplex errors).

    mode

    Channel types for monitoring errors.

    • 0 : OUT channel

    • 1 : IN channel

    • 2 : All channels

  • Return Value

    When there is an error, a negative value must be returned which disables the monitoring function.

3.21. chk_pong_msg

The chk_pong_msg function checks for reply messages for monitoring channel errors from the remote node.

  • Prototype

    int chk_pong_msg(msg_header_t *hp)
  • Parameter

    Parameter Description

    hp

    Message received from the remote.

  • Return Value

    Return Value Description

    Positive Number

    When the message from the remote server is a normal channel error monitoring reply message.

    0

    When the message from the remote server is a general message, not a channel error monitoring reply message. Such message is processed in the get_msg_info function.

    Negative Number

    When the message from the remote server is an abnormal channel error monitoring reply message.

3.22. set_extping_msg

The set_extping_msg function can configure the message for monitoring channel errors, or the message period, timeout, etc. This function must be configured when the [-x] option is specified. This function is called only once when the TCPGW program is started.

  • Prototype

    int set_extping_msg(msg_header_t *hp, char *data, int len, int *interval,
                        int *binterval, int *timeout, int *mode)
  • Parameter

    Parameter Description

    hp

    Message periodically sent to monitor channel errors. Required.

    data

    Message body that follows the error monitoring message (hp). Optional.

    len

    Maximum length of the error monitoring message body. Configure the maximum length with the [-b] option. Default value: 0

    interval

    Interval for monitoring channel errors. If set to 0, the channel error monitoring function is disabled. (Unit: seconds)

    binterval

    Interval for checking the main channel status while in the backup channel mode. If set to 0, the status checking function is disabled. (Unit: seconds)

    timeout

    Timeout for channel error monitoring. When a reply is not received within this time, the channel is disconnected. (Unit: seconds). The channel is actually disconnected before reset_ping_msg() is called when sending the ping message at the specified interval.

    If set to 0, only ping message is sent and pong message is ignored (monitors half duplex errors).

    mode

    Channel types for monitoring errors.

    • 0 : OUT channel

    • 1 : IN channel

    • 2 : All channels

  • Return Value

    Value Description

    0

    When the function has been successfully performed.

    Negative Number

    When the function has failed to be performed.

  • Example

    int set_extping_msg(msg_header_t *hp, char *data, int len, int *interval,
                        int *binterval, int *timeout, int *mode)
    {
            msg_body_t *body;
    
            body = (msg_body_t *)data;
            memset(body->data, 0x00, 52);
    
            memcpy(body->data, "tmax50", 7);
            body->data[51] = 0;
            printf("set_extping_msg : data = %s\n", body->data);
    
            hp->len = 7;
            *interval = 10;
            *binterval = 20;
            *timeout = 100;
            *mode = 0; /* OUTBOUND CHANNEL */
    
            return 1;
    }

3.23. chk_extpong_msg

The chk_extpong_msg function checks messages received from the server to detect a channel error.

  • Prototype

    int chk_extpong_msg(msg_header_t *hp, char *data, int len)
  • Parameter

    Parameter Description

    hp

    Message header received from the remote server when a channel error is detected.

    data

    Message body received from the remote server when a channel error is detected.

    len

    Length of the message body.

  • Return Value

    Value Description

    Positive Number

    When the message from the remote server is a normal channel error monitoring reply message.

    0

    When the message from the remote server is a regular message, not a channel error monitoring reply message. Such message is processed in the get_msg_info function.

    Negative Number

    When the message from the remote server is an abnormal channel error monitoring reply message.

  • Example

    int chk_extpong_msg(msg_header_t *hp, char *data, int len)
    {
            msg_body_t *body;
            char data2[15];
    
            body = (msg_body_t *)data;
            printf("chk_extpong_msg : data = %s\n", body->data);
    
            if (strcmp(body->data, "ping_reply")
                    return 1;
            return 0;
    }

3.24. reset_ping_msg

The reset_ping_msg function is called periodically to determine whether to send the channel error monitoring (TCP/IP ping) message, and to reconfigure the message.

Before the ping message is sent to the remote server according to the interval cycle set using the set_ping_msg function, this function is called to check and optionally modify the sent message. It also decides whether to send the ping message to the remote server according to the return value.

  • Prototype

    int reset_ping_msg(msg_header_t *hp)
  • Parameter

    Parameter Description

    hp

    Message header to send to monitor channel errors. The message header set using the set_ping_msg function is the default value.

  • Return Value

    Value Description

    Positive Number

    Ping message is sent to the remote server.

    Negative Number

    Ping message is not sent to the remote server.

  • Example

    int reset_ping_msg(msg_header_t *hp)
    {
            hp->len = 0;
            hp->msgtype = HEALTH_CHECK;
            return 1;
    }

3.25. reset_extping_msg

The reset_extping_msg function is called periodically to determine whether to send the channel error monitoring (TCP/IP ping) message, and to reconfigure the message.

Before the ping message is sent to the remote server according to the interval cycle set using the set_ping_msg function, this function is called to check and optionally modify the sent message. It also decides whether to send the ping message to the remote server according to the return value.

  • Prototype

    int reset_extping_msg(msg_header_t *hp, char *data, int len)
  • Parameter

    Parameter Description

    hp

    Message header to send to monitor channel errors. The message header set using the set_ping_msg function is the default value.

    data

    Pointer to the message body to reconfigure. Max buffer size is set in len. The return value is set to the actual buffer size.

    len

    Maximum available message body size.

  • Return Value

    Value Description

    Positive Number

    Ping message is sent to the remote server with the specified size of the message body.

    0

    Ping message is sent to the remote node without the message body.

    Negative Number

    Ping message is not sent to the remote node.

  • Example

    int reset_extping_msg(msg_header_t *hp, char *data, int len)
    {
            int body_len;
            char *message = "reset_msg";
    
            body_len = min(len, strlen(message));
            strncpy(data, message, (body_len - 1));
            data[(body_len - 1)] = '\0';
            hp->len = body_len;
            printf("reset_extping_msg : data = %s\n", data);
    
            return body_len;
    }

3.26. set_error_msg

The set_error_msg function is automatically called when there is an error, such as timeout or network disconnection, during transaction with the remote node via TCPGW. The user can modify the user header or the user data in the function.

  • Prototype

    int set_error_msg(msg_header_t *hp, int err, char *data, int len)
  • Parameter

    Parameter Description

    hp

    Message header that was sent when an error occurred. Can be modified by the user.

    data

    Data that was sent when an error occurred. Can be modified by the user.

    len

    Message body length.

  • Return Value

    Value Description

    Positive Number

    Sends as much data as the returned length. CLOPT="-I" option must be configured.

    0

    Only up to the user header part has been sent.

    Negative Number

    Message is not sent to CLH.

  • Error

    Error Code Description

    [TPECLOSE]

    Occurs when the connection to the remote node is broken after requesting a service to the remote node.

    [TPENOENT]

    When the [-E] option is used, a connection is made and data is sent to the remote node at every service request. This error occurs when the number of simultaneous calls exceeds the max number of channels set with the [-n] option.

    [TPENOREADY]

    Occurs when there is no available channel due to being disconnected with the remote node.

    [TPEOS]

    Occurs when memory cannot be allocated although it has been allocated in TCPGW.

    [TPEPROTO]

    Occurs when TCPGW is in the asynchronous mode instead of synchronous mode when TCPGW is called via tpforward. The tpforward & tprelay methods must be in synchronous mode.

    [TPESVCERR]

    Occurs when 0 or a negative number is returned from put_msg_info.

    [TPESYSTEM]

    Occurs when the map file for the requested data is not loaded when using code conversion in TCPGW. This error also occurs when data is sent to the remote node when a negative number is returned by put_msg_info due to a code conversion error.

    [TPETIME]

    Occurs when there is no reply within the specified time for a service requested to the remote node.

  • Example

    int set_error_msg(msg_header_t *hp, int err, char *data, int len)
    {
         msg_body_t * body;
         body = (msg_body_t *)data;
         strcpy(body->data, "changed hello data");
         /* Since data is not included in the error message,
           -1 option must be used to also send the data part.
           Otherwise, only user header part is sent to CLH.   */
         /* The hp and data values can be same without the user header. */
         strcpy(hp->retsvcname, "RECVSVC_CHANGE");
         return len;
    }

3.27. get_msg_security

The get_msg_security function is called to process user data after executing the get_msg_info() or get_extmsg_info() function. The get_extmsg_info() function can replace this function.

  • Prototype

    int get_msg_security(char **data, int asize, int len)
  • Parameter

    Parameter Description

    data

    Data buffer address read from the remote node. If the buffer size is insufficient, then the buffer size can be extended using realloc(). If the buffer pointer is changed by calling realloc(), the changed pointer address must be saved in this parameter.

    asize

    Memory size allocated to the data buffer read from the remote node.

    len

    Message body length.

  • Return Value

    Value Description

    Positive Number

    Total length of the processed user data.

    0

    Does not apply user data changes.

  • Example

    int get_msg_security(char **data, int asize, int len)
    {
         ...
         new_size = len * 2;
         if (new_size > asize) {
             tmpbuf = (char *)realloc(*data, new_size);
             if (tmpbuf == NULL) {
                 /* error processing */
             }
             *data = tmpbuf;
         }
         ...
         return new_size;
    }

3.28. put_msg_security

The put_msg_security function is called to process user data before executing the put_msg_info() or the put_extmsg_info() function. The put_extmsg_info() function can replace this function.

  • Prototype

    int put_msg_security(char **data, int asize, int len)
  • Parameter

    Parameter Description

    data

    Data buffer address to send to the remote node. If the buffer size is insufficient, then the buffer size can be extended using realloc(). If the buffer pointer is changed by calling realloc(), the changed pointer address must be saved in this parameter.

    asize

    Memory size allocated to the data buffer to send to the remote node.

    len

    Message body length.

  • Return Value

    Value Description

    Positive Number

    Total length of the processed user data.

    0

    Does not apply user data changes.

  • Example

    int put_msg_security(char **data, int asize, int len)
    {
         ...
         new_size = len * 2;
         if (new_size > asize) {
             tmpbuf = (char *)realloc(*data, new_size);
             if (tmpbuf == NULL) {
                 /* error processing */
             }
             *data = tmpbuf;
         }
         ...
         return new_size;
    }

4. register.c

This is the user function registration file. Only registered functions can be called from the gateway library. When the gateway is compiled, register.c must be included. Unused functions can be registered as NULL.

The following is an example of a register.c file.

/* --------------------- tcpgw register.c ------------------------ */
#include <stdio.h>
#include <arpa/inet.h>
#include "custom.h"

extern int _tcpgw_regfn_init();
extern int _tcpgw_regfn(int type, void *regFn);

extern int init_remote_info(char *myname, int mynumber, int num_channel, int key);
extern int prepare_shutdown(int code);
extern int remote_connected(int index, int addr, int portno, int type, int fd);
extern int remote_connected_ipv6(int index, struct sockaddr *saddr, int portno, int type, int fd);
extern int remote_closed(int index, int type);
extern int get_msg_length(msg_header_t * hp);
extern int get_msg_info(msg_header_t * hp, char *data, msg_info_t * info);
extern int put_msg_info(msg_header_t * hp, char *data, msg_info_t * info);
extern int put_msg_complete(msg_header_t * hp, char *data, msg_info_t * info);
extern int get_channel_num(char *data);
extern int get_service_name(char *header, int err, char *svc);
extern int set_service_timeout(int uid, char *header);
extern int get_msg_security(char **data, int asize, int len);
extern int put_msg_security(char **data, int asize, int len);
extern int chk_end_msg(int len, char *data);
extern int get_extmsg_info(msg_header_t * hp, char **data, int asize, msg_info_t * info);
extern int put_extmsg_info(msg_header_t * hp, char **data, int asize, msg_info_t * info);
extern int inmsg_recovery(char *data, msg_info_t * info);
extern int outmsg_recovery(char *data, msg_info_t * info);
extern int set_ping_msg(msg_header_t * hp, int *interval, int *bintrval, int *timeout, int *mode);
extern int chk_pong_msg(msg_header_t * hp);
extern int set_extping_msg(msg_header_t * hp, char *data, int len, int *interval, int *bintrval, int *timeout, int *mode);
extern int chk_extpong_msg(msg_header_t * hp, char *data, int len);
extern int reset_ping_msg(msg_header_t * hp);
extern int reset_extping_msg(msg_header_t * hp, char *data, int len);
extern int set_error_msg(msg_header_t * hp, int err, char *data, int len);
extern int allow_connection(int addr, int portno, int type, int fd);
extern int allow_connection_ipv6(struct sockaddr *saddr, int portno, int type, int fd);

/**************************************************************************
 *  int
 *  _register_custom()
 *
 *      returns no used
 *      [function number]
 *        1.  init_remote_info
 *        2.  prepare_shutdown
 *        3.  remote_connected
 *        4.  remote_closed
 *        5.  get_msg_length
 *        6.  get_msg_info
 *        7.  put_msg_info
 *        8.  put_msg_complete
 *        9.  get_channel_num
 *        10. get_service_name
 *        11. set_service_timeout
 *        12. get_msg_security
 *        13. put_msg_security
 *        14. chk_end_msg
 *        15. get_extmsg_info
 *        16. put_extmsg_info
 *        17. inmsg_recovery
 *        18. outmsg_recovery
 *        19. set_ping_msg
 *        20. chk_pong_msg
 *        21. set_extping_msg
 *        22. chk_extpong_msg
 *        23. reset_ping_msg
 *        24. reset_extping_msg
 *        25. set_error_msg
 *        26. allow_connection
 *        27. allow_connection_ipv6
 *        28. remote_connected_ipv6
 **************************************************************************/

int _register_custom()
{
    _tcpgw_regfn_init();
    _tcpgw_regfn(1, init_remote_info);
    _tcpgw_regfn(2, prepare_shutdown);
    _tcpgw_regfn(3, remote_connected);
    _tcpgw_regfn(4, remote_closed);
    _tcpgw_regfn(5, get_msg_length);

#if defined(_TCPGW_USE_EXTMSG)
    _tcpgw_regfn(15, get_extmsg_info);
    _tcpgw_regfn(16, put_extmsg_info);
#else
    _tcpgw_regfn(6, get_msg_info);
    _tcpgw_regfn(7, put_msg_info);
#endif
    _tcpgw_regfn(8, put_msg_complete);
    _tcpgw_regfn(9, get_channel_num);
    _tcpgw_regfn(10, get_service_name);
    _tcpgw_regfn(11, set_service_timeout);

#if defined(_TCPGW_USE_EXTPING)
    _tcpgw_regfn(21, set_extping_msg);
    _tcpgw_regfn(22, chk_extpong_msg);
#else
    _tcpgw_regfn(19, set_ping_msg);
    _tcpgw_regfn(20, chk_pong_msg);
#endif

#if defined(_TCPGW_VERSION_OLD)
#elif defined(_TCPGW_VERSION_1)
    _tcpgw_regfn(12, get_msg_security);
    _tcpgw_regfn(14, chk_end_msg);
#elif defined(_TCPGW_VERSION_2)
    _tcpgw_regfn(12, get_msg_security);
    _tcpgw_regfn(14, chk_end_msg);
    _tcpgw_regfn(17, inmsg_recovery);
    _tcpgw_regfn(18, outmsg_recovery);
#else
    _tcpgw_regfn(14, chk_end_msg);
    _tcpgw_regfn(17, inmsg_recovery);
    _tcpgw_regfn(18, outmsg_recovery);
#endif

    return 1;
}