Community discussions

MikroTik App
 
nagylzs
Member
Member
Topic Author
Posts: 356
Joined: Sun May 26, 2019 2:08 pm

Calculate number of seconds in last-handshake

Mon Nov 20, 2023 4:13 pm

I would like to write a script that runs periodically, and toggles (disable + enable) any wireguard peer that has not been seen in a while. This is needed because in my experience, any wireguard peer becomes unusuable when the listen address of the wireguard server socket is changed (e.g. when the router gets a different addres on its WAN interface). This is an annoying thing, that has been around for a while. There can be other reasons why a peer would become dead. My goal is to monitor all peers in the background, and restart them when they have not been seen for a while. This could save me a lot of time.

I can get the last-handshake value with a script:
 :put [/interface/wireguard/peers/get 0 last-handshake ]      
00:00:45
But I'm not sure how to compare this with a given number of seconds. Actually, I'm confused about the type of this data. The documentation does not make a difference between date, time, timestamp and interval types: https://wiki.mikrotik.com/wiki/Manual:S ... Data_types

It only has this vague description: "time - date and time value".

But clearly, the expression 10000m is not a date:
 :put 10000m
6d22:40:00
These three values below clearly have a different type:
:put [/system/clock get time]
14:57:35
:put [/system/clock get date]    
2023-11-20
:put [/system/script/get 0 last-started ]
2023-11-19 20:00:00
So we have at least four different kind of values but we only have a single data type called "time", and I'm really confused about this.

Some operators seems logical, but they do not work as expected. Here is an example:
> :put [ [/system/script/get 0 last-started ] ]      
2023-11-19 20:00:00
> :put [ [/system/script/get 0 last-started ] + 10m ]    
2023-11-19 20:00:00
Looks like adding "100m" to "2023-11-19 20:00:00" is not an error (because it does not throw an error), but it does nothing. These values are not interpreted as string (that would result in "2023-11-19 20:00:0010m", but they are also not interpreted as timestamp and interval values. But they are interpreted I guess, otherwise the expression would throw an error. What is happening here?

Here are some questions.
  • What is the type of the value that is printed as 6d22:40 ?
  • What is the type of the value that is printed as 14:57:35 ?
  • What is the type of the value that is printed as 2023-11-20 ?
  • What is the type of the value that is printed as 2023-11-19 20:00:00 ?
  • Out of these four things, which ones are documented, and which ones aren't?
  • How can I access various properties of these values? (For example, year number in a date, or total number of sedconds in an interval)
  • Are there any operators that work on this/these types?
 
User avatar
eworm
Forum Guru
Forum Guru
Posts: 1071
Joined: Wed Oct 22, 2014 9:23 am
Location: Oberhausen, Germany
Contact:

Re: Calculate number of seconds in last-handshake

Mon Nov 20, 2023 10:34 pm

The last-handshake property is of type "time", and you can just compare that with other times.
[admin@mikrotik] > :put (2s < 5m)
true
[admin@mikrotik] > :put (2d < 5m)  
false
You can use just that to find your stale peers:
/interface/wireguard/peers/print where last-handshake>5m
Note there is a culprit for last-handshake to find connected peers: An uninitialized property (where a peer never connected) matches when filtering for "smaller than". In this case you have a add another match to make sure the property is initialized.
/interface/wireguard/peers/print where last-handshake last-handshake<5m
And finally peers that never connected:
/interface/wireguard/peers/print where !last-handshake
 
User avatar
eworm
Forum Guru
Forum Guru
Posts: 1071
Joined: Wed Oct 22, 2014 9:23 am
Location: Oberhausen, Germany
Contact:

Re: Calculate number of seconds in last-handshake

Mon Nov 20, 2023 10:36 pm

  • What is the type of the value that is printed as 2023-11-20 ?
  • What is the type of the value that is printed as 2023-11-19 20:00:00 ?
I think these are just strings...

You can check with:
[admin@mikrotik] > :put [ :typeof [ /system/clock get date ] ]
str
 
nagylzs
Member
Member
Topic Author
Posts: 356
Joined: Sun May 26, 2019 2:08 pm

Re: Calculate number of seconds in last-handshake

Mon Nov 20, 2023 10:52 pm

The last-handshake property is of type "time", and you can just compare that with other times.
[admin@mikrotik] > :put (2s < 5m)
true
[admin@mikrotik] > :put (2d < 5m)  
false
This was very helpful, thank you!
 
nagylzs
Member
Member
Topic Author
Posts: 356
Joined: Sun May 26, 2019 2:08 pm

Re: Calculate number of seconds in last-handshake

Mon Nov 20, 2023 11:28 pm

  • What is the type of the value that is printed as 2023-11-20 ?
  • What is the type of the value that is printed as 2023-11-19 20:00:00 ?
I think these are just strings...

You can check with:
[admin@mikrotik] > :put [ :typeof [ /system/clock get date ] ]
str
Well, I think that the documentation needs to be updated. And not just the docs, possibly the type system too, at least name of the "time" type should be changed.

Here are some facts:

* The name of the type is "time", but it cannot store time. It can only store interval.
* The documentation says that "time - date and time value", but in fact this it cannot store time values, and certainly not date values.
* In the docs, the "totime" function has this description: "convert variable to time" - but the syntax and the interpretation is totally undefined. All right, I can figure out that :put [:totime 120] returns 00:02:00, so integers are interpreted as seconds. Similarily, :put [:totime "3d"] is converted to 3d00:00:00.
Other wreid examples::put [:totime "d"] returns nothing instead of 1d, but :put [:totime "0:100"] returns 01:40:00 (this is possibly a bug, not a feature). We should not write scripts based on guesswork.
* totime can convert a string or an integer into a (time)interval, but there is no function to convert an interval into an integer. It makes impossible to do arithmetic with intervals.
* this includes adding / removing intervals to timestamps. For example, I cannot test if the last execution of a scheduled script was more than 5 hours ago. It is because the "last execution" is a string, and it would be VERY difficult to do this in pure RouterOS script. (Daylight saving adjustments and leap seconds might have happened in the last 6 hours...)

All right, I understand that for an OS created for routers, a timestamp type might not be very important for most users. I'm not complaining, just exploring possibilities. I believe there was a way to write scripts in lua, but that feature has been removed. It would be possible to install something inside docker, but programs running inside docker containers cannot access the router's configuration. Is there a way to use a different language? RouterOS script language seems very cryptic, and it is lacking lots of features.

What do you think, should I report these as documentation bugs? Is there a chance that someone will update the docs?

Thank you,

Laszlo

Who is online

Users browsing this forum: Bing [Bot] and 4 guests