|
@@ -217,7 +217,9 @@ bool IfaceMgr::openSockets4(const uint16_t port) {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- sock = openSocket(iface->getName(), *addr, port);
|
|
|
+ // Using openSocket4 directly instead of using openSocket to
|
|
|
+ // pass boolean arguments that enable broadcast traffic.
|
|
|
+ sock = openSocket4(*iface, *addr, port, true, true);
|
|
|
if (sock < 0) {
|
|
|
isc_throw(SocketConfigError, "failed to open unicast socket");
|
|
|
}
|
|
@@ -509,22 +511,43 @@ IfaceMgr::getLocalAddress(const IOAddress& remote_addr, const uint16_t port) {
|
|
|
return IOAddress(local_address);
|
|
|
}
|
|
|
|
|
|
-int IfaceMgr::openSocket4(Iface& iface, const IOAddress& addr, uint16_t port) {
|
|
|
+int IfaceMgr::openSocket4(Iface& iface, const IOAddress& addr, uint16_t port,
|
|
|
+ bool receive_bcast, bool send_bcast) {
|
|
|
|
|
|
struct sockaddr_in addr4;
|
|
|
memset(&addr4, 0, sizeof(sockaddr));
|
|
|
addr4.sin_family = AF_INET;
|
|
|
addr4.sin_port = htons(port);
|
|
|
|
|
|
- addr4.sin_addr.s_addr = htonl(addr);
|
|
|
- //addr4.sin_addr.s_addr = 0; // anyaddr: this will receive 0.0.0.0 => 255.255.255.255 traffic
|
|
|
- // addr4.sin_addr.s_addr = 0xffffffffu; // broadcast address. This will receive 0.0.0.0 => 255.255.255.255 as well
|
|
|
+ // If we are to receive broadcast messages we have to bind
|
|
|
+ // to "ANY" address.
|
|
|
+ addr4.sin_addr.s_addr = receive_bcast ? INADDR_ANY : htonl(addr);
|
|
|
|
|
|
int sock = socket(AF_INET, SOCK_DGRAM, 0);
|
|
|
if (sock < 0) {
|
|
|
isc_throw(SocketConfigError, "Failed to create UDP6 socket.");
|
|
|
}
|
|
|
|
|
|
+ if (receive_bcast) {
|
|
|
+ // Bind to device so as we receive traffic on a specific interface.
|
|
|
+ if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, iface.getName().c_str(),
|
|
|
+ iface.getName().length() + 1) < 0) {
|
|
|
+ close(sock);
|
|
|
+ isc_throw(SocketConfigError, "Failed to set SO_BINDTODEVICE option"
|
|
|
+ << "on socket " << sock);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (send_bcast) {
|
|
|
+ // Enable sending to broadcast address.
|
|
|
+ int flag = 1;
|
|
|
+ if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &flag, sizeof(flag)) < 0) {
|
|
|
+ close(sock);
|
|
|
+ isc_throw(SocketConfigError, "Failed to set SO_BINDTODEVICE option"
|
|
|
+ << "on socket " << sock);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if (bind(sock, (struct sockaddr *)&addr4, sizeof(addr4)) < 0) {
|
|
|
close(sock);
|
|
|
isc_throw(SocketConfigError, "Failed to bind socket " << sock << " to " << addr.toText()
|