TCP commands
TCP commands contains functions to obtain and manipulate information related to the TCP layer, such as sockopt:
TCP:reject() — Allows the user to reject a TCP connection from a client.
TCP:set_snat_ip(str) — Allows the user to set the backend TCP connection’s source address and port.
TCP:clear_snat_ip() — Allows the user to clear any IP that was set using the set_snat_ip() command.
TCP:sockopt(t) — Allows the user to customize the send buffer and receive buffer size. Can set or get various socket/IP/TCP operations, such as buffer size, timeout, MSS, etc. This currently only supports snd_buf and rcv_buf buffer sizes. For client-side events, this command applies to the client-side socket; for server-side events, it applies to server-side socket.
TCP:after_timer_set() — Allows the user to create and schedule a timer with a callback function and timeout value. This allows you to create multiple timers each with a unique callback function name.
TCP:after_timer_cancel() — Allows the user to cancel a scheduled timer. This function can only cancel a timer before it is triggered if it is not periodic.
TCP:after_timer_get() — Allows the user to get the information about the scheduled timers.
TCP:close() — Allows the user to close the TCP connection immediately.
TCP:reject()
Allows the user to reject a TCP connection from a client.
Syntax
TCP:reject();
Arguments
N/A
Example
when TCP_ACCEPTED {
--check if the st is true or false;
If st then
TCP:reject();
end
}
FortiADC version: V5.0
Used in events: TCP_ACCEPTED
TCP:set_snat_ip(str)
Allows the user to set the backend TCP connection’s source address and port.
Syntax
TCP:set_snat_ip(str);
Note: To use the set_snat_ip() command, you must ensure the SOURCE ADDRESS flag is selected in the HTTP or HTTPS profile type.
Arguments
| Name | Description |
|---|---|
|
str |
A string which specifies the ip address. |
Example
when TCP_ACCEPTED{
addr_group = “172.24.172.60/24”
client_ip = IP:client_addr()
matched = cmp_addr(client_ip, addr_group)
if matched then
if TCP:set_snat_ip(“10.106.3.124”) then
debug(“set SNAT ip to 10.106.3.124\n”)
end
end
}
Note: The VS must have the client address enabled in the profile, as shown in the example below.
config load-balance profile
edit "http"
set type http
set client-address enable
next
end
FortiADC version: V5.2
Used in events: TCP_ACCEPTED / HTTP_REQUEST / HTTP_DATA_REQUEST / CLIENTSSL_HANDSHAKE
TCP:clear_snat_ip()
Allows the user to clear any IP that was set using the set_snat_ip() command.
Syntax
TCP:clear_snat_ip();
Arguments
N/A
Example
when HTTP_REQUEST {
if TCP:clear_snat_ip() then
debug(“clear SNAT ip!\n”)
}
FortiADC version: V5.0
Used in events: TCP_ACCEPTED / HTTP_REQUEST / HTTP_DATA_REQUEST / CLIENTSSL_HANDSHAKE
TCP:sockopt(t)
Allows the user to customize the send buffer and receive buffer size. Can set or get various socket/IP/TCP operations, such as buffer size, timeout, MSS, etc. This currently only supports snd_buf and rcv_buf buffer sizes. For client-side events, this command applies to the client-side socket; for server-side events, it applies to server-side socket.
Syntax
TCP:sockopt(t);
Arguments
| Name | Description |
|---|---|
|
t |
A table which specifies the event and operation, variable. |
Example
when RULE_INIT {
debug(" ======== RULE_INIT ========\n");
-- access to https://notes.shichao.io/unp/ch7/ for more details.
tcp_message = {};
tcp_message[1]="snd_buf"; --int
tcp_message[2]="rcv_buf"; --int
setIntMsg = {};
setIntMsg[1]="snd_buf"; --int
setIntMsg[2]="rcv_buf"; --int
setIntValue = {};
setIntValue[1] = 111222;
setIntValue[2] = 111222;
}when VS_LISTENER_BIND{
--when a VS tries to bind.
debug(" ======== VS_LISTENER_BIND ========\n");
for k,v in pairs(tcp_message) do
t = {};
t["op"] = "get"
t["message"]=v
if TCP:sockopt(t) then
debug("%s value is %d\n",v, TCP:sockopt(t));
else
debug("get %s status %s\n",v,TCP:sockopt(t));
end
end
debug(" ==== set ==== \n");
for k,v in pairs(setIntMsg) do
s = {};
s["op"] = "set"; --or "set"
s["message"] = v
s["value"] = setIntValue[k]; -- for integer value
result = TCP:sockopt(s);
debug("setting %s to %s return %s\n",v,setIntValue[k], result);
end
debug(" ==== End set ==== \n");
for k,v in pairs(tcp_message) do
t = {};
t["op"] = "get"
t["message"]=v
if TCP:sockopt(t) then
debug("%s value is %d\n",v, TCP:sockopt(t));
else
debug("get %s status %s\n",v,TCP:sockopt(t));
end
end
}
when HTTP_RESPONSE {
debug(" ======== HTTP_RESPONSE ========\n");
t={}
t["size"] = 100;
HTTP:collect(t)
debug(" ==== set ==== \n");
for k,v in pairs(setIntMsg) do
s = {};
s["op"] = "set"; --or "set"
s["message"] = v
s["value"] = setIntValue[k]; -- for integer value
result = TCP:sockopt(s);
debug("setting %s to %s return %s\n",v,setIntValue[k], result);
end
debug(" ==== End set ==== \n");
for k,v in pairs(tcp_message) do
t = {};
t["op"] = "get"
t["message"]=v
if TCP:sockopt(t) then
debug("%s value is %d\n",v, TCP:sockopt(t));
else
debug("get %s status %s\n",v,TCP:sockopt(t));
end
end
}when HTTP_DATA_RESPONSE {
debug(" ======== HTTP_DATA_RESPONSE ========\n");
debug(" ==== set ==== \n");
for k,v in pairs(setIntMsg) do
s = {};
s["op"] = "set"; --or "set"
s["message"] = v
s["value"] = setIntValue[k]; -- for integer value
result = TCP:sockopt(s);
debug("setting %s to %s return %s\n",v,setIntValue[k], result);
end
debug(" ==== End set ==== \n");
for k,v in pairs(tcp_message) do
t = {};
t["op"] = "get"
t["message"]=v
if TCP:sockopt(t) then
debug("%s value is %d\n",v, TCP:sockopt(t));
else
debug("get %s status %s\n",v,TCP:sockopt(t));
end
end
}
FortiADC version: V5.0
Used in events:
-
In client-side events, including TCP_BIND, TCP_ACCEPTED, HTTP_REQUEST, HTTP_DATA_REQUEST
-
In server-side events, including HTTP_RESPONSE, HTTP_DATA_RESPONSE, BEFORE_CONNECT, SERVER_CONNECTED.
TCP:after_timer_set()
Allows the user to create and schedule a timer with a callback function and timeout value. This allows you to create multiple timers each with a unique callback function name. Periodic timers will be executed periodically until the associated session is closed or the after_timer is closed.
Returns Boolean true if successful, otherwise, returns Boolean false.
Syntax
TCP:after_timer_set (timer_cb_name, timeout, periodic);
Arguments
| Name | Description |
|---|---|
|
timer_cb_name |
A string of the callback function name. This is also the unique identification of a timer. This parameter is required. |
|
timeout |
An integer as the timeout value in milliseconds. This parameter is required. |
|
periodic |
A Boolean to indicate whether this timer is periodic. This parameter is required. |
Example
when TCP_ACCEPTED {
debug("[%s]------> TCP accepted begin:\n",ctime());
local_count = 10
cip = IP:client_addr();
debug("[%s]------> client IP %s\n", ctime(),cip);
cport = IP:client_port();
debug("[%s]------> client Port %s\n", ctime(),cport);
debug("[%s]------> local_count= %d\n", ctime(),local_count);
debug("[%s]------> After function called here.\n",ctime());
AFTER_TIMER_NAME = function ()
debug("[%s]=======> After function call begin:\n",ctime())
cport = IP:client_port();
debug("[%s]=======> client Port %s\n",ctime(),cport);
debug("[%s]=======> After function call end.\n",ctime())
end
TCP:after_timer_set("AFTER_TIMER_NAME", 5000, true);
}
When the client successfully creates a TCP connection, the script will be executed. The function will be executed every 5 seconds (5000 milliseconds) and print out the text.
FortiADC console debug output:
[Thu Jan 11 16:30:50 2024]------> TCP accepted begin: [Thu Jan 11 16:30:50 2024]------> client IP 10.1.0.161 [Thu Jan 11 16:30:50 2024]------> client Port 37818 [Thu Jan 11 16:30:50 2024]------> local_count= 10 [Thu Jan 11 16:30:50 2024]------> After function called here. [Thu Jan 11 16:30:55 2024]=======> After function call begin: [Thu Jan 11 16:30:55 2024]=======> client Port 37818 [Thu Jan 11 16:30:55 2024]=======> After function call end. [Thu Jan 11 16:31:00 2024]=======> After function call begin: [Thu Jan 11 16:31:00 2024]=======> client Port 37818 [Thu Jan 11 16:31:00 2024]=======> After function call end.
FortiADC version: V7.4.1
Used in events:
-
HTTP events: HTTP_REQUEST / HTTP_RESPONSE / HTTP_DATA_REQUEST / HTTP_DATA_RESPONSE
-
TCP events: TCP_ACCEPTED / SERVER_CONNECTED / SERVER_BEFORE_CONNECT
TCP:after_timer_cancel()
Allows the user to cancel a scheduled timer. This function can only cancel a timer before it is triggered if it is not periodic.
Returns Boolean true if successful, otherwise, returns Boolean false.
Syntax
TCP:after_timer_cancel (timer_cb_name);
Arguments
| Name | Description |
|---|---|
|
timer_cb_name |
A string to indicate the name of the timer to be canceled. This parameter is required. |
Example
when TCP_ACCEPTED {
AFTER_TIMER_NAME = function ()
debug("[%s]====>After function call begin:\n",ctime());
debug("[%s]====>After function call end.\n",ctime());
end
TCP:after_timer_set("AFTER_TIMER_NAME", 1000, true);
}
when HTTP_REQUEST{
debug("[%s]------> Events: HTTP_REQUEST begin:\n", ctime());
TCP:after_timer_cancel("AFTER_TIMER_NAME");
}
When the client successfully creates a TCP connection, the script will be executed. When the HTTP is requested, the AFTER_TIMER_NAME will be stopped.
FortiADC console debug output:
[Thu Oct 5 13:37:51 2023]====>After function call begin: [Thu Oct 5 13:37:51 2023]====>After function call end. [Thu Oct 5 13:37:52 2023]====>After function call begin: [Thu Oct 5 13:37:52 2023]====>After function call end. [Thu Oct 5 13:37:53 2023]------> Events: HTTP_REQUEST begin:
FortiADC version: V7.4.1
Used in events:
-
HTTP events: HTTP_REQUEST / HTTP_RESPONSE / HTTP_DATA_REQUEST / HTTP_DATA_RESPONSE
-
TCP events: TCP_ACCEPTED / SERVER_CONNECTED / SERVER_BEFORE_CONNECT
TCP:after_timer_get()
Allows the user to get the information about the scheduled timers.
When successful, returns a string for one timer, a table of strings for multiple timers. For example, the returned string “'AFTER_TIMER_NAME':5000:periodic” shows the timer name, expiration in milliseconds and if it is periodic.
Returns nil for all failures.
Syntax
TCP:after_timer_get ([timer_cb_name]);
Arguments
| Name | Description |
|---|---|
|
timer_cb_name |
A string to indicate the name of the timer. This parameter is optional. If this parameter is empty, then the function will get the information for all existing timers. |
Example
when TCP_ACCEPTED {
AFTER_TIMER_NAME = function ()
debug("[%s]====>After function call begin:\n",ctime());
debug("[%s]====>After function call end.\n",ctime());
end
TCP:after_timer_set("AFTER_TIMER_NAME", 1000, true);
ret = TCP:after_timer_get("AFTER_TIMER_NAME");
debug("after_timer_get success: %s\n", ret);
}
When the client successfully creates a TCP connection, the script will be executed. This function gets the after_timer information and prints it out on the first line.
FortiADC console debug output:
after_timer_get success: 'AFTER_TIMER_NAME':1000:periodic [Thu Oct 5 12:36:34 2023]====>After function call begin: [Thu Oct 5 12:36:34 2023]====>After function call end. [Thu Oct 5 12:36:35 2023]====>After function call begin: [Thu Oct 5 12:36:35 2023]====>After function call end.
FortiADC version: V7.4.1
Used in events:
-
HTTP events: HTTP_REQUEST / HTTP_RESPONSE / HTTP_DATA_REQUEST / HTTP_DATA_RESPONSE
-
TCP events: TCP_ACCEPTED / SERVER_CONNECTED / SERVER_BEFORE_CONNECT
TCP:close()
Allows the user to close the TCP connection immediately. Once an associated session is closed, all the after_timers will be deleted.
Returns Boolean true if successful, otherwise, returns Boolean false.
Syntax
TCP:close();
Arguments
N/A
Example
when TCP_ACCEPTED {
AFTER_TIMER_NAME = function ()
debug("[%s]====>After function call begin:\n",ctime());
debug("[%s]====>After function call end.\n",ctime());
end
TCP:after_timer_set("AFTER_TIMER_NAME", 1000, true);
}
when HTTP_REQUEST{
debug("[%s]------> Events: HTTP_REQUEST begin:\n", ctime());
TCP:close();
}
When the client successfully creates a TCP connection, the script will be executed. When the HTTP is requested, the TCP connection will be closed.
Client side:
[root@Client1 ~]# curl http://10.1.0.15 -v * Trying 10.1.0.15:80... * Connected to 10.1.0.15 (10.1.0.15) port 80 (#0) > GET / HTTP/1.1 > Host: 10.1.0.15 > User-Agent: curl/8.0.1 > Accept: */* > * Empty reply from server * Closing connection 0 curl: (52) Empty reply from server
FortiADC version: V7.4.1
Used in events:
-
HTTP events: HTTP_REQUEST / HTTP_RESPONSE / HTTP_DATA_REQUEST / HTTP_DATA_RESPONSE
-
TCP events: TCP_ACCEPTED / SERVER_CONNECTED / SERVER_BEFORE_CONNECT
-
CLIENTSSL_HANDSHAKE