Skip to content
Snippets Groups Projects
Select Git revision
  • a34275d8be7826aaa95a3f9785f454b1b2bc8026
  • main default protected
2 results

recvmmsg.c

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    recvmmsg.c 1.23 KiB
    #define _GNU_SOURCE
    #include <sys/socket.h>
    #include <stdio.h>
    
    // A wrapper around recvmmsg() for use in Python
    int recvmmsg_python(int fd, int num_packets, int max_packet_size, char *packets, int *packet_lengths)
    {
      int num_read;
    
      // register our receive buffer(s)
      struct iovec iov[num_packets];
      for (unsigned i = 0; i < num_packets; i++) {
        iov[i].iov_base = packets + i * max_packet_size;
        iov[i].iov_len  = max_packet_size;
      }
    
      struct mmsghdr msgs[num_packets];
      for (unsigned i = 0; i < num_packets; ++i) {
        msgs[i].msg_hdr.msg_name    = NULL; // we don't need to know who sent the data
        msgs[i].msg_hdr.msg_iov     = &iov[i];
        msgs[i].msg_hdr.msg_iovlen  = 1;
        msgs[i].msg_hdr.msg_control = NULL; // we're not interested in OoB data
      }
    
      // Note: the timeout parameter doesn't work as expected: only between datagrams
      // is the timeout checked, not when waiting for one (i.e. num_packets=1 or MSG_WAITFORONE).
      num_read = recvmmsg(fd, &msgs[0], num_packets, 0, NULL);
      if (num_read < 0) {
        // just print any error we encounter
        perror("recvmmsg");
      }
    
      for (int i = 0; i < num_read; ++i) {
        packet_lengths[i] = msgs[i].msg_len; // num bytes received is stored in msg_len by recvmmsg()
      }
    
      return num_read;
    }