|
20 | 20 | #include <sys/mman.h>
|
21 | 21 | #include <poll.h>
|
22 | 22 | #include <signal.h>
|
| 23 | +#include <sys/ioctl.h> |
| 24 | +#include <linux/sockios.h> |
23 | 25 |
|
24 | 26 | #include "vsock_test_zerocopy.h"
|
25 | 27 | #include "timeout.h"
|
@@ -1238,6 +1240,79 @@ static void test_double_bind_connect_client(const struct test_opts *opts)
|
1238 | 1240 | }
|
1239 | 1241 | }
|
1240 | 1242 |
|
| 1243 | +#define MSG_BUF_IOCTL_LEN 64 |
| 1244 | +static void test_unsent_bytes_server(const struct test_opts *opts, int type) |
| 1245 | +{ |
| 1246 | + unsigned char buf[MSG_BUF_IOCTL_LEN]; |
| 1247 | + int client_fd; |
| 1248 | + |
| 1249 | + client_fd = vsock_accept(VMADDR_CID_ANY, opts->peer_port, NULL, type); |
| 1250 | + if (client_fd < 0) { |
| 1251 | + perror("accept"); |
| 1252 | + exit(EXIT_FAILURE); |
| 1253 | + } |
| 1254 | + |
| 1255 | + recv_buf(client_fd, buf, sizeof(buf), 0, sizeof(buf)); |
| 1256 | + control_writeln("RECEIVED"); |
| 1257 | + |
| 1258 | + close(client_fd); |
| 1259 | +} |
| 1260 | + |
| 1261 | +static void test_unsent_bytes_client(const struct test_opts *opts, int type) |
| 1262 | +{ |
| 1263 | + unsigned char buf[MSG_BUF_IOCTL_LEN]; |
| 1264 | + int ret, fd, sock_bytes_unsent; |
| 1265 | + |
| 1266 | + fd = vsock_connect(opts->peer_cid, opts->peer_port, type); |
| 1267 | + if (fd < 0) { |
| 1268 | + perror("connect"); |
| 1269 | + exit(EXIT_FAILURE); |
| 1270 | + } |
| 1271 | + |
| 1272 | + for (int i = 0; i < sizeof(buf); i++) |
| 1273 | + buf[i] = rand() & 0xFF; |
| 1274 | + |
| 1275 | + send_buf(fd, buf, sizeof(buf), 0, sizeof(buf)); |
| 1276 | + control_expectln("RECEIVED"); |
| 1277 | + |
| 1278 | + ret = ioctl(fd, SIOCOUTQ, &sock_bytes_unsent); |
| 1279 | + if (ret < 0) { |
| 1280 | + if (errno == EOPNOTSUPP) { |
| 1281 | + fprintf(stderr, "Test skipped, SIOCOUTQ not supported.\n"); |
| 1282 | + } else { |
| 1283 | + perror("ioctl"); |
| 1284 | + exit(EXIT_FAILURE); |
| 1285 | + } |
| 1286 | + } else if (ret == 0 && sock_bytes_unsent != 0) { |
| 1287 | + fprintf(stderr, |
| 1288 | + "Unexpected 'SIOCOUTQ' value, expected 0, got %i\n", |
| 1289 | + sock_bytes_unsent); |
| 1290 | + exit(EXIT_FAILURE); |
| 1291 | + } |
| 1292 | + |
| 1293 | + close(fd); |
| 1294 | +} |
| 1295 | + |
| 1296 | +static void test_stream_unsent_bytes_client(const struct test_opts *opts) |
| 1297 | +{ |
| 1298 | + test_unsent_bytes_client(opts, SOCK_STREAM); |
| 1299 | +} |
| 1300 | + |
| 1301 | +static void test_stream_unsent_bytes_server(const struct test_opts *opts) |
| 1302 | +{ |
| 1303 | + test_unsent_bytes_server(opts, SOCK_STREAM); |
| 1304 | +} |
| 1305 | + |
| 1306 | +static void test_seqpacket_unsent_bytes_client(const struct test_opts *opts) |
| 1307 | +{ |
| 1308 | + test_unsent_bytes_client(opts, SOCK_SEQPACKET); |
| 1309 | +} |
| 1310 | + |
| 1311 | +static void test_seqpacket_unsent_bytes_server(const struct test_opts *opts) |
| 1312 | +{ |
| 1313 | + test_unsent_bytes_server(opts, SOCK_SEQPACKET); |
| 1314 | +} |
| 1315 | + |
1241 | 1316 | #define RCVLOWAT_CREDIT_UPD_BUF_SIZE (1024 * 128)
|
1242 | 1317 | /* This define is the same as in 'include/linux/virtio_vsock.h':
|
1243 | 1318 | * it is used to decide when to send credit update message during
|
@@ -1523,6 +1598,16 @@ static struct test_case test_cases[] = {
|
1523 | 1598 | .run_client = test_stream_rcvlowat_def_cred_upd_client,
|
1524 | 1599 | .run_server = test_stream_cred_upd_on_low_rx_bytes,
|
1525 | 1600 | },
|
| 1601 | + { |
| 1602 | + .name = "SOCK_STREAM ioctl(SIOCOUTQ) 0 unsent bytes", |
| 1603 | + .run_client = test_stream_unsent_bytes_client, |
| 1604 | + .run_server = test_stream_unsent_bytes_server, |
| 1605 | + }, |
| 1606 | + { |
| 1607 | + .name = "SOCK_SEQPACKET ioctl(SIOCOUTQ) 0 unsent bytes", |
| 1608 | + .run_client = test_seqpacket_unsent_bytes_client, |
| 1609 | + .run_server = test_seqpacket_unsent_bytes_server, |
| 1610 | + }, |
1526 | 1611 | {},
|
1527 | 1612 | };
|
1528 | 1613 |
|
|
0 commit comments