/
githubmirror
/
liburing
Обзор
Документация
Войти
/
githubmirror
/
liburing
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
test/conn-unreach.c
132 строки
3 KB
Jens Axboe
test/conn-unreach: fix bad res value
01 фев 2026, 01:46
01 фев 2026, 01:46
14000b9
Код
Авторство
О чём код?
/* SPDX-License-Identifier: MIT */ /* * Check that IORING_OP_CONNECT properly returns -ECONNRESET when * attempting to connect to an unreachable address. See: * * https://github.com/axboe/liburing/discussions/1335 */ #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <string.h> #include <assert.h> #include <errno.h> #include <fcntl.h> #include <unistd.h> #include <sys/socket.h> #include <sys/un.h> #include <netinet/tcp.h> #include <netinet/in.h> #include <arpa/inet.h> #include "liburing.h" #include "helpers.h" static int check_cqe(struct io_uring *ring, struct io_uring_cqe *cqe) { if (cqe->res == -EINVAL) return T_EXIT_SKIP; switch (cqe->user_data) { case 1: if (cqe->res != -ECONNRESET && cqe->res != -ENETUNREACH) { fprintf(stderr, "Unexpected connect: %d\n", cqe->res); return T_EXIT_FAIL; } break; case 2: if (cqe->res) { fprintf(stderr, "Unexpected shutdown: %d\n", cqe->res); return T_EXIT_FAIL; } break; } io_uring_cqe_seen(ring, cqe); return T_EXIT_PASS; } static int test(struct io_uring *ring, struct sockaddr_in *saddr, int p_fd) { struct io_uring_cqe *cqe; struct io_uring_sqe *sqe1, *sqe2; socklen_t val_len; int ret, val; sqe1 = io_uring_get_sqe(ring); io_uring_prep_connect(sqe1, p_fd, (struct sockaddr *)saddr, sizeof(*saddr)); sqe1->user_data = 1; ret = io_uring_submit(ring); assert(ret != -1); usleep(200000); // 200ms sqe2 = io_uring_get_sqe(ring); io_uring_prep_shutdown(sqe2, p_fd, SHUT_RDWR); sqe2->user_data = 2; ret = io_uring_submit(ring); assert(ret != -1); ret = io_uring_wait_cqe(ring, &cqe); if (ret < 0) { fprintf(stderr, "wait: %s\n", strerror(-ret)); return T_EXIT_FAIL; } ret = check_cqe(ring, cqe); if (ret != T_EXIT_PASS) return ret; val = 0; val_len = sizeof(val); ret = getsockopt(p_fd, SOL_SOCKET, SO_ERROR, &val, &val_len); assert(ret != -1); ret = io_uring_wait_cqe(ring, &cqe); if (ret < 0) { fprintf(stderr, "wait: %s\n", strerror(-ret)); return T_EXIT_FAIL; } return check_cqe(ring, cqe); } int main(int argc, char *argv[]) { struct sockaddr_in addr = { }; struct io_uring ring; int val, p_fd, ret; if (argc > 1) return T_EXIT_SKIP; p_fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP); val = 1; ret = setsockopt(p_fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)); assert(ret != -1); // NB. these are to make things faster val = 2; ret = setsockopt(p_fd, IPPROTO_TCP, TCP_SYNCNT, &val, sizeof(val)); assert(ret != -1); val = 500; // 500ms ret = setsockopt(p_fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &val, sizeof(val)); assert(ret != -1); t_set_nonblock(p_fd); addr.sin_family = AF_INET; /* any unreachable address */ addr.sin_addr.s_addr = inet_addr("172.31.5.5"); addr.sin_port = htons(12345); ret = io_uring_queue_init(2, &ring, 0); assert(ret >= 0); ret = test(&ring, &addr, p_fd); io_uring_queue_exit(&ring); return ret; }