net.c revision 5e34ceafd6ea07785c470c8a8cd7cae740493743
1ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe/*
2da751ca9665bcdeca56d2eec5b629a0953c07662Jens Axboe * net engine
3da751ca9665bcdeca56d2eec5b629a0953c07662Jens Axboe *
4da751ca9665bcdeca56d2eec5b629a0953c07662Jens Axboe * IO engine that reads/writes to/from sockets.
5da751ca9665bcdeca56d2eec5b629a0953c07662Jens Axboe *
6ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe */
7ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <stdio.h>
8ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <stdlib.h>
9ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <unistd.h>
10842805f55b6dd021edbb5259a775c148ef18fa9cSteven Noonan#include <signal.h>
11ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <errno.h>
12ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <assert.h>
13ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <netinet/in.h>
1470a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan#include <netinet/tcp.h>
15ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <arpa/inet.h>
16ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include <netdb.h>
175fdd124a3b811993542825847f207587d5f4661eJens Axboe#include <sys/poll.h>
187292056a38857ded6f7a64f11d14d642772c31bdJens Axboe#include <sys/types.h>
190fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe#include <sys/stat.h>
207292056a38857ded6f7a64f11d14d642772c31bdJens Axboe#include <sys/socket.h>
210fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe#include <sys/un.h>
22ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
23ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#include "../fio.h"
24ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
25b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestruct netio_data {
26b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	int listenfd;
279cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int use_splice;
289cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int pipes[2];
29b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct sockaddr_in addr;
3049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	struct sockaddr_in6 addr6;
310fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	struct sockaddr_un addr_un;
32b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe};
33ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
34de890a1e48d40238dac69f302708dde8719de240Steven Langstruct netio_options {
35de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct thread_data *td;
36de890a1e48d40238dac69f302708dde8719de240Steven Lang	unsigned int port;
37de890a1e48d40238dac69f302708dde8719de240Steven Lang	unsigned int proto;
38de890a1e48d40238dac69f302708dde8719de240Steven Lang	unsigned int listen;
396f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	unsigned int pingpong;
4070a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan	unsigned int nodelay;
41d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer	unsigned int ttl;
42531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe	unsigned int window_size;
435e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe	unsigned int mss;
44f16b7405fff7c3fc1da421b6bdf8552cc99c3156Bruce Cran	char *intfc;
45de890a1e48d40238dac69f302708dde8719de240Steven Lang};
46de890a1e48d40238dac69f302708dde8719de240Steven Lang
47664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestruct udp_close_msg {
48664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	uint32_t magic;
49664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	uint32_t cmd;
50664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe};
51664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
52664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboeenum {
53664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	FIO_LINK_CLOSE = 0x89,
54b96d243044023b28731341d290943b5d47a5f794Jens Axboe	FIO_LINK_OPEN_CLOSE_MAGIC = 0x6c696e6b,
55b96d243044023b28731341d290943b5d47a5f794Jens Axboe	FIO_LINK_OPEN = 0x98,
560fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
570fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	FIO_TYPE_TCP	= 1,
580fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	FIO_TYPE_UDP	= 2,
590fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	FIO_TYPE_UNIX	= 3,
6049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	FIO_TYPE_TCP_V6	= 4,
6149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	FIO_TYPE_UDP_V6	= 5,
62664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe};
63664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
64de890a1e48d40238dac69f302708dde8719de240Steven Langstatic int str_hostname_cb(void *data, const char *input);
65de890a1e48d40238dac69f302708dde8719de240Steven Langstatic struct fio_option options[] = {
66de890a1e48d40238dac69f302708dde8719de240Steven Lang	{
67de890a1e48d40238dac69f302708dde8719de240Steven Lang		.name	= "hostname",
68e8b0e958cd219cabb1154e2b06036863a7d6dbd7Jens Axboe		.lname	= "net engine hostname",
69de890a1e48d40238dac69f302708dde8719de240Steven Lang		.type	= FIO_OPT_STR_STORE,
70de890a1e48d40238dac69f302708dde8719de240Steven Lang		.cb	= str_hostname_cb,
71de890a1e48d40238dac69f302708dde8719de240Steven Lang		.help	= "Hostname for net IO engine",
72e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe		.category = FIO_OPT_C_ENGINE,
73e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe		.group	= FIO_OPT_G_NETIO,
74de890a1e48d40238dac69f302708dde8719de240Steven Lang	},
75de890a1e48d40238dac69f302708dde8719de240Steven Lang	{
76de890a1e48d40238dac69f302708dde8719de240Steven Lang		.name	= "port",
77e8b0e958cd219cabb1154e2b06036863a7d6dbd7Jens Axboe		.lname	= "net engine port",
78de890a1e48d40238dac69f302708dde8719de240Steven Lang		.type	= FIO_OPT_INT,
79de890a1e48d40238dac69f302708dde8719de240Steven Lang		.off1	= offsetof(struct netio_options, port),
80de890a1e48d40238dac69f302708dde8719de240Steven Lang		.minval	= 1,
81de890a1e48d40238dac69f302708dde8719de240Steven Lang		.maxval	= 65535,
82de890a1e48d40238dac69f302708dde8719de240Steven Lang		.help	= "Port to use for TCP or UDP net connections",
83e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe		.category = FIO_OPT_C_ENGINE,
84e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe		.group	= FIO_OPT_G_NETIO,
85de890a1e48d40238dac69f302708dde8719de240Steven Lang	},
86de890a1e48d40238dac69f302708dde8719de240Steven Lang	{
87de890a1e48d40238dac69f302708dde8719de240Steven Lang		.name	= "protocol",
88e8b0e958cd219cabb1154e2b06036863a7d6dbd7Jens Axboe		.lname	= "net engine protocol",
89de890a1e48d40238dac69f302708dde8719de240Steven Lang		.alias	= "proto",
90de890a1e48d40238dac69f302708dde8719de240Steven Lang		.type	= FIO_OPT_STR,
91de890a1e48d40238dac69f302708dde8719de240Steven Lang		.off1	= offsetof(struct netio_options, proto),
92de890a1e48d40238dac69f302708dde8719de240Steven Lang		.help	= "Network protocol to use",
93de890a1e48d40238dac69f302708dde8719de240Steven Lang		.def	= "tcp",
94de890a1e48d40238dac69f302708dde8719de240Steven Lang		.posval = {
95de890a1e48d40238dac69f302708dde8719de240Steven Lang			  { .ival = "tcp",
96de890a1e48d40238dac69f302708dde8719de240Steven Lang			    .oval = FIO_TYPE_TCP,
97de890a1e48d40238dac69f302708dde8719de240Steven Lang			    .help = "Transmission Control Protocol",
98de890a1e48d40238dac69f302708dde8719de240Steven Lang			  },
99eb2323108392e65ab7c4e4c5cbd74a1597b60187Jens Axboe#ifdef CONFIG_IPV6
10049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe			  { .ival = "tcpv6",
10149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe			    .oval = FIO_TYPE_TCP_V6,
10249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe			    .help = "Transmission Control Protocol V6",
10349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe			  },
104eb2323108392e65ab7c4e4c5cbd74a1597b60187Jens Axboe#endif
105de890a1e48d40238dac69f302708dde8719de240Steven Lang			  { .ival = "udp",
106de890a1e48d40238dac69f302708dde8719de240Steven Lang			    .oval = FIO_TYPE_UDP,
107f5cc3d0ea8acf13c8e722da6c2d485889968d132Bruce Cran			    .help = "User Datagram Protocol",
108de890a1e48d40238dac69f302708dde8719de240Steven Lang			  },
109eb2323108392e65ab7c4e4c5cbd74a1597b60187Jens Axboe#ifdef CONFIG_IPV6
11049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe			  { .ival = "udpv6",
11149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe			    .oval = FIO_TYPE_UDP_V6,
11249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe			    .help = "User Datagram Protocol V6",
11349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe			  },
114eb2323108392e65ab7c4e4c5cbd74a1597b60187Jens Axboe#endif
115de890a1e48d40238dac69f302708dde8719de240Steven Lang			  { .ival = "unix",
116de890a1e48d40238dac69f302708dde8719de240Steven Lang			    .oval = FIO_TYPE_UNIX,
117de890a1e48d40238dac69f302708dde8719de240Steven Lang			    .help = "UNIX domain socket",
118de890a1e48d40238dac69f302708dde8719de240Steven Lang			  },
119de890a1e48d40238dac69f302708dde8719de240Steven Lang		},
120e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe		.category = FIO_OPT_C_ENGINE,
121e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe		.group	= FIO_OPT_G_NETIO,
122de890a1e48d40238dac69f302708dde8719de240Steven Lang	},
1231eafa37ac57bb08ca21af8ab76bd7848ae2e7c97Jens Axboe#ifdef CONFIG_TCP_NODELAY
124de890a1e48d40238dac69f302708dde8719de240Steven Lang	{
12570a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan		.name	= "nodelay",
12670a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan		.type	= FIO_OPT_BOOL,
12770a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan		.off1	= offsetof(struct netio_options, nodelay),
12870a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan		.help	= "Use TCP_NODELAY on TCP connections",
129e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe		.category = FIO_OPT_C_ENGINE,
130e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe		.group	= FIO_OPT_G_NETIO,
13170a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan	},
1321eafa37ac57bb08ca21af8ab76bd7848ae2e7c97Jens Axboe#endif
133de890a1e48d40238dac69f302708dde8719de240Steven Lang	{
134de890a1e48d40238dac69f302708dde8719de240Steven Lang		.name	= "listen",
135e8b0e958cd219cabb1154e2b06036863a7d6dbd7Jens Axboe		.lname	= "net engine listen",
136de890a1e48d40238dac69f302708dde8719de240Steven Lang		.type	= FIO_OPT_STR_SET,
137de890a1e48d40238dac69f302708dde8719de240Steven Lang		.off1	= offsetof(struct netio_options, listen),
138de890a1e48d40238dac69f302708dde8719de240Steven Lang		.help	= "Listen for incoming TCP connections",
139e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe		.category = FIO_OPT_C_ENGINE,
140e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe		.group	= FIO_OPT_G_NETIO,
141de890a1e48d40238dac69f302708dde8719de240Steven Lang	},
142de890a1e48d40238dac69f302708dde8719de240Steven Lang	{
1436f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe		.name	= "pingpong",
1446f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe		.type	= FIO_OPT_STR_SET,
1456f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe		.off1	= offsetof(struct netio_options, pingpong),
1466f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe		.help	= "Ping-pong IO requests",
147e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe		.category = FIO_OPT_C_ENGINE,
148e90a0adf85f75a65c02b22ba3766dff0d9d82ae6Jens Axboe		.group	= FIO_OPT_G_NETIO,
1496f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	},
1506f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	{
151b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer		.name	= "interface",
152b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer		.lname	= "net engine interface",
153b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer		.type	= FIO_OPT_STR_STORE,
154f16b7405fff7c3fc1da421b6bdf8552cc99c3156Bruce Cran		.off1	= offsetof(struct netio_options, intfc),
155b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer		.help	= "Network interface to use",
156b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer		.category = FIO_OPT_C_ENGINE,
157b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer		.group	= FIO_OPT_G_NETIO,
158b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer	},
159b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer	{
160d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer		.name	= "ttl",
161d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer		.lname	= "net engine multicast ttl",
162d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer		.type	= FIO_OPT_INT,
163d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer		.off1	= offsetof(struct netio_options, ttl),
164d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer		.def    = "1",
165d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer		.minval	= 0,
166d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer		.help	= "Time-to-live value for outgoing UDP multicast packets",
167d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer		.category = FIO_OPT_C_ENGINE,
168d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer		.group	= FIO_OPT_G_NETIO,
169d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer	},
170531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe#ifdef CONFIG_NET_WINDOWSIZE
171531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe	{
172531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe		.name	= "window_size",
173531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe		.lname	= "Window Size",
174531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe		.type	= FIO_OPT_INT,
175531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe		.off1	= offsetof(struct netio_options, window_size),
176531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe		.minval	= 0,
177531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe		.help	= "Set socket buffer window size",
178531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe		.category = FIO_OPT_C_ENGINE,
179531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe		.group	= FIO_OPT_G_NETIO,
180531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe	},
181531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe#endif
1825e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe#ifdef CONFIG_NET_MSS
1835e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe	{
1845e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe		.name	= "mss",
1855e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe		.lname	= "Maximum segment size",
1865e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe		.type	= FIO_OPT_INT,
1875e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe		.off1	= offsetof(struct netio_options, mss),
1885e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe		.minval	= 0,
1895e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe		.help	= "Set TCP maximum segment size",
1905e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe		.category = FIO_OPT_C_ENGINE,
1915e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe		.group	= FIO_OPT_G_NETIO,
1925e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe	},
1935e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe#endif
194d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer	{
195de890a1e48d40238dac69f302708dde8719de240Steven Lang		.name	= NULL,
196de890a1e48d40238dac69f302708dde8719de240Steven Lang	},
197de890a1e48d40238dac69f302708dde8719de240Steven Lang};
198de890a1e48d40238dac69f302708dde8719de240Steven Lang
19949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboestatic inline int is_udp(struct netio_options *o)
20049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe{
20149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	return o->proto == FIO_TYPE_UDP || o->proto == FIO_TYPE_UDP_V6;
20249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe}
20349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe
20449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboestatic inline int is_tcp(struct netio_options *o)
20549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe{
20649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	return o->proto == FIO_TYPE_TCP || o->proto == FIO_TYPE_TCP_V6;
20749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe}
20849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe
20949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboestatic inline int is_ipv6(struct netio_options *o)
21049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe{
21149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	return o->proto == FIO_TYPE_UDP_V6 || o->proto == FIO_TYPE_TCP_V6;
21249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe}
21349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe
214531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboestatic int set_window_size(struct thread_data *td, int fd)
215531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe{
216531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe#ifdef CONFIG_NET_WINDOWSIZE
217531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe	struct netio_options *o = td->eo;
218531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe	unsigned int wss;
219531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe	int snd, rcv, ret;
220531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe
221531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe	if (!o->window_size)
222531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe		return 0;
223531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe
224531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe	rcv = o->listen || o->pingpong;
225531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe	snd = !o->listen || o->pingpong;
226531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe	wss = o->window_size;
227531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe	ret = 0;
228531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe
229531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe	if (rcv) {
230531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe		ret = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void *) &wss,
231531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe					sizeof(wss));
232531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe		if (ret < 0)
233531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe			td_verror(td, errno, "rcvbuf window size");
234531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe	}
235531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe	if (snd && !ret) {
236531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe		ret = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (void *) &wss,
237531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe					sizeof(wss));
238531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe		if (ret < 0)
239531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe			td_verror(td, errno, "sndbuf window size");
240531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe	}
241531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe
242531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe	return ret;
243531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe#else
244531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe	td_verror(td, -EINVAL, "setsockopt window size");
245531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe	return -1;
246531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe#endif
247531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe}
248531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe
2495e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboestatic int set_mss(struct thread_data *td, int fd)
2505e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe{
2515e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe#ifdef CONFIG_NET_MSS
2525e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe	struct netio_options *o = td->eo;
2535e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe	unsigned int mss;
2545e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe	int ret;
2555e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe
2565e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe	if (!o->mss || !is_tcp(o))
2575e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe		return 0;
2585e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe
2595e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe	mss = o->mss;
2605e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe	ret = setsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, (void *) &mss,
2615e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe				sizeof(mss));
2625e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe	if (ret < 0)
2635e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe		td_verror(td, errno, "setsockopt TCP_MAXSEG");
2645e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe
2655e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe	return ret;
2665e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe#else
2675e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe	td_verror(td, -EINVAL, "setsockopt TCP_MAXSEG");
2685e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe	return -1;
2695e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe#endif
2705e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe}
2715e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe
2725e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe
273371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe/*
274371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe * Return -1 for error and 'nr events' for a positive number
275371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe * of events
276371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe */
277371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboestatic int poll_wait(struct thread_data *td, int fd, short events)
278371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe{
279371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe	struct pollfd pfd;
280371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe	int ret;
281371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe
282371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe	while (!td->terminate) {
283371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe		pfd.fd = fd;
284371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe		pfd.events = events;
285371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe		ret = poll(&pfd, 1, -1);
286371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe		if (ret < 0) {
287371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe			if (errno == EINTR)
288d5b388a560783a61af7b424757bc6dead2309c28Jens Axboe				break;
289371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe
290371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe			td_verror(td, errno, "poll");
291371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe			return -1;
292371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe		} else if (!ret)
293371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe			continue;
294371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe
295371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe		break;
296371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe	}
297371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe
298371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe	if (pfd.revents & events)
299371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe		return 1;
300371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe
301371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe	return -1;
302371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe}
303371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe
304b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrerstatic int fio_netio_is_multicast(const char *mcaddr)
305b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer{
306b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer	in_addr_t addr = inet_network(mcaddr);
307b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer	if (addr == -1)
308b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer		return 0;
309b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer
310b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer	if (inet_network("224.0.0.0") <= addr &&
311b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer	    inet_network("239.255.255.255") >= addr)
312b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer		return 1;
313b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer
314b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer	return 0;
315b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer}
316b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer
317b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer
318ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic int fio_netio_prep(struct thread_data *td, struct io_u *io_u)
319ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
320de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
321ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
3227a6499dada619928267d26b4629b0c8623dc423aJens Axboe	/*
3237a6499dada619928267d26b4629b0c8623dc423aJens Axboe	 * Make sure we don't see spurious reads to a receiver, and vice versa
3247a6499dada619928267d26b4629b0c8623dc423aJens Axboe	 */
32549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	if (is_tcp(o))
326de890a1e48d40238dac69f302708dde8719de240Steven Lang		return 0;
327de890a1e48d40238dac69f302708dde8719de240Steven Lang
328de890a1e48d40238dac69f302708dde8719de240Steven Lang	if ((o->listen && io_u->ddir == DDIR_WRITE) ||
329de890a1e48d40238dac69f302708dde8719de240Steven Lang	    (!o->listen && io_u->ddir == DDIR_READ)) {
330e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, EINVAL, "bad direction");
3317a6499dada619928267d26b4629b0c8623dc423aJens Axboe		return 1;
332ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
3333f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran
334f85ac25a7d5c9d5ba4d5c73363a6a2a461a9b013Jens Axboe	return 0;
335ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
336ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
33767bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe#ifdef CONFIG_LINUX_SPLICE
338cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int splice_io_u(int fdin, int fdout, unsigned int len)
339ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
3409cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int bytes = 0;
3417a6499dada619928267d26b4629b0c8623dc423aJens Axboe
3429cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	while (len) {
343cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe		int ret = splice(fdin, NULL, fdout, NULL, len, 0);
3449cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
3459cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		if (ret < 0) {
3469cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			if (!bytes)
3479cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe				bytes = ret;
3489cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
3499cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			break;
3509cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		} else if (!ret)
3519cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			break;
3529cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
3539cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		bytes += ret;
354f657a2fbbb0deaf455edc478d73b664929bcb766Jens Axboe		len -= ret;
3559cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	}
3569cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
3579cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	return bytes;
3589cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
3599cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
3609cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/*
361cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * Receive bytes from a socket and fill them into the internal pipe
3629cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe */
363cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int splice_in(struct thread_data *td, struct io_u *io_u)
3649cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
3659cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	struct netio_data *nd = td->io_ops->data;
3669cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
367cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	return splice_io_u(io_u->file->fd, nd->pipes[1], io_u->xfer_buflen);
3689cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
3699cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
3709cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/*
371cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * Transmit 'len' bytes from the internal pipe
3729cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe */
373cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int splice_out(struct thread_data *td, struct io_u *io_u,
374cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe		      unsigned int len)
3759cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
3769cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	struct netio_data *nd = td->io_ops->data;
377cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe
378cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	return splice_io_u(nd->pipes[0], io_u->file->fd, len);
379cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe}
380cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe
381cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int vmsplice_io_u(struct io_u *io_u, int fd, unsigned int len)
382cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe{
3839cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	struct iovec iov = {
3849cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		.iov_base = io_u->xfer_buf,
3859cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		.iov_len = len,
3869cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	};
3879cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int bytes = 0;
3889cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
3899cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	while (iov.iov_len) {
390cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe		int ret = vmsplice(fd, &iov, 1, SPLICE_F_MOVE);
3919cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
3929cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		if (ret < 0) {
3939cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			if (!bytes)
3949cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe				bytes = ret;
3959cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			break;
3969cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		} else if (!ret)
3979cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			break;
3989cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
3999cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		iov.iov_len -= ret;
400cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe		iov.iov_base += ret;
401f657a2fbbb0deaf455edc478d73b664929bcb766Jens Axboe		bytes += ret;
4029cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	}
4039cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
4049cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	return bytes;
405cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe
4069cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
4079cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
4089cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/*
409cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * vmsplice() pipe to io_u buffer
4109cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe */
411cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int vmsplice_io_u_out(struct thread_data *td, struct io_u *io_u,
412cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe			     unsigned int len)
4139cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
4149cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	struct netio_data *nd = td->io_ops->data;
4159cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
416cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	return vmsplice_io_u(io_u, nd->pipes[0], len);
417cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe}
4189cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
419cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe/*
420cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * vmsplice() io_u to pipe
421cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe */
422cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboestatic int vmsplice_io_u_in(struct thread_data *td, struct io_u *io_u)
423cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe{
424cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	struct netio_data *nd = td->io_ops->data;
425ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
426cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	return vmsplice_io_u(io_u, nd->pipes[1], io_u->xfer_buflen);
4279cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
4289cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
429cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe/*
430cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * splice receive - transfer socket data into a pipe using splice, then map
431cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * that pipe data into the io_u using vmsplice.
432cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe */
4339cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_splice_in(struct thread_data *td, struct io_u *io_u)
4349cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
4359cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int ret;
4369cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
4379cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	ret = splice_in(td, io_u);
438cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	if (ret > 0)
439cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe		return vmsplice_io_u_out(td, io_u, ret);
4409cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
441cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	return ret;
4429cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
4439cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
444cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe/*
445cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * splice transmit - map data from the io_u into a pipe by using vmsplice,
446cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe * then transfer that pipe to a socket using splice.
447cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe */
4489cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_splice_out(struct thread_data *td, struct io_u *io_u)
4499cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
4509cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int ret;
4519cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
4529cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	ret = vmsplice_io_u_in(td, io_u);
453cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	if (ret > 0)
454cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe		return splice_out(td, io_u, ret);
4559cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
456cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe	return ret;
4579cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
4585921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#else
4595921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic int fio_netio_splice_in(struct thread_data *td, struct io_u *io_u)
4605921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe{
461af8771b9b91eb2cd23a40aaa729bad4f78acb928Jens Axboe	errno = EOPNOTSUPP;
4625921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe	return -1;
4635921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe}
4645921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe
4655921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic int fio_netio_splice_out(struct thread_data *td, struct io_u *io_u)
4665921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe{
467af8771b9b91eb2cd23a40aaa729bad4f78acb928Jens Axboe	errno = EOPNOTSUPP;
4685921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe	return -1;
4695921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe}
4705921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif
4719cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
4729cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_send(struct thread_data *td, struct io_u *io_u)
4739cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
474414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	struct netio_data *nd = td->io_ops->data;
475de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
4766f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	int ret, flags = 0;
477371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe
478664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	do {
47949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		if (is_udp(o)) {
48010aa136bddbaa7c845ab4eacb4a9a4a88d6657a3Jens Axboe			const struct sockaddr *to;
48149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe			socklen_t len;
48249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe
48349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe			if (is_ipv6(o)) {
48449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe				to = (struct sockaddr *) &nd->addr6;
48549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe				len = sizeof(nd->addr6);
48649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe			} else {
48749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe				to = (struct sockaddr *) &nd->addr;
48849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe				len = sizeof(nd->addr);
48949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe			}
49062b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe
491664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			ret = sendto(io_u->file->fd, io_u->xfer_buf,
49249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe					io_u->xfer_buflen, flags, to, len);
493664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		} else {
494664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			/*
495664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			 * if we are going to write more, set MSG_MORE
496664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			 */
4975921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#ifdef MSG_MORE
4986f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe			if ((td->this_io_bytes[DDIR_WRITE] + io_u->xfer_buflen <
4996f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe			    td->o.size) && !o->pingpong)
500664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe				flags |= MSG_MORE;
5015921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif
502664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			ret = send(io_u->file->fd, io_u->xfer_buf,
503664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe					io_u->xfer_buflen, flags);
504664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		}
505664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		if (ret > 0)
506664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			break;
5079cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
508664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		ret = poll_wait(td, io_u->file->fd, POLLOUT);
509664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		if (ret <= 0)
510664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			break;
511664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	} while (1);
512664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
513664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	return ret;
514664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe}
515664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
516664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestatic int is_udp_close(struct io_u *io_u, int len)
517664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe{
518664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	struct udp_close_msg *msg;
519664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
520664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	if (len != sizeof(struct udp_close_msg))
521664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		return 0;
522664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
523664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	msg = io_u->xfer_buf;
524b96d243044023b28731341d290943b5d47a5f794Jens Axboe	if (ntohl(msg->magic) != FIO_LINK_OPEN_CLOSE_MAGIC)
525664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		return 0;
526664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	if (ntohl(msg->cmd) != FIO_LINK_CLOSE)
527664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		return 0;
528664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
529664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	return 1;
5309cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
5319cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
532414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboestatic int fio_netio_recv(struct thread_data *td, struct io_u *io_u)
5339cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
534414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	struct netio_data *nd = td->io_ops->data;
535de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
5366f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	int ret, flags = 0;
537664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
538664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	do {
53949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		if (is_udp(o)) {
540b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer			struct sockaddr *from;
54149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe			socklen_t l, *len = &l;
542b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer
543b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer			if (o->listen) {
54449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe				if (!is_ipv6(o)) {
54549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe					from = (struct sockaddr *) &nd->addr;
54649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe					*len = sizeof(nd->addr);
54749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe				} else {
54849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe					from = (struct sockaddr *) &nd->addr6;
54949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe					*len = sizeof(nd->addr6);
55049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe				}
551b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer			} else {
552b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer				from = NULL;
553b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer				len = NULL;
554b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer			}
555664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
556664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			ret = recvfrom(io_u->file->fd, io_u->xfer_buf,
557b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer					io_u->xfer_buflen, flags, from, len);
558664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			if (is_udp_close(io_u, ret)) {
559664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe				td->done = 1;
560664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe				return 0;
561664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			}
562664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		} else {
563664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			ret = recv(io_u->file->fd, io_u->xfer_buf,
564664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe					io_u->xfer_buflen, flags);
565664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		}
566664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		if (ret > 0)
567664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			break;
5687d988f68c7f0ff6bd4c9e558c4defbd9a544b167Jens Axboe		else if (!ret && (flags & MSG_WAITALL))
5697d988f68c7f0ff6bd4c9e558c4defbd9a544b167Jens Axboe			break;
5709cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
571664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		ret = poll_wait(td, io_u->file->fd, POLLIN);
572664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		if (ret <= 0)
573664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe			break;
574664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		flags |= MSG_WAITALL;
575664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	} while (1);
576414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
577664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	return ret;
5789cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
5799cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
5806f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboestatic int __fio_netio_queue(struct thread_data *td, struct io_u *io_u,
5816f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe			     enum fio_ddir ddir)
5829cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
5839cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	struct netio_data *nd = td->io_ops->data;
584de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
5859cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	int ret;
5869cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
5876f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	if (ddir == DDIR_WRITE) {
58849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		if (!nd->use_splice || is_udp(o) ||
589de890a1e48d40238dac69f302708dde8719de240Steven Lang		    o->proto == FIO_TYPE_UNIX)
5909cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			ret = fio_netio_send(td, io_u);
591414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		else
592414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe			ret = fio_netio_splice_out(td, io_u);
5936f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	} else if (ddir == DDIR_READ) {
59449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		if (!nd->use_splice || is_udp(o) ||
595de890a1e48d40238dac69f302708dde8719de240Steven Lang		    o->proto == FIO_TYPE_UNIX)
596414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe			ret = fio_netio_recv(td, io_u);
5979cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		else
598414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe			ret = fio_netio_splice_in(td, io_u);
599d4f12dd05cfb2e8e7a72604cd870e10f2394914eJens Axboe	} else
6007a6499dada619928267d26b4629b0c8623dc423aJens Axboe		ret = 0;	/* must be a SYNC */
601ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
602cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe	if (ret != (int) io_u->xfer_buflen) {
6030ecdd7f38e521cb55677264437fca6597976fd49Jens Axboe		if (ret > 0) {
604cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe			io_u->resid = io_u->xfer_buflen - ret;
605cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe			io_u->error = 0;
60636167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe			return FIO_Q_COMPLETED;
6070ecdd7f38e521cb55677264437fca6597976fd49Jens Axboe		} else if (!ret)
6080ecdd7f38e521cb55677264437fca6597976fd49Jens Axboe			return FIO_Q_BUSY;
6090ecdd7f38e521cb55677264437fca6597976fd49Jens Axboe		else {
610414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe			int err = errno;
611414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
6126f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe			if (ddir == DDIR_WRITE && err == EMSGSIZE)
613414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe				return FIO_Q_BUSY;
614414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
615414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe			io_u->error = err;
616414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		}
617ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
618ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
61936167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	if (io_u->error)
620e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, io_u->error, "xfer");
621ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
62236167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	return FIO_Q_COMPLETED;
623ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
624ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
6256f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboestatic int fio_netio_queue(struct thread_data *td, struct io_u *io_u)
6266f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe{
6276f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	struct netio_options *o = td->eo;
6286f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	int ret;
6296f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe
6306f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	fio_ro_check(td, io_u);
6316f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe
6326f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	ret = __fio_netio_queue(td, io_u, io_u->ddir);
6336f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	if (!o->pingpong || ret != FIO_Q_COMPLETED)
6346f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe		return ret;
6356f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe
6366f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	/*
6376f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	 * For ping-pong mode, receive or send reply as needed
6386f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	 */
6396f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	if (td_read(td) && io_u->ddir == DDIR_READ)
6406f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe		ret = __fio_netio_queue(td, io_u, DDIR_WRITE);
6416f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	else if (td_write(td) && io_u->ddir == DDIR_WRITE)
6426f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe		ret = __fio_netio_queue(td, io_u, DDIR_READ);
6436f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe
6446f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe	return ret;
6456f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe}
6466f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe
647b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_connect(struct thread_data *td, struct fio_file *f)
648ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
649b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
650de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
6516264c7a8ddd0998f371604c227d3aea491922681Jens Axboe	int type, domain;
652414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
653de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->proto == FIO_TYPE_TCP) {
6540fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		domain = AF_INET;
655414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		type = SOCK_STREAM;
65649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	} else if (o->proto == FIO_TYPE_TCP_V6) {
65749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		domain = AF_INET6;
65849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		type = SOCK_STREAM;
659de890a1e48d40238dac69f302708dde8719de240Steven Lang	} else if (o->proto == FIO_TYPE_UDP) {
6600fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		domain = AF_INET;
661414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		type = SOCK_DGRAM;
66249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	} else if (o->proto == FIO_TYPE_UDP_V6) {
66349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		domain = AF_INET6;
66449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		type = SOCK_DGRAM;
665de890a1e48d40238dac69f302708dde8719de240Steven Lang	} else if (o->proto == FIO_TYPE_UNIX) {
6660fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		domain = AF_UNIX;
6670fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		type = SOCK_STREAM;
6680fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	} else {
669de890a1e48d40238dac69f302708dde8719de240Steven Lang		log_err("fio: bad network type %d\n", o->proto);
6700fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		f->fd = -1;
6710fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		return 1;
6720fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	}
673ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
6740fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	f->fd = socket(domain, type, 0);
675b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	if (f->fd < 0) {
676b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		td_verror(td, errno, "socket");
677b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		return 1;
678ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
679ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
6801eafa37ac57bb08ca21af8ab76bd7848ae2e7c97Jens Axboe#ifdef CONFIG_TCP_NODELAY
68149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	if (o->nodelay && is_tcp(o)) {
6826264c7a8ddd0998f371604c227d3aea491922681Jens Axboe		int optval = 1;
6836264c7a8ddd0998f371604c227d3aea491922681Jens Axboe
68426e594a55a54d47ce0a0784c27c6f851c83d101aJens Axboe		if (setsockopt(f->fd, IPPROTO_TCP, TCP_NODELAY, (void *) &optval, sizeof(int)) < 0) {
68570a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan			log_err("fio: cannot set TCP_NODELAY option on socket (%s), disable with 'nodelay=0'\n", strerror(errno));
68670a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan			return 1;
68770a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan		}
68870a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan	}
6891eafa37ac57bb08ca21af8ab76bd7848ae2e7c97Jens Axboe#endif
69070a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan
691531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe	if (set_window_size(td, f->fd)) {
692531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe		close(f->fd);
693531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe		return 1;
694531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe	}
6955e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe	if (set_mss(td, f->fd)) {
6965e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe		close(f->fd);
6975e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe		return 1;
6985e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe	}
699531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe
70049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	if (is_udp(o)) {
701d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer		if (!fio_netio_is_multicast(td->o.filename))
702d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer			return 0;
70349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		if (is_ipv6(o)) {
70449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe			log_err("fio: multicast not supported on IPv6\n");
70549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe			close(f->fd);
70649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe			return 1;
70749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		}
708d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer
709f16b7405fff7c3fc1da421b6bdf8552cc99c3156Bruce Cran		if (o->intfc) {
710b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer			struct in_addr interface_addr;
71149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe
712f16b7405fff7c3fc1da421b6bdf8552cc99c3156Bruce Cran			if (inet_aton(o->intfc, &interface_addr) == 0) {
713b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer				log_err("fio: interface not valid interface IP\n");
714b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer				close(f->fd);
715b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer				return 1;
716b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer			}
717f16b7405fff7c3fc1da421b6bdf8552cc99c3156Bruce Cran			if (setsockopt(f->fd, IPPROTO_IP, IP_MULTICAST_IF, (const char*)&interface_addr, sizeof(interface_addr)) < 0) {
718b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer				td_verror(td, errno, "setsockopt IP_MULTICAST_IF");
719b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer				close(f->fd);
720b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer				return 1;
721b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer			}
722b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer		}
723f16b7405fff7c3fc1da421b6bdf8552cc99c3156Bruce Cran		if (setsockopt(f->fd, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&o->ttl, sizeof(o->ttl)) < 0) {
724d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer			td_verror(td, errno, "setsockopt IP_MULTICAST_TTL");
725d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer			close(f->fd);
726d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer			return 1;
727d3a623deee774b82e4f92c6b9b4b0233b0f4454cShawn Bohrer		}
728414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		return 0;
729b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer	} else if (o->proto == FIO_TYPE_TCP) {
73067bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe		socklen_t len = sizeof(nd->addr);
731414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
7320fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		if (connect(f->fd, (struct sockaddr *) &nd->addr, len) < 0) {
7330fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe			td_verror(td, errno, "connect");
734b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe			close(f->fd);
7350fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe			return 1;
7360fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		}
73749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	} else if (o->proto == FIO_TYPE_TCP_V6) {
73849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		socklen_t len = sizeof(nd->addr6);
73949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe
74049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		if (connect(f->fd, (struct sockaddr *) &nd->addr6, len) < 0) {
74149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe			td_verror(td, errno, "connect");
74249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe			close(f->fd);
74349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe			return 1;
74449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		}
74549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe
7460fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	} else {
7470fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		struct sockaddr_un *addr = &nd->addr_un;
74867bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe		socklen_t len;
7490fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
7500fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		len = sizeof(addr->sun_family) + strlen(addr->sun_path) + 1;
7510fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
7520fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		if (connect(f->fd, (struct sockaddr *) addr, len) < 0) {
7530fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe			td_verror(td, errno, "connect");
754b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe			close(f->fd);
7550fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe			return 1;
7560fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		}
757ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
758ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
759ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	return 0;
760ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
761ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
762b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_accept(struct thread_data *td, struct fio_file *f)
7635fdd124a3b811993542825847f207587d5f4661eJens Axboe{
764b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
765de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
76649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	socklen_t socklen;
7676264c7a8ddd0998f371604c227d3aea491922681Jens Axboe	int state;
7685fdd124a3b811993542825847f207587d5f4661eJens Axboe
76949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	if (is_udp(o)) {
770414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		f->fd = nd->listenfd;
771414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		return 0;
772414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe	}
773414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
774859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe	state = td->runstate;
775859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe	td_set_runstate(td, TD_SETTING_UP);
776859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe
7776d86144dd10b05e8b82e9b895c35dd778e5e71abJens Axboe	log_info("fio: waiting for connection\n");
7785fdd124a3b811993542825847f207587d5f4661eJens Axboe
779371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe	if (poll_wait(td, nd->listenfd, POLLIN) < 0)
780859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe		goto err;
7810c09442b26216aed16f758712f744a2c54726cdbJens Axboe
78249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	if (o->proto == FIO_TYPE_TCP) {
78349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		socklen = sizeof(nd->addr);
78449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		f->fd = accept(nd->listenfd, (struct sockaddr *) &nd->addr, &socklen);
78549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	} else {
78649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		socklen = sizeof(nd->addr6);
78749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		f->fd = accept(nd->listenfd, (struct sockaddr *) &nd->addr6, &socklen);
78849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	}
78949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe
790371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe	if (f->fd < 0) {
791371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe		td_verror(td, errno, "accept");
792859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe		goto err;
793b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	}
7945fdd124a3b811993542825847f207587d5f4661eJens Axboe
7951eafa37ac57bb08ca21af8ab76bd7848ae2e7c97Jens Axboe#ifdef CONFIG_TCP_NODELAY
79649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	if (o->nodelay && is_tcp(o)) {
7976264c7a8ddd0998f371604c227d3aea491922681Jens Axboe		int optval = 1;
7986264c7a8ddd0998f371604c227d3aea491922681Jens Axboe
79926e594a55a54d47ce0a0784c27c6f851c83d101aJens Axboe		if (setsockopt(f->fd, IPPROTO_TCP, TCP_NODELAY, (void *) &optval, sizeof(int)) < 0) {
80070a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan			log_err("fio: cannot set TCP_NODELAY option on socket (%s), disable with 'nodelay=0'\n", strerror(errno));
80170a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan			return 1;
80270a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan		}
80370a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan	}
8041eafa37ac57bb08ca21af8ab76bd7848ae2e7c97Jens Axboe#endif
80570a7878c00e130affc3e0bd7d59bd83d57c3268eSteven Noonan
8060cae16ffe3e4ca17cdb88fe64d357b7cde643f6aJens Axboe	reset_all_stats(td);
807859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe	td_set_runstate(td, state);
808b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	return 0;
809859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboeerr:
810859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe	td_set_runstate(td, state);
811859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe	return 1;
812b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe}
813b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
814664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestatic void fio_netio_udp_close(struct thread_data *td, struct fio_file *f)
815664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe{
816664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	struct netio_data *nd = td->io_ops->data;
81749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	struct netio_options *o = td->eo;
818664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	struct udp_close_msg msg;
81949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	struct sockaddr *to;
82049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	socklen_t len;
821664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	int ret;
822664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
82349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	if (is_ipv6(o)) {
82449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		to = (struct sockaddr *) &nd->addr6;
82549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		len = sizeof(nd->addr6);
82649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	} else {
82749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		to = (struct sockaddr *) &nd->addr;
82849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		len = sizeof(nd->addr);
82949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	}
83049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe
831b96d243044023b28731341d290943b5d47a5f794Jens Axboe	msg.magic = htonl(FIO_LINK_OPEN_CLOSE_MAGIC);
832664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	msg.cmd = htonl(FIO_LINK_CLOSE);
833664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
83449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	ret = sendto(f->fd, (void *) &msg, sizeof(msg), MSG_WAITALL, to, len);
835664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	if (ret < 0)
836664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		td_verror(td, errno, "sendto udp link close");
837664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe}
838664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
839664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboestatic int fio_netio_close_file(struct thread_data *td, struct fio_file *f)
840664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe{
841de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
842664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
843664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	/*
844664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	 * If this is an UDP connection, notify the receiver that we are
845664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	 * closing down the link
846664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	 */
84749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	if (is_udp(o))
848664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe		fio_netio_udp_close(td, f);
849664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
850664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe	return generic_close_file(td, f);
851664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe}
852664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
853b96d243044023b28731341d290943b5d47a5f794Jens Axboestatic int fio_netio_udp_recv_open(struct thread_data *td, struct fio_file *f)
854b96d243044023b28731341d290943b5d47a5f794Jens Axboe{
855b96d243044023b28731341d290943b5d47a5f794Jens Axboe	struct netio_data *nd = td->io_ops->data;
85649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	struct netio_options *o = td->eo;
857b96d243044023b28731341d290943b5d47a5f794Jens Axboe	struct udp_close_msg msg;
85849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	struct sockaddr *to;
85949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	socklen_t len;
860b96d243044023b28731341d290943b5d47a5f794Jens Axboe	int ret;
861b96d243044023b28731341d290943b5d47a5f794Jens Axboe
86249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	if (is_ipv6(o)) {
86349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		len = sizeof(nd->addr6);
86449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		to = (struct sockaddr *) &nd->addr6;
86549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	} else {
86649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		len = sizeof(nd->addr);
86749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		to = (struct sockaddr *) &nd->addr;
86849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	}
86949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe
8701f81991ed356dd7257aef2c715ba9a24d9af93a5Jens Axboe	ret = recvfrom(f->fd, (void *) &msg, sizeof(msg), MSG_WAITALL, to, &len);
871b96d243044023b28731341d290943b5d47a5f794Jens Axboe	if (ret < 0) {
872ee7062fdd7c2fdc0a0427343b5c5c119e7c08032Shawn Bohrer		td_verror(td, errno, "recvfrom udp link open");
873b96d243044023b28731341d290943b5d47a5f794Jens Axboe		return ret;
874b96d243044023b28731341d290943b5d47a5f794Jens Axboe	}
875b96d243044023b28731341d290943b5d47a5f794Jens Axboe
876b96d243044023b28731341d290943b5d47a5f794Jens Axboe	if (ntohl(msg.magic) != FIO_LINK_OPEN_CLOSE_MAGIC ||
877b96d243044023b28731341d290943b5d47a5f794Jens Axboe	    ntohl(msg.cmd) != FIO_LINK_OPEN) {
878b96d243044023b28731341d290943b5d47a5f794Jens Axboe		log_err("fio: bad udp open magic %x/%x\n", ntohl(msg.magic),
879b96d243044023b28731341d290943b5d47a5f794Jens Axboe								ntohl(msg.cmd));
880b96d243044023b28731341d290943b5d47a5f794Jens Axboe		return -1;
881b96d243044023b28731341d290943b5d47a5f794Jens Axboe	}
882b96d243044023b28731341d290943b5d47a5f794Jens Axboe
883b96d243044023b28731341d290943b5d47a5f794Jens Axboe	return 0;
884b96d243044023b28731341d290943b5d47a5f794Jens Axboe}
885b96d243044023b28731341d290943b5d47a5f794Jens Axboe
886b96d243044023b28731341d290943b5d47a5f794Jens Axboestatic int fio_netio_udp_send_open(struct thread_data *td, struct fio_file *f)
887b96d243044023b28731341d290943b5d47a5f794Jens Axboe{
888b96d243044023b28731341d290943b5d47a5f794Jens Axboe	struct netio_data *nd = td->io_ops->data;
88949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	struct netio_options *o = td->eo;
890b96d243044023b28731341d290943b5d47a5f794Jens Axboe	struct udp_close_msg msg;
89149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	struct sockaddr *to;
89249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	socklen_t len;
893b96d243044023b28731341d290943b5d47a5f794Jens Axboe	int ret;
894b96d243044023b28731341d290943b5d47a5f794Jens Axboe
89549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	if (is_ipv6(o)) {
89649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		len = sizeof(nd->addr6);
89749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		to = (struct sockaddr *) &nd->addr6;
89849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	} else {
89949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		len = sizeof(nd->addr);
90049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		to = (struct sockaddr *) &nd->addr;
90149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	}
90249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe
903b96d243044023b28731341d290943b5d47a5f794Jens Axboe	msg.magic = htonl(FIO_LINK_OPEN_CLOSE_MAGIC);
904b96d243044023b28731341d290943b5d47a5f794Jens Axboe	msg.cmd = htonl(FIO_LINK_OPEN);
905b96d243044023b28731341d290943b5d47a5f794Jens Axboe
90649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	ret = sendto(f->fd, (void *) &msg, sizeof(msg), MSG_WAITALL, to, len);
907b96d243044023b28731341d290943b5d47a5f794Jens Axboe	if (ret < 0) {
908b96d243044023b28731341d290943b5d47a5f794Jens Axboe		td_verror(td, errno, "sendto udp link open");
909b96d243044023b28731341d290943b5d47a5f794Jens Axboe		return ret;
910b96d243044023b28731341d290943b5d47a5f794Jens Axboe	}
911b96d243044023b28731341d290943b5d47a5f794Jens Axboe
912b96d243044023b28731341d290943b5d47a5f794Jens Axboe	return 0;
913b96d243044023b28731341d290943b5d47a5f794Jens Axboe}
914b96d243044023b28731341d290943b5d47a5f794Jens Axboe
915b96d243044023b28731341d290943b5d47a5f794Jens Axboestatic int fio_netio_open_file(struct thread_data *td, struct fio_file *f)
916b96d243044023b28731341d290943b5d47a5f794Jens Axboe{
917b96d243044023b28731341d290943b5d47a5f794Jens Axboe	int ret;
918b96d243044023b28731341d290943b5d47a5f794Jens Axboe	struct netio_options *o = td->eo;
919b96d243044023b28731341d290943b5d47a5f794Jens Axboe
920b96d243044023b28731341d290943b5d47a5f794Jens Axboe	if (o->listen)
921b96d243044023b28731341d290943b5d47a5f794Jens Axboe		ret = fio_netio_accept(td, f);
922b96d243044023b28731341d290943b5d47a5f794Jens Axboe	else
923b96d243044023b28731341d290943b5d47a5f794Jens Axboe		ret = fio_netio_connect(td, f);
924b96d243044023b28731341d290943b5d47a5f794Jens Axboe
925b96d243044023b28731341d290943b5d47a5f794Jens Axboe	if (ret) {
926b96d243044023b28731341d290943b5d47a5f794Jens Axboe		f->fd = -1;
927b96d243044023b28731341d290943b5d47a5f794Jens Axboe		return ret;
928b96d243044023b28731341d290943b5d47a5f794Jens Axboe	}
929b96d243044023b28731341d290943b5d47a5f794Jens Axboe
93049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	if (is_udp(o)) {
931b96d243044023b28731341d290943b5d47a5f794Jens Axboe		if (td_write(td))
932b96d243044023b28731341d290943b5d47a5f794Jens Axboe			ret = fio_netio_udp_send_open(td, f);
933b96d243044023b28731341d290943b5d47a5f794Jens Axboe		else {
934b96d243044023b28731341d290943b5d47a5f794Jens Axboe			int state;
935b96d243044023b28731341d290943b5d47a5f794Jens Axboe
936b96d243044023b28731341d290943b5d47a5f794Jens Axboe			state = td->runstate;
937b96d243044023b28731341d290943b5d47a5f794Jens Axboe			td_set_runstate(td, TD_SETTING_UP);
938b96d243044023b28731341d290943b5d47a5f794Jens Axboe			ret = fio_netio_udp_recv_open(td, f);
939b96d243044023b28731341d290943b5d47a5f794Jens Axboe			td_set_runstate(td, state);
940b96d243044023b28731341d290943b5d47a5f794Jens Axboe		}
941b96d243044023b28731341d290943b5d47a5f794Jens Axboe	}
942b96d243044023b28731341d290943b5d47a5f794Jens Axboe
943b96d243044023b28731341d290943b5d47a5f794Jens Axboe	if (ret)
944b96d243044023b28731341d290943b5d47a5f794Jens Axboe		fio_netio_close_file(td, f);
945b96d243044023b28731341d290943b5d47a5f794Jens Axboe
946b96d243044023b28731341d290943b5d47a5f794Jens Axboe	return ret;
947b96d243044023b28731341d290943b5d47a5f794Jens Axboe}
948b96d243044023b28731341d290943b5d47a5f794Jens Axboe
9490b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboestatic int fio_fill_addr(struct thread_data *td, const char *host, int af,
9500b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe			 void *dst, struct addrinfo **res)
9510b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe{
9520b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe	struct netio_options *o = td->eo;
9530b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe	struct addrinfo hints;
9540b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe	int ret;
9550b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe
9560b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe	if (inet_pton(af, host, dst))
9570b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe		return 0;
9580b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe
9590b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe	memset(&hints, 0, sizeof(hints));
9600b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe
9610b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe	if (is_tcp(o))
9620b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe		hints.ai_socktype = SOCK_STREAM;
9630b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe	else
9640b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe		hints.ai_socktype = SOCK_DGRAM;
9650b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe
966b1b1be2a569fb9226fa1ebbfed91f34322ce1c9cJens Axboe	if (is_ipv6(o))
967b1b1be2a569fb9226fa1ebbfed91f34322ce1c9cJens Axboe		hints.ai_family = AF_INET6;
968b1b1be2a569fb9226fa1ebbfed91f34322ce1c9cJens Axboe	else
969b1b1be2a569fb9226fa1ebbfed91f34322ce1c9cJens Axboe		hints.ai_family = AF_INET;
970b1b1be2a569fb9226fa1ebbfed91f34322ce1c9cJens Axboe
9710b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe	ret = getaddrinfo(host, NULL, &hints, res);
9720b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe	if (ret) {
9730b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe		int e = EINVAL;
9740b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe		char str[128];
9750b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe
9760b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe		if (ret == EAI_SYSTEM)
9770b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe			e = errno;
9780b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe
9790b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe		snprintf(str, sizeof(str), "getaddrinfo: %s", gai_strerror(ret));
9800b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe		td_verror(td, e, str);
9810b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe		return 1;
9820b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe	}
9830b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe
9840b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe	return 0;
9850b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe}
9860b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe
9870fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboestatic int fio_netio_setup_connect_inet(struct thread_data *td,
9880fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe					const char *host, unsigned short port)
989b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{
990b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
99149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	struct netio_options *o = td->eo;
9920b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe	struct addrinfo *res = NULL;
9930b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe	void *dst, *src;
9940b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe	int af, len;
995b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
996166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe	if (!host) {
997166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe		log_err("fio: connect with no host to connect to.\n");
998166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe		if (td_read(td))
999166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe			log_err("fio: did you forget to set 'listen'?\n");
1000166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe
1001166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe		td_verror(td, EINVAL, "no hostname= set");
1002166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe		return 1;
1003166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe	}
1004166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe
10050b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe	nd->addr.sin_family = AF_INET;
10060b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe	nd->addr.sin_port = htons(port);
10070b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe	nd->addr6.sin6_family = AF_INET6;
10080b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe	nd->addr6.sin6_port = htons(port);
1009b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
10100b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe	if (is_ipv6(o)) {
10110b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe		af = AF_INET6;
101268631b36e37e1ecaadc1e5697ead4adc21640562Jens Axboe		dst = &nd->addr6.sin6_addr;
101349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	} else {
10140b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe		af = AF_INET;
101568631b36e37e1ecaadc1e5697ead4adc21640562Jens Axboe		dst = &nd->addr.sin_addr;
10160b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe	}
101749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe
10180b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe	if (fio_fill_addr(td, host, af, dst, &res))
10190b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe		return 1;
102049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe
10210b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe	if (!res)
10220b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe		return 0;
102349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe
10240b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe	if (is_ipv6(o)) {
10250b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe		len = sizeof(nd->addr6.sin6_addr);
10260b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe		src = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
10270b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe	} else {
10280b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe		len = sizeof(nd->addr.sin_addr);
10290b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe		src = &((struct sockaddr_in *) res->ai_addr)->sin_addr;
10305fdd124a3b811993542825847f207587d5f4661eJens Axboe	}
10315fdd124a3b811993542825847f207587d5f4661eJens Axboe
10320b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe	memcpy(dst, src, len);
10330b783341927056e62ca2178c2ca74cca2c7b0100Jens Axboe	freeaddrinfo(res);
10345fdd124a3b811993542825847f207587d5f4661eJens Axboe	return 0;
10355fdd124a3b811993542825847f207587d5f4661eJens Axboe}
10365fdd124a3b811993542825847f207587d5f4661eJens Axboe
10370fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboestatic int fio_netio_setup_connect_unix(struct thread_data *td,
10380fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe					const char *path)
10390fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe{
10400fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	struct netio_data *nd = td->io_ops->data;
10410fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	struct sockaddr_un *soun = &nd->addr_un;
10420fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
10430fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	soun->sun_family = AF_UNIX;
10444b159fa61a9c3ed7e00c8135189c184dcc48c69fJens Axboe	memset(soun->sun_path, 0, sizeof(soun->sun_path));
10454b159fa61a9c3ed7e00c8135189c184dcc48c69fJens Axboe	strncpy(soun->sun_path, path, sizeof(soun->sun_path) - 1);
10460fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	return 0;
10470fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe}
10480fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
1049de890a1e48d40238dac69f302708dde8719de240Steven Langstatic int fio_netio_setup_connect(struct thread_data *td)
10500fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe{
1051de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
10520fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
105349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	if (is_udp(o) || is_tcp(o))
1054de890a1e48d40238dac69f302708dde8719de240Steven Lang		return fio_netio_setup_connect_inet(td, td->o.filename,o->port);
10550fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	else
1056de890a1e48d40238dac69f302708dde8719de240Steven Lang		return fio_netio_setup_connect_unix(td, td->o.filename);
10570fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe}
10580fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
10590fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboestatic int fio_netio_setup_listen_unix(struct thread_data *td, const char *path)
10600fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe{
10610fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	struct netio_data *nd = td->io_ops->data;
10620fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	struct sockaddr_un *addr = &nd->addr_un;
10630fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	mode_t mode;
10640fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	int len, fd;
10650fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
10660fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	fd = socket(AF_UNIX, SOCK_STREAM, 0);
10670fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	if (fd < 0) {
10680fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		log_err("fio: socket: %s\n", strerror(errno));
10690fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		return -1;
10700fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	}
10710fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
10720fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	mode = umask(000);
10730fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
10740fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	memset(addr, 0, sizeof(*addr));
10750fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	addr->sun_family = AF_UNIX;
10764b159fa61a9c3ed7e00c8135189c184dcc48c69fJens Axboe	strncpy(addr->sun_path, path, sizeof(addr->sun_path) - 1);
10770fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	unlink(path);
10780fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
10790fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	len = sizeof(addr->sun_family) + strlen(path) + 1;
10800fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
10810fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	if (bind(fd, (struct sockaddr *) addr, len) < 0) {
10820fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		log_err("fio: bind: %s\n", strerror(errno));
1083b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe		close(fd);
10840fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		return -1;
10850fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	}
10860fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
10870fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	umask(mode);
10880fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	nd->listenfd = fd;
10890fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	return 0;
10900fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe}
10910fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
10920fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboestatic int fio_netio_setup_listen_inet(struct thread_data *td, short port)
1093ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
1094b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
1095de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
1096b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer	struct ip_mreq mr;
1097b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer	struct sockaddr_in sin;
109849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	struct sockaddr *saddr;
109949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	int fd, opt, type, domain;
110049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	socklen_t len;
1101ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
1102b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer	memset(&sin, 0, sizeof(sin));
110349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe
110449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	if (o->proto == FIO_TYPE_TCP) {
1105414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		type = SOCK_STREAM;
110649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		domain = AF_INET;
110749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	} else if (o->proto == FIO_TYPE_TCP_V6) {
110849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		type = SOCK_STREAM;
110949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		domain = AF_INET6;
111049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	} else if (o->proto == FIO_TYPE_UDP) {
1111414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe		type = SOCK_DGRAM;
111249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		domain = AF_INET;
111349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	} else if (o->proto == FIO_TYPE_UDP_V6) {
111449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		type = SOCK_DGRAM;
111549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		domain = AF_INET6;
111649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	} else {
111749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		log_err("fio: unknown proto %d\n", o->proto);
111849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		return 1;
111949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	}
1120414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
112149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	fd = socket(domain, type, 0);
1122ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	if (fd < 0) {
1123e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, errno, "socket");
1124ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
1125ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
1126ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
1127ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	opt = 1;
112826e594a55a54d47ce0a0784c27c6f851c83d101aJens Axboe	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *) &opt, sizeof(opt)) < 0) {
1129e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, errno, "setsockopt");
11304a93dec2a85f4a979421638fde2877268c470ab1Shawn Bohrer		close(fd);
1131ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
1132ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
11336bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe#ifdef SO_REUSEPORT
113426e594a55a54d47ce0a0784c27c6f851c83d101aJens Axboe	if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, (void *) &opt, sizeof(opt)) < 0) {
1135e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, errno, "setsockopt");
11364a93dec2a85f4a979421638fde2877268c470ab1Shawn Bohrer		close(fd);
11376bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe		return 1;
11386bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe	}
11396bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe#endif
1140ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
1141531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe	if (set_window_size(td, fd)) {
1142531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe		close(fd);
1143531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe		return 1;
1144531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe	}
11455e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe	if (set_mss(td, fd)) {
11465e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe		close(fd);
11475e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe		return 1;
11485e34ceafd6ea07785c470c8a8cd7cae740493743Jens Axboe	}
1149531e67afb01714c03a3aad00911a5c897f3f9e1dJens Axboe
11506611e9c767bad5c903c8ac59b9ae8409315dbca2Jens Axboe	if (td->o.filename) {
115149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		if (!is_udp(o) || !fio_netio_is_multicast(td->o.filename)) {
1152b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer			log_err("fio: hostname not valid for non-multicast inbound network IO\n");
1153b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer			close(fd);
1154b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer			return 1;
1155b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer		}
11566611e9c767bad5c903c8ac59b9ae8409315dbca2Jens Axboe		if (is_ipv6(o)) {
11576611e9c767bad5c903c8ac59b9ae8409315dbca2Jens Axboe			log_err("fio: IPv6 not supported for multicast network IO");
11586611e9c767bad5c903c8ac59b9ae8409315dbca2Jens Axboe			close(fd);
11596611e9c767bad5c903c8ac59b9ae8409315dbca2Jens Axboe			return 1;
11606611e9c767bad5c903c8ac59b9ae8409315dbca2Jens Axboe		}
1161b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer
1162b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer		inet_aton(td->o.filename, &sin.sin_addr);
1163b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer
1164b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer		mr.imr_multiaddr = sin.sin_addr;
1165f16b7405fff7c3fc1da421b6bdf8552cc99c3156Bruce Cran		if (o->intfc) {
1166f16b7405fff7c3fc1da421b6bdf8552cc99c3156Bruce Cran			if (inet_aton(o->intfc, &mr.imr_interface) == 0) {
1167b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer				log_err("fio: interface not valid interface IP\n");
1168b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer				close(fd);
1169b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer				return 1;
1170b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer			}
1171b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer		} else {
1172b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer			mr.imr_interface.s_addr = htonl(INADDR_ANY);
1173b93b6a2e1e0d9b919d0b2d4106d3abe415234a46Shawn Bohrer		}
11746611e9c767bad5c903c8ac59b9ae8409315dbca2Jens Axboe
1175f16b7405fff7c3fc1da421b6bdf8552cc99c3156Bruce Cran		if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&mr, sizeof(mr)) < 0) {
1176b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer			td_verror(td, errno, "setsockopt IP_ADD_MEMBERSHIP");
1177b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer			close(fd);
1178b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer			return 1;
1179b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer		}
1180b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer	}
1181b511c9aaa5f289596b05743c5b8e40451017129cShawn Bohrer
118249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	if (!is_ipv6(o)) {
118349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		saddr = (struct sockaddr *) &nd->addr;
118449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		len = sizeof(nd->addr);
118549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe
118649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		nd->addr.sin_family = AF_INET;
118749ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		nd->addr.sin_addr.s_addr = sin.sin_addr.s_addr ? sin.sin_addr.s_addr : htonl(INADDR_ANY);
118849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		nd->addr.sin_port = htons(port);
118949ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	} else {
119049ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		saddr = (struct sockaddr *) &nd->addr6;
119149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		len = sizeof(nd->addr6);
119249ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe
119349ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		nd->addr6.sin6_family = AF_INET6;
119466f7a56f70e40e9e953c47fae3a3432e87cd0cb7Jens Axboe		nd->addr6.sin6_addr = in6addr_any;
119549ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe		nd->addr6.sin6_port = htons(port);
119649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	}
1197ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
119849ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	if (bind(fd, saddr, len) < 0) {
1199d19cedd63494cf8aef6443fb2ce866cd7a977b98Jens Axboe		close(fd);
1200e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, errno, "bind");
1201ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
1202ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
12030fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
12040fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	nd->listenfd = fd;
12050fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	return 0;
12060fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe}
12070fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
1208de890a1e48d40238dac69f302708dde8719de240Steven Langstatic int fio_netio_setup_listen(struct thread_data *td)
12090fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe{
12100fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	struct netio_data *nd = td->io_ops->data;
1211de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
12120fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	int ret;
12130fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
121449ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	if (is_udp(o) || is_tcp(o))
1215de890a1e48d40238dac69f302708dde8719de240Steven Lang		ret = fio_netio_setup_listen_inet(td, o->port);
12160fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	else
1217de890a1e48d40238dac69f302708dde8719de240Steven Lang		ret = fio_netio_setup_listen_unix(td, td->o.filename);
12180fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
12190fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	if (ret)
12200fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		return ret;
122149ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	if (is_udp(o))
12220fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		return 0;
12230fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
12240fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	if (listen(nd->listenfd, 10) < 0) {
1225e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_verror(td, errno, "listen");
12260fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe		nd->listenfd = -1;
1227ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe		return 1;
1228ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe	}
1229ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
1230b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	return 0;
1231ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
1232ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
12339bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboestatic int fio_netio_init(struct thread_data *td)
1234ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
1235de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = td->eo;
1236af52b3455ad892322aab2791282b6bd4efdfdbf3Jens Axboe	int ret;
1237ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
12383f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran#ifdef WIN32
12393f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran	WSADATA wsd;
12403f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran	WSAStartup(MAKEWORD(2,2), &wsd);
12413f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran#endif
12423f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran
124316d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe	if (td_random(td)) {
124416d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe		log_err("fio: network IO can't be random\n");
124516d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe		return 1;
124616d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe	}
1247ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
1248de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->proto == FIO_TYPE_UNIX && o->port) {
1249de890a1e48d40238dac69f302708dde8719de240Steven Lang		log_err("fio: network IO port not valid with unix socket\n");
1250de890a1e48d40238dac69f302708dde8719de240Steven Lang		return 1;
1251de890a1e48d40238dac69f302708dde8719de240Steven Lang	} else if (o->proto != FIO_TYPE_UNIX && !o->port) {
1252de890a1e48d40238dac69f302708dde8719de240Steven Lang		log_err("fio: network IO requires port for tcp or udp\n");
1253de890a1e48d40238dac69f302708dde8719de240Steven Lang		return 1;
1254de890a1e48d40238dac69f302708dde8719de240Steven Lang	}
1255ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
125649ccb8c10036ca0dca1238558c390f61f769c3c9Jens Axboe	if (!is_tcp(o)) {
1257de890a1e48d40238dac69f302708dde8719de240Steven Lang		if (o->listen) {
12589b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe			log_err("fio: listen only valid for TCP proto IO\n");
12599b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe			return 1;
1260de890a1e48d40238dac69f302708dde8719de240Steven Lang		}
1261de890a1e48d40238dac69f302708dde8719de240Steven Lang		if (td_rw(td)) {
12629b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe			log_err("fio: datagram network connections must be"
1263de890a1e48d40238dac69f302708dde8719de240Steven Lang				   " read OR write\n");
12649b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe			return 1;
12659b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe		}
12669b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe		if (o->proto == FIO_TYPE_UNIX && !td->o.filename) {
12679b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe			log_err("fio: UNIX sockets need host/filename\n");
12689b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe			return 1;
1269de890a1e48d40238dac69f302708dde8719de240Steven Lang		}
1270de890a1e48d40238dac69f302708dde8719de240Steven Lang		o->listen = td_read(td);
1271de890a1e48d40238dac69f302708dde8719de240Steven Lang	}
1272443662efa60d9082bc820641e7d1d31dd58d3ae1Jens Axboe
1273de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->listen)
1274de890a1e48d40238dac69f302708dde8719de240Steven Lang		ret = fio_netio_setup_listen(td);
12750fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe	else
1276de890a1e48d40238dac69f302708dde8719de240Steven Lang		ret = fio_netio_setup_connect(td);
1277ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
12787bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe	return ret;
1279ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
1280ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
1281b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic void fio_netio_cleanup(struct thread_data *td)
12829bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe{
1283b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	struct netio_data *nd = td->io_ops->data;
1284b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
1285b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	if (nd) {
128664b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe		if (nd->listenfd != -1)
128764b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe			close(nd->listenfd);
128864b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe		if (nd->pipes[0] != -1)
128964b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe			close(nd->pipes[0]);
129064b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe		if (nd->pipes[1] != -1)
129164b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe			close(nd->pipes[1]);
129264b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe
1293b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe		free(nd);
1294b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe	}
1295b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe}
1296b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
1297b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboestatic int fio_netio_setup(struct thread_data *td)
1298b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{
12997bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe	struct netio_data *nd;
13007bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe
1301de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (!td->files_index) {
13025903e7b7907854014478b6febfc5645a203ff59eJens Axboe		add_file(td, td->o.filename ?: "net", 0, 0);
1303de890a1e48d40238dac69f302708dde8719de240Steven Lang		td->o.nr_files = td->o.nr_files ?: 1;
1304b53f2c545d8335380b507bd7281178c25d27ddf0Jens Axboe		td->o.open_files++;
1305de890a1e48d40238dac69f302708dde8719de240Steven Lang	}
1306de890a1e48d40238dac69f302708dde8719de240Steven Lang
13077bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe	if (!td->io_ops->data) {
13087bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe		nd = malloc(sizeof(*nd));;
13097bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe
13107bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe		memset(nd, 0, sizeof(*nd));
13117bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe		nd->listenfd = -1;
131264b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe		nd->pipes[0] = nd->pipes[1] = -1;
13137bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe		td->io_ops->data = nd;
13147bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe	}
1315b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
13169bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe	return 0;
13179bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe}
13189bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe
131936d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboestatic void fio_netio_terminate(struct thread_data *td)
132036d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe{
1321e5f7caafa1eb8dc6343cea57cb5dc43e5774f058Jens Axboe	kill(td->pid, SIGTERM);
132236d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe}
132336d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe
132467bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe#ifdef CONFIG_LINUX_SPLICE
13259cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboestatic int fio_netio_setup_splice(struct thread_data *td)
13269cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe{
13279cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	struct netio_data *nd;
13289cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
13299cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	fio_netio_setup(td);
13309cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
13319cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	nd = td->io_ops->data;
13329cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	if (nd) {
13339cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		if (pipe(nd->pipes) < 0)
13349cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe			return 1;
13359cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
13369cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		nd->use_splice = 1;
13379cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe		return 0;
13389cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	}
13399cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
13409cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	return 1;
13419cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe}
13429cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
13435921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic struct ioengine_ops ioengine_splice = {
1344de890a1e48d40238dac69f302708dde8719de240Steven Lang	.name			= "netsplice",
1345de890a1e48d40238dac69f302708dde8719de240Steven Lang	.version		= FIO_IOOPS_VERSION,
1346de890a1e48d40238dac69f302708dde8719de240Steven Lang	.prep			= fio_netio_prep,
1347de890a1e48d40238dac69f302708dde8719de240Steven Lang	.queue			= fio_netio_queue,
1348de890a1e48d40238dac69f302708dde8719de240Steven Lang	.setup			= fio_netio_setup_splice,
1349de890a1e48d40238dac69f302708dde8719de240Steven Lang	.init			= fio_netio_init,
1350de890a1e48d40238dac69f302708dde8719de240Steven Lang	.cleanup		= fio_netio_cleanup,
1351de890a1e48d40238dac69f302708dde8719de240Steven Lang	.open_file		= fio_netio_open_file,
135236d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe	.close_file		= fio_netio_close_file,
135336d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe	.terminate		= fio_netio_terminate,
1354de890a1e48d40238dac69f302708dde8719de240Steven Lang	.options		= options,
1355de890a1e48d40238dac69f302708dde8719de240Steven Lang	.option_struct_size	= sizeof(struct netio_options),
1356de890a1e48d40238dac69f302708dde8719de240Steven Lang	.flags			= FIO_SYNCIO | FIO_DISKLESSIO | FIO_UNIDIR |
135736d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe				  FIO_PIPEIO,
1358ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe};
13595921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif
1360ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
13615921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboestatic struct ioengine_ops ioengine_rw = {
1362de890a1e48d40238dac69f302708dde8719de240Steven Lang	.name			= "net",
1363de890a1e48d40238dac69f302708dde8719de240Steven Lang	.version		= FIO_IOOPS_VERSION,
1364de890a1e48d40238dac69f302708dde8719de240Steven Lang	.prep			= fio_netio_prep,
1365de890a1e48d40238dac69f302708dde8719de240Steven Lang	.queue			= fio_netio_queue,
1366de890a1e48d40238dac69f302708dde8719de240Steven Lang	.setup			= fio_netio_setup,
1367de890a1e48d40238dac69f302708dde8719de240Steven Lang	.init			= fio_netio_init,
1368de890a1e48d40238dac69f302708dde8719de240Steven Lang	.cleanup		= fio_netio_cleanup,
1369de890a1e48d40238dac69f302708dde8719de240Steven Lang	.open_file		= fio_netio_open_file,
1370de890a1e48d40238dac69f302708dde8719de240Steven Lang	.close_file		= fio_netio_close_file,
137136d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe	.terminate		= fio_netio_terminate,
1372de890a1e48d40238dac69f302708dde8719de240Steven Lang	.options		= options,
1373de890a1e48d40238dac69f302708dde8719de240Steven Lang	.option_struct_size	= sizeof(struct netio_options),
1374de890a1e48d40238dac69f302708dde8719de240Steven Lang	.flags			= FIO_SYNCIO | FIO_DISKLESSIO | FIO_UNIDIR |
1375ad705bcb7e79a7cdb9891db17b4c40b13b6c30c3Steven Noonan				  FIO_PIPEIO | FIO_BIT_BASED,
13769cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe};
13779cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1378de890a1e48d40238dac69f302708dde8719de240Steven Langstatic int str_hostname_cb(void *data, const char *input)
1379de890a1e48d40238dac69f302708dde8719de240Steven Lang{
1380de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct netio_options *o = data;
1381de890a1e48d40238dac69f302708dde8719de240Steven Lang
1382de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (o->td->o.filename)
1383de890a1e48d40238dac69f302708dde8719de240Steven Lang		free(o->td->o.filename);
1384de890a1e48d40238dac69f302708dde8719de240Steven Lang	o->td->o.filename = strdup(input);
1385de890a1e48d40238dac69f302708dde8719de240Steven Lang	return 0;
1386de890a1e48d40238dac69f302708dde8719de240Steven Lang}
1387de890a1e48d40238dac69f302708dde8719de240Steven Lang
1388ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic void fio_init fio_netio_register(void)
1389ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
13909cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	register_ioengine(&ioengine_rw);
139167bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe#ifdef CONFIG_LINUX_SPLICE
13929cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	register_ioengine(&ioengine_splice);
13935921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif
1394ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
1395ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
1396ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboestatic void fio_exit fio_netio_unregister(void)
1397ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe{
13989cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	unregister_ioengine(&ioengine_rw);
139967bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe#ifdef CONFIG_LINUX_SPLICE
14009cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe	unregister_ioengine(&ioengine_splice);
14015921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif
1402ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe}
1403