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.
-
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.
-
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.
-
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 This function is called before connecting to the remote node.
This function is called after connecting to the remote node.
This function is called after connecting to the remote node in the IPv6 protocol environment.
This function is called after disconnecting from the remote node.
This function is called before a new connection is made with the remote node. The return value determines whether to allow the requested connection.
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.
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.
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.
This function allows the user to select the channel when sending data from a Tmax service or client to the remote node.
This function is called when a message is sent to the remote node.
This function is called after a message is sent to the remote node.
This function is configured according to the error code of the service name to tpreply() or tpacall() to.
This function is called immediately before TCPGW shut downs.
This function can be called when there is a service timeout.
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.
This function is called when an error occurs while processing a request from the remote node.
This function is called when an error occurs while sending a request to the remote node.
Similar to get_msg_info except for some functionality.
Similar to put_msg_info except for some functionality.
User-defined function that can configure settings, interval, and timeout for messages sent to check for channel errors.
User-defined function that checks the channel error monitoring response message status.
This function configures the message that is sent to detect for channel errors on the server.
This function checks messages received from the server to detect a channel error.
This function is called periodically to reset TCP/IP Ping (channel error detection) message and its status.
Similar to reset_ping_msg except for some functionality.
This function is automatically called when there’s an error during transaction with the remote node.
This function can process data after get_msg_info is called.
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; }