Chapter 3. User Programs and Functions

Table of Contents

3.1. Overview
3.2. custom.h
3.3. custom.c
3.3.1. init_remote_info
3.3.2. remote_connected
3.3.3. remote_connected_ipv6
3.3.4. remote_closed
3.3.5. allow_connection
3.3.6. allow_connection_ipv6
3.3.7. get_msg_length
3.3.8. get_msg_info
3.3.9. get_channel_num
3.3.10. put_msg_info
3.3.11. put_msg_complete
3.3.12. get_service_name
3.3.13. prepare_shutdown
3.3.14. set_service_timeout
3.3.15. chk_end_msg
3.3.16. inmsg_recovery
3.3.17. outmsg_recovery
3.3.18. get_extmsg_info
3.3.19. put_extmsg_info
3.3.20. set_ping_msg
3.3.21. chk_pong_msg
3.3.22. set_extping_msg
3.3.23. chk_extpong_msg
3.3.24. reset_ping_msg
3.3.25. reset_extping_msg
3.3.26. set_error_msg
3.3.27. get_msg_security
3.3.28. put_msg_security
3.4. register.c

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

3.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 "3.3. custom.c".

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

    Note

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

3.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 "3.3. 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.

    MemberDescription
    char svc[20]Service name that TCPGW uses to call the service when it is requested from the remote service.
    int errError status during service request or reply data transmission.
    int lenLength of the sent/received data.
    int uidUID 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 msgtypeCurrently not used.
    int channel_idSending/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;

3.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, then 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.

    FunctionDescription
    init_remote_infoThis function is called before connecting to the remote node.
    remote_connectedThis function is called after connecting to the remote node.
    remote_connected_ipv6This function is called after connecting to the remote node in the IPv6 protocol environment.
    remote_closedThis function is called after disconnecting from the remote node.
    allow_connectionThis 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_ipv6This 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 can be called.
    get_msg_lengthWhen a request or a reply is received from the remote node, this function continuously reads as much data as specified by the can be called.
    get_msg_infoThis 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_numThis function allows the user to select the channel when sending data from a Tmax service or client to the remote node.
    put_msg_infoThis function is called when a message is sent to the remote node.
    put_msg_completeThis function is called after a message is sent to the remote node.
    get_service_nameThis function is configured according to the error code of the service name to tpreply() or tpacall() to.
    prepare_shutdownThis function is called immediately before TCPGW shut downs.
    set_service_timeoutThis function can be called when there is a service timeout.
    chk_end_msgThis 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_recoveryThis function is called when an error occurs while processing a request from the remote node.
    outmsg_recoveryThis function is called when an error occurs while sending a request to the remote node.
    get_extmsg_infoSimilar to get_msg_info except for some functionality.
    put_extmsg_infoSimilar to put_msg_info except for some functionality.
    set_ping_msgUser-defined function that can configure settings, interval, and timeout for messages sent to check for channel errors.
    chk_pong_msgUser-defined function that checks the channel error monitoring response message status.
    set_extping_msgThis function configures the message that is sent to detect for channel errors on the server.
    chk_extpong_msgThis function checks messages received from the server to detect a channel error.
    reset_ping_msgThis function is called periodically to reset TCP/IP Ping (channel error detection) message and its status.
    reset_extping_msgSimilar to reset_ping_msg except for some functionality.
    set_error_msgThis function is automatically called when there's an error during transaction with the remote node.
    get_msg_securityThis function can process data after get_msg_info is called.
    put_msg_securityThis function can process data before put_msg_info is called.

    Note

    Examples of the functions described in this section are described in "Chapter 4. Examples".

3.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

    ParameterDescription
    mynameTCPGW server name.
    mynumberTCPGW process number used to identify each process when multiple TCPGW are run simultaneously. The number starts from 0.
    num_channelMax 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.
    keyShared memory key value set using the [-k ] option in the Tmax environment file.

3.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

    ParameterDescription
    indexIndex value of each channel when TCPGW is connected to multiple channels using the [-n] or [-N] option.
    addrRemote node address.
    portnoPort 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.
    typeChannel type connected to the remote node. Either IN_CHANNEL or OUT_CHANNEL.
    fdSocket number connected to the remote node.

3.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

    ParameterDescription
    indexIndex value of each channel when TCPGW is connected to multiple channels using the [-n] or [-N] option.
    saddrRemote node address and port number. Must be casted as the sockaddr struct type suitable for the IPv4 or IPv6 protocol environment.
    portnoPort 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.
    typeChannel type connected to the remote node. Either IN_CHANNEL or OUT_CHANNEL.
    fdSocket 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.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

    ParameterDescription
    indexIndex value for each channel when TCPGW is connected to multiple channels with the [-n] option or the [-N] option.
    typeChannel type connected to the remote node. Either IN_CHANNEL or OUT_CHANNEL.

3.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

    ParameterDescription
    addrRemote node address.
    portnoPort 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.
    typeChannel type connected to the remote node. Either IN_CHANNEL or OUT_CHANNEL.
    fdSocket number connected to the remote node.
  • can be called

    ValueDescription
    1Allows connection requests with the remote node.
    Negative NumberDoes 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.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

    ParameterDescription
    saddrRemote node address and port number. Must be casted as the sockaddr struct type suitable for the IPv4 or IPv6 protocol environment.
    portnoPort 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.
    typeChannel type connected to the remote node. Either IN_CHANNEL or OUT_CHANNEL.
    fdSocket number connected to the remote node.
  • can be called

    ValueDescription
    1Allows connection request with the remote node.
    Negative NumberDoes 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.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

    ParameterDescription
    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.

  • can be called

    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.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

    ParameterDescription
    hpPointer to the message header read from the remote node. Same as the struct used in get_msg_length.
    dataData part read from the remote node.
    infoStruct that interfaces between the TCPGW library (libtcpgw.a, libtcpgw.so) and custom.c. Sets various information 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.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

    ParameterDescription
    dataData to send to the remote node.
  • Return Value

    Channel number.

3.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

    ParameterDescription
    hpMessage header to send to the remote node.
    dataData to send to the remote node.
    infoData 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.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

    ParameterDescription
    hpMessage header to send to the remote node.
    dataData to send to the remote node.
    infoData information to send to the remote node.

3.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

    ParameterDescription
    headerPointer to the user header stored in TCPGW configured using the [-H] or [-h] option.
    errError code.
    svcName of the service that receives tpreply() or tpacall().

3.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

    ParameterDescription
    codeTermination code. Currently not in use.

3.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

    ParameterDescription
    uidUser ID of the transaction where the service timeout occurred.
    headerHeader of the transaction where the service timeout occurred.

3.3.15. chk_end_msg

The chk_end_msg 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.

  • Prototype

    int chk_end_msg(int len, char *data)

  • Parameter

    ParameterDescription
    lenLength of the data read from the remote node.
    dataData part read from the remote node.

3.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

    ParameterDescription
    dataData 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.

    ValueDescription
    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 NumberDiscard the data.

3.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

    ParameterDescription
    dataData 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

    ValueDescription
    Positive Number
    • When a value is set in info→svc: Send a tpacall(..., TPNOREPLY) to the applicable service.

    • When info→msgtype is lower than 1000: Return the data to the requester.

    • When info→msgtype is 1000 or higher: Discard the data.

3.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

    ParameterDescription
    hpPointer to the message header data read from the remote node. Same as the struct used in get_msg_length().
    dataAddress of the data buffer read from the remote node.
    asizeMemory size allocated to the data buffer read from the remote node.
    infoStruct that interfaces between the TCPGW library (libtcpgw.a, libtcpgw.so) and custom.c. Sets various information 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.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

    ParameterDescription
    hpPointer to the message header data to send to the remote node. Same as the struct used in put_msg_length().
    dataAddress of the data buffer to send to the remote node.
    asizeMemory size allocated to the data buffer to send to the remote node.
    infoInformation 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.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

    ParameterDescription
    hpMessage periodically sent to monitor channel errors. Required.
    intervalInterval for monitoring channel errors. If set to 0, the channel error monitoring function is disabled. (Unit: seconds)
    bintervalInterval 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.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

    ParameterDescription
    hpMessage received from the remote.

  • Return Value

    Return ValueDescription
    Positive NumberWhen the message from the remote server is a normal channel error monitoring reply message.
    0When 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 NumberWhen the message from the remote server is an abnormal channel error monitoring reply message.

3.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

    ParameterDescription
    hpMessage periodically sent to monitor channel errors. Required.
    dataMessage body that follows the error monitoring message (hp). Optional.
    lenMaximum length of the error monitoring message body. Configure the maximum length with the [-b] option. Default value: 0
    intervalInterval for monitoring channel errors. If set to 0, the channel error monitoring function is disabled. (Unit: seconds)
    bintervalInterval 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

    ValueDescription
    0When the function has been successfully performed.
    Negative NumberWhen 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.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

    ParameterDescription
    hpMessage header received from the remote server when a channel error is detected.
    dataMessage body received from the remote server when a channel error is detected.
    lenLength of the message body.

  • Return Value

    ValueDescription
    Positive NumberWhen the message from the remote server is a normal channel error monitoring reply message.
    0When 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 NumberWhen 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.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

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

  • Return Value

    ValueDescription
    Positive NumberPing message is sent to the remote server.
    Negative NumberPing 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.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

    ParameterDescription
    hpMessage header to send to monitor channel errors. The message header set using the set_ping_msg function is the default value.
    dataPointer to the message body to reconfigure. Max buffer size is set in len. The return value is set to the actual buffer size.
    lenMaximum available message body size.

  • Return Value

    ValueDescription
    Positive NumberPing message is sent to the remote server with the specified size of the message body.
    0Ping message is sent to the remote node without the message body.
    Negative NumberPing 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.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

    ParameterDescription
    hpMessage header that was sent when an error occurred. Can be modified by the user.
    dataData that was sent when an error occurred. Can be modified by the user.
    lenMessage body length.
  • Return Value

    ValueDescription
    Positive NumberSends as much data as the returned length. CLOPT="-I" option must be configured.
    0Only up to the user header part has been sent.
    Negative NumberMessage is not sent to CLH.
  • Error

    Error CodeDescription
    [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.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

    ParameterDescription
    dataData 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.
    asizeMemory size allocated to the data buffer read from the remote node.
    lenMessage body length.
  • Return Value

    ValueDescription
    Positive NumberTotal length of the processed user data.
    0Do 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.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

    ParameterDescription
    dataData 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.
    asizeMemory size allocated to the data buffer to send to the remote node.
    lenMessage body length.
  • Return Value

    ValueDescription
    Positive NumberTotal length of the processed user data.
    0Do 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;
    }

3.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;
}