| 384 | } // namespace |
| 385 | |
| 386 | void |
| 387 | UDPNetProcessorInternal::read_single_message_from_net(UDPNetHandler *nh, UDPConnection *xuc) |
| 388 | { |
| 389 | UnixUDPConnection *uc = static_cast<UnixUDPConnection *>(xuc); |
| 390 | |
| 391 | // receive packet and queue onto UDPConnection. |
| 392 | // don't call back connection at this time. |
| 393 | int64_t r; |
| 394 | int iters = 0; |
| 395 | unsigned max_niov = 32; |
| 396 | int64_t gso_size{0}; // in case is available. |
| 397 | struct msghdr msg; |
| 398 | Ptr<IOBufferBlock> chain, next_chain; |
| 399 | struct iovec tiovec[max_niov]; |
| 400 | int64_t size_index = BUFFER_SIZE_INDEX_2K; |
| 401 | int64_t buffer_size = BUFFER_SIZE_FOR_INDEX(size_index); |
| 402 | // The max length of receive buffer is 32 * buffer_size (2048) = 65536 bytes. |
| 403 | // Because the 'UDP Length' is type of uint16_t defined in RFC 768. |
| 404 | // And there is 8 octets in 'User Datagram Header' which means the max length of payload is no more than 65527 bytes. |
| 405 | do { |
| 406 | // create IOBufferBlock chain to receive data |
| 407 | unsigned int niov = build_iovec_block_chain(max_niov, size_index, chain, tiovec); |
| 408 | |
| 409 | // build struct msghdr |
| 410 | sockaddr_storage fromaddr; |
| 411 | sockaddr_storage toaddr; |
| 412 | msg.msg_name = &fromaddr; |
| 413 | msg.msg_namelen = sizeof(fromaddr); |
| 414 | msg.msg_iov = tiovec; |
| 415 | msg.msg_iovlen = niov; |
| 416 | msg.msg_flags = 0; |
| 417 | |
| 418 | static const size_t cmsg_size{CMSG_SPACE(sizeof(int)) |
| 419 | #ifdef IP_PKTINFO |
| 420 | + CMSG_SPACE(sizeof(struct in_pktinfo)) |
| 421 | #endif |
| 422 | #if defined(IPV6_PKTINFO) || defined(IPV6_RECVPKTINFO) |
| 423 | + CMSG_SPACE(sizeof(struct in6_pktinfo)) |
| 424 | #endif |
| 425 | #ifdef IP_RECVDSTADDR |
| 426 | + CMSG_SPACE(sizeof(struct in_addr)) |
| 427 | #endif |
| 428 | #ifdef UDP_GRO |
| 429 | + CMSG_SPACE(sizeof(uint16_t)) |
| 430 | #endif |
| 431 | }; |
| 432 | |
| 433 | char control[cmsg_size] = {0}; |
| 434 | msg.msg_control = control; |
| 435 | msg.msg_controllen = cmsg_size; |
| 436 | |
| 437 | // receive data by recvmsg |
| 438 | r = uc->sock.recvmsg(&msg, 0); |
| 439 | if (r <= 0) { |
| 440 | // error |
| 441 | break; |
| 442 | } |
| 443 |
nothing calls this directly
no test coverage detected