| 1278 | } |
| 1279 | |
| 1280 | static int __handle_recv(struct io_uring *ring, struct conn *c, |
| 1281 | struct conn_dir *cd, struct io_uring_cqe *cqe) |
| 1282 | { |
| 1283 | struct conn_dir *ocd = &c->cd[!cd->index]; |
| 1284 | int bid, nr_packets; |
| 1285 | |
| 1286 | /* |
| 1287 | * Not having a buffer attached should only happen if we get a zero |
| 1288 | * sized receive, because the other end closed the connection. It |
| 1289 | * cannot happen otherwise, as all our receives are using provided |
| 1290 | * buffers and hence it's not possible to return a CQE with a non-zero |
| 1291 | * result and not have a buffer attached. |
| 1292 | */ |
| 1293 | if (!(cqe->flags & IORING_CQE_F_BUFFER)) { |
| 1294 | cd->pending_recv = 0; |
| 1295 | |
| 1296 | if (!recv_done_res(cqe->res)) { |
| 1297 | fprintf(stderr, "no buffer assigned, res=%d\n", cqe->res); |
| 1298 | return 1; |
| 1299 | } |
| 1300 | start_close: |
| 1301 | prep_next_send(ring, c, ocd, other_dir_fd(c, cqe_to_fd(cqe))); |
| 1302 | close_cd(c, cd); |
| 1303 | return 0; |
| 1304 | } |
| 1305 | |
| 1306 | if (cqe->res && cqe->res < buf_size) |
| 1307 | cd->rcv_shrt++; |
| 1308 | |
| 1309 | bid = cqe->flags >> IORING_CQE_BUFFER_SHIFT; |
| 1310 | |
| 1311 | /* |
| 1312 | * BIDI will use the same buffer pool and do receive on both CDs, |
| 1313 | * so can't reliably check. TODO. |
| 1314 | */ |
| 1315 | if (!bidi && cd->rcv_next_bid != -1 && bid != cd->rcv_next_bid) { |
| 1316 | fprintf(stderr, "recv bid %d, wanted %d\n", bid, cd->rcv_next_bid); |
| 1317 | goto start_close; |
| 1318 | } |
| 1319 | |
| 1320 | vlog("%d: recv: bid=%d, res=%d, cflags=%x\n", c->tid, bid, cqe->res, cqe->flags); |
| 1321 | /* |
| 1322 | * If we're a sink, we're done here. Just replenish the buffer back |
| 1323 | * to the pool. For proxy mode, we will send the data to the other |
| 1324 | * end and the buffer will be replenished once the send is done with |
| 1325 | * it. |
| 1326 | */ |
| 1327 | if (buf_ring_inc) |
| 1328 | nr_packets = recv_inc(c, ocd, &bid, cqe); |
| 1329 | else if (is_sink) |
| 1330 | nr_packets = replenish_buffers(c, &bid, cqe->res); |
| 1331 | else if (rcv_msg && recv_mshot) |
| 1332 | nr_packets = recv_mshot_msg(c, ocd, &bid, cqe->res); |
| 1333 | else |
| 1334 | nr_packets = recv_bids(c, ocd, &bid, cqe->res); |
| 1335 | |
| 1336 | if (cd->rcv_bucket) |
| 1337 | cd->rcv_bucket[nr_packets]++; |
no test coverage detected