Skip to content

Commit

Permalink
First attempt of mDNS interface selection (open62541#2856)
Browse files Browse the repository at this point in the history
  • Loading branch information
Stasik0 authored and Pro committed Jul 2, 2019
1 parent c4bce59 commit 1de8b24
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 3 deletions.
3 changes: 3 additions & 0 deletions examples/discovery/server_multicast.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,9 @@ int main(int argc, char **argv) {

config->discovery.mdns.mdnsServerName = UA_String_fromChars("Sample Multicast Server");

//setting custom outbound interface
config->discovery.mdnsInterfaceIP = UA_String_fromChars("42.42.42.42"); //this line will produce an error and set the interface to 0.0.0.0

// See http://www.opcfoundation.org/UA/schemas/1.03/ServerCapabilities.csv
// For a LDS server, you should only indicate the LDS capability.
// If this instance is an LDS and at the same time a normal OPC UA server, you also have to indicate
Expand Down
1 change: 1 addition & 0 deletions include/open62541/server_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ typedef struct {

#ifdef UA_ENABLE_DISCOVERY_MULTICAST
UA_MdnsDiscoveryConfiguration mdns;
UA_String mdnsInterfaceIP;
#endif

} UA_ServerConfig_Discovery;
Expand Down
1 change: 1 addition & 0 deletions plugins/ua_config_default.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ setDefaultConfig(UA_ServerConfig *conf) {

#ifdef UA_ENABLE_DISCOVERY_MULTICAST
UA_MdnsDiscoveryConfiguration_init(&conf->discovery.mdns);
conf->discovery.mdnsInterfaceIP = UA_STRING_NULL;
#endif

/* Custom DataTypes */
Expand Down
44 changes: 41 additions & 3 deletions src/server/ua_discovery_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*
* Copyright 2014-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
* Copyright 2014, 2017 (c) Florian Palm
* Copyright 2015-2016 (c) Sten Grüner
* Copyright 2015-2016, 2019 (c) Sten Grüner
* Copyright 2015 (c) Chris Iatrou
* Copyright 2015-2016 (c) Oleksiy Vasylyev
* Copyright 2016-2017 (c) Stefan Profanter, fortiss GmbH
Expand All @@ -17,9 +17,13 @@

#ifdef UA_ENABLE_DISCOVERY_MULTICAST

#ifndef IN_ZERONET
#define IN_ZERONET(addr) ((addr & IN_CLASSA_NET) == 0)
#endif

/* Create multicast 224.0.0.251:5353 socket */
static UA_SOCKET
discovery_createMulticastSocket(void) {
discovery_createMulticastSocket(UA_Server* server) {
UA_SOCKET s;
int flag = 1, ittl = 255;
struct sockaddr_in in;
Expand All @@ -44,6 +48,40 @@ discovery_createMulticastSocket(void) {
return UA_INVALID_SOCKET;
}

/* Custom outbound multicast interface */
size_t length = server->config.discovery.mdnsInterfaceIP.length;
if(length > 0){
char* interfaceName = (char*)UA_malloc(length+1);
if (!interfaceName) {
UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_NETWORK, "Multicast DNS: cannot alloc memory for iface name");
return 0;
}
struct in_addr ina;
memset(&ina, 0, sizeof(ina));
memcpy(interfaceName, server->config.discovery.mdnsInterfaceIP.data, length);
interfaceName[length] = '\0';
inet_pton(AF_INET, interfaceName, &ina);
UA_free(interfaceName);
/* Set interface for outbound multicast */
if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, (char*)&ina, sizeof(ina)) < 0)
UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER, "Multicast DNS: failed setting IP_MULTICAST_IF to %s: %s", inet_ntoa(ina), strerror(errno));
}

/* Check outbound multicast interface parameters */
struct in_addr interface_addr;
socklen_t addr_size = sizeof(struct in_addr);
if (getsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, (char*)&interface_addr, &addr_size) < 0) {
UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_NETWORK, "Multicast DNS: getsockopt(IP_MULTICAST_IF) failed");
}

if(IN_ZERONET(ntohl(interface_addr.s_addr))){
UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_NETWORK, "Multicast DNS: outbound interface 0.0.0.0, it means that the first OS interface is used (you can explicitly set the interface by using 'discovery.mdnsInterfaceIP' config parameter)");
}else{
char buf[16];
inet_ntop(AF_INET, &interface_addr, buf, 16);
UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_NETWORK, "Multicast DNS: outbound interface is %s", buf);
}

mc.imr_multiaddr.s_addr = inet_addr("224.0.0.251");
mc.imr_interface.s_addr = htonl(INADDR_ANY);
UA_setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mc, sizeof(mc));
Expand All @@ -59,7 +97,7 @@ initMulticastDiscoveryServer(UA_DiscoveryManager *dm, UA_Server* server) {
server->discoveryManager.mdnsDaemon = mdnsd_new(QCLASS_IN, 1000);
UA_initialize_architecture_network();

if((server->discoveryManager.mdnsSocket = discovery_createMulticastSocket()) == UA_INVALID_SOCKET) {
if((server->discoveryManager.mdnsSocket = discovery_createMulticastSocket(server)) == UA_INVALID_SOCKET) {
UA_LOG_SOCKET_ERRNO_WRAP(
UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER,
"Could not create multicast socket. Error: %s", errno_str));
Expand Down
1 change: 1 addition & 0 deletions src/server/ua_server_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ UA_ServerConfig_clean(UA_ServerConfig *config) {
UA_ApplicationDescription_deleteMembers(&config->applicationDescription);
#ifdef UA_ENABLE_DISCOVERY_MULTICAST
UA_MdnsDiscoveryConfiguration_clear(&config->discovery.mdns);
UA_String_clear(&config->discovery.mdnsInterfaceIP);
#endif

/* Custom DataTypes */
Expand Down

0 comments on commit 1de8b24

Please sign in to comment.