|
@@ -13,7 +13,9 @@
|
|
|
// PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
|
|
#include <config.h>
|
|
|
+#include <exceptions/exceptions.h>
|
|
|
#include <dhcp/tests/pkt_filter6_test_stub.h>
|
|
|
+#include <netinet/in.h>
|
|
|
#include <list>
|
|
|
|
|
|
namespace {
|
|
@@ -38,7 +40,43 @@ SocketInfo
|
|
|
PktFilter6TestStub::openSocket(const Iface&,
|
|
|
const isc::asiolink::IOAddress& addr,
|
|
|
const uint16_t port, const bool) {
|
|
|
- return (SocketInfo(addr, port, 0));
|
|
|
+ // Create a socket which may be used on select() but which is unlikely
|
|
|
+ // to return any data.
|
|
|
+ int sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
|
|
|
+ if (sock < 0) {
|
|
|
+ isc_throw(Unexpected, "PktFilter6TestStub: opening socket failed");
|
|
|
+ }
|
|
|
+
|
|
|
+ // Set reuse address
|
|
|
+ int flag = 1;
|
|
|
+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, static_cast<const void*>(&flag),
|
|
|
+ sizeof(flag)) < 0) {
|
|
|
+ ::close(sock);
|
|
|
+ isc_throw(Unexpected, "PktFilter6TestStub:: failed to set SO_REUSEADDR on"
|
|
|
+ " socket");
|
|
|
+ }
|
|
|
+
|
|
|
+ // Set no blocking
|
|
|
+ if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
|
|
|
+ ::close(sock);
|
|
|
+ isc_throw(Unexpected, "PktFilter6TestStub: failed to set O_NONBLOCK on"
|
|
|
+ " socket");
|
|
|
+ }
|
|
|
+
|
|
|
+ // Bind to the local address and random port.
|
|
|
+ struct sockaddr_in6 local6;
|
|
|
+ memset(&local6, 0, sizeof(local6));
|
|
|
+ local6.sin6_family = AF_INET6;
|
|
|
+#ifdef HAVE_SA_LEN
|
|
|
+ local6.sin6_len = sizeof(local6);
|
|
|
+#endif
|
|
|
+
|
|
|
+ if (bind(sock, (struct sockaddr *)&local6, sizeof(local6)) < 0) {
|
|
|
+ ::close(sock);
|
|
|
+ isc_throw(Unexpected, "PktFilter6TestStub: failed to bind socket");
|
|
|
+ }
|
|
|
+
|
|
|
+ return (SocketInfo(addr, port, sock));
|
|
|
}
|
|
|
|
|
|
Pkt6Ptr
|