|
@@ -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
|
|
@@ -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;
|
|
@@ -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));
|
|
@@ -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));
|