New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Verify DiscoveryURL from OPC Server is resolvable #570
Conversation
Signed-off-by: harrisontin <harrisontin@microsoft.com>
Signed-off-by: harrisontin <harrisontin@microsoft.com>
Signed-off-by: harrisontin <harrisontin@microsoft.com>
Signed-off-by: harrisontin <harrisontin@microsoft.com>
Signed-off-by: harrisontin <harrisontin@microsoft.com>
Signed-off-by: harrisontin <harrisontin@microsoft.com>
/version patch |
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Signed-off-by: harrisontin <harrisontin@microsoft.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not familiar with OPC UA URLs so I handled this with "generic" URLs in mind, so this functionally looks good to me.
I added some comments about error handling/safety, as I don't think it is likeable that a rogue/faulty discovered device can make the discovery handler panic (this might not be enough as I didn't check the existing code path, but this should make it less likely).
// Test that it converts the discovery url to an ip address if the discovery url is a hostname that is not resolvable | ||
fn test_get_discovery_url_ip() { | ||
let ip_url = "opc.tcp://192.168.0.1:50000/"; | ||
let discovery_url = "opc.tcp://OPCTest:50000/OPCUA/Simluation"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From a DNS point of view this could one day become resolvable (unlikely but yet), we may want to use the reserved tld .invalid
here to ensure this (and make it clearer at first glance this is a not resolvable domain).
let discovery_url = "opc.tcp://OPCTest:50000/OPCUA/Simluation"; | |
let discovery_url = "opc.tcp://OPCTest.invalid:50000/OPCUA/Simluation"; |
let url = Url::parse(&discovery_url).unwrap(); | ||
let mut path = url.path().to_string(); | ||
let host = url.host_str().unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not really fond of panicking if an external service sends crappy things, I think it is better to directly return an Option<String>
here and return None
if the URL we got is completely invalid (and log an error so the user can be aware of that).
let url = Url::parse(&discovery_url).unwrap(); | ||
let mut path = url.path().to_string(); | ||
let host = url.host_str().unwrap(); | ||
let port = url.port().unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather use unwrap_or
here with the default port, as it is valid to omit the port in a URL
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a standard default port for opcua servers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, there is one defined in the opcua crate (didn't check the specs though): https://docs.rs/opcua/latest/opcua/core/constants/constant.DEFAULT_OPC_UA_SERVER_PORT.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And IANA confirm that same port number (4840) for "OPC UA Connection Protocol"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you! updated
Signed-off-by: harrisontin <harrisontin@microsoft.com>
Signed-off-by: harrisontin <harrisontin@microsoft.com>
Signed-off-by: harrisontin <harrisontin@microsoft.com>
Signed-off-by: harrisontin <harrisontin@microsoft.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Signed-off-by: harrisontin <harrisontin@microsoft.com>
Signed-off-by: harrisontin <harrisontin@microsoft.com>
Signed-off-by: harrisontin <harrisontin@microsoft.com>
What this PR does / why we need it:
This PR solves the issue when OPC server returns a discoveryURL that contains a hostname instead of an IP address. If the broker is not able to resolve the hostname, then it will return an error. The suggested solution is to have the discovery handler try resolving the discoveryURL (by to_socket_addr), if it fails, then we will use the IP address that user passes in instead. Note it should only perform on Server type not DiscoveryServer type.
closes #555
Sample: Using Prosys OPC UA Simulation Server
Before:
After:
Special notes for your reviewer:
If applicable:
cargo fmt
)cargo build
)cargo clippy
)cargo test
)cargo doc
)