| 185 | } |
| 186 | |
| 187 | static int do_recv(struct io_uring *ring, struct recv_data *rd) |
| 188 | { |
| 189 | struct io_uring_cqe *cqe; |
| 190 | int bid, next_bid = 0; |
| 191 | void *verify_ptr; |
| 192 | int verify_sz = 0; |
| 193 | int verify_bid = 0; |
| 194 | |
| 195 | verify_ptr = malloc(rd->recv_bytes); |
| 196 | |
| 197 | do { |
| 198 | if (recv_get_cqe(ring, rd, &cqe)) |
| 199 | break; |
| 200 | if (cqe->res == -EINVAL) { |
| 201 | fprintf(stdout, "recv not supported, skipping\n"); |
| 202 | return 0; |
| 203 | } |
| 204 | if (cqe->res < 0) { |
| 205 | fprintf(stderr, "failed recv cqe: %d\n", cqe->res); |
| 206 | goto err; |
| 207 | } |
| 208 | if (!(cqe->flags & IORING_CQE_F_BUFFER)) { |
| 209 | fprintf(stderr, "no buffer set in recv\n"); |
| 210 | goto err; |
| 211 | } |
| 212 | bid = cqe->flags >> IORING_CQE_BUFFER_SHIFT; |
| 213 | if (bid != next_bid) { |
| 214 | fprintf(stderr, "got bid %d, wanted %d\n", bid, next_bid); |
| 215 | goto err; |
| 216 | } |
| 217 | if (!rd->recv_bundle && cqe->res > MSG_SIZE) { |
| 218 | fprintf(stderr, "recv got wrong length: %d\n", cqe->res); |
| 219 | goto err; |
| 220 | } |
| 221 | if (!(verify_sz % MSG_SIZE)) { |
| 222 | if (!verify_seq(rd, verify_ptr, verify_sz, verify_bid)) |
| 223 | goto err; |
| 224 | verify_bid += verify_sz / MSG_SIZE; |
| 225 | verify_bid &= RECV_BID_MASK; |
| 226 | verify_sz = 0; |
| 227 | } else { |
| 228 | memcpy(verify_ptr + verify_sz, rd->recv_buf + (bid * MSG_SIZE), cqe->res); |
| 229 | verify_sz += cqe->res; |
| 230 | } |
| 231 | next_bid = bid + ((cqe->res + MSG_SIZE - 1) / MSG_SIZE); |
| 232 | next_bid &= RECV_BID_MASK; |
| 233 | rd->recv_bytes -= cqe->res; |
| 234 | io_uring_cqe_seen(ring, cqe); |
| 235 | if (!(cqe->flags & IORING_CQE_F_MORE) && rd->recv_bytes) { |
| 236 | if (arm_recv(ring, rd)) |
| 237 | goto err; |
| 238 | } |
| 239 | } while (rd->recv_bytes); |
| 240 | |
| 241 | if (verify_sz && !(verify_sz % MSG_SIZE) && |
| 242 | !verify_seq(rd, verify_ptr, verify_sz, verify_bid)) |
| 243 | goto err; |
| 244 |
no test coverage detected