Update Windows code to fix build breakage
[fio.git] / engines / net.c
index b2c1283454090ed42554908c6642dd130e37cc59..52cc8a7f92c48f15d538f848810d0ad2710c89cd 100644 (file)
@@ -37,6 +37,8 @@ struct netio_options {
        unsigned int listen;
        unsigned int pingpong;
        unsigned int nodelay;
+       unsigned int ttl;
+       char *intfc;
 };
 
 struct udp_close_msg {
@@ -128,6 +130,26 @@ static struct fio_option options[] = {
                .category = FIO_OPT_C_ENGINE,
                .group  = FIO_OPT_G_NETIO,
        },
+       {
+               .name   = "interface",
+               .lname  = "net engine interface",
+               .type   = FIO_OPT_STR_STORE,
+               .off1   = offsetof(struct netio_options, intfc),
+               .help   = "Network interface to use",
+               .category = FIO_OPT_C_ENGINE,
+               .group  = FIO_OPT_G_NETIO,
+       },
+       {
+               .name   = "ttl",
+               .lname  = "net engine multicast ttl",
+               .type   = FIO_OPT_INT,
+               .off1   = offsetof(struct netio_options, ttl),
+               .def    = "1",
+               .minval = 0,
+               .help   = "Time-to-live value for outgoing UDP multicast packets",
+               .category = FIO_OPT_C_ENGINE,
+               .group  = FIO_OPT_G_NETIO,
+       },
        {
                .name   = NULL,
        },
@@ -531,9 +553,30 @@ static int fio_netio_connect(struct thread_data *td, struct fio_file *f)
        }
 #endif
 
-       if (o->proto == FIO_TYPE_UDP)
+       if (o->proto == FIO_TYPE_UDP) {
+               if (!fio_netio_is_multicast(td->o.filename))
+                       return 0;
+
+               if (o->intfc) {
+                       struct in_addr interface_addr;
+                       if (inet_aton(o->intfc, &interface_addr) == 0) {
+                               log_err("fio: interface not valid interface IP\n");
+                               close(f->fd);
+                               return 1;
+                       }
+                       if (setsockopt(f->fd, IPPROTO_IP, IP_MULTICAST_IF, (const char*)&interface_addr, sizeof(interface_addr)) < 0) {
+                               td_verror(td, errno, "setsockopt IP_MULTICAST_IF");
+                               close(f->fd);
+                               return 1;
+                       }
+               }
+               if (setsockopt(f->fd, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&o->ttl, sizeof(o->ttl)) < 0) {
+                       td_verror(td, errno, "setsockopt IP_MULTICAST_TTL");
+                       close(f->fd);
+                       return 1;
+               }
                return 0;
-       else if (o->proto == FIO_TYPE_TCP) {
+       else if (o->proto == FIO_TYPE_TCP) {
                socklen_t len = sizeof(nd->addr);
 
                if (connect(f->fd, (struct sockaddr *) &nd->addr, len) < 0) {
@@ -841,8 +884,16 @@ static int fio_netio_setup_listen_inet(struct thread_data *td, short port)
                inet_aton(td->o.filename, &sin.sin_addr);
 
                mr.imr_multiaddr = sin.sin_addr;
-               mr.imr_interface.s_addr = htonl(INADDR_ANY);
-               if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mr, sizeof(mr)) < 0) {
+               if (o->intfc) {
+                       if (inet_aton(o->intfc, &mr.imr_interface) == 0) {
+                               log_err("fio: interface not valid interface IP\n");
+                               close(fd);
+                               return 1;
+                       }
+               } else {
+                       mr.imr_interface.s_addr = htonl(INADDR_ANY);
+               }
+               if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&mr, sizeof(mr)) < 0) {
                        td_verror(td, errno, "setsockopt IP_ADD_MEMBERSHIP");
                        close(fd);
                        return 1;