dimanche 28 juin 2015

Getting the destination address of UDP packet

I have been using the following example posted in this same site. This is my version of it. (Please excuse my lack of experience with C socket programming:)

In constructor:

int sock = udpsocket_.native();
// sock is bound AF_INET socket, usually SOCK_DGRAM
// include struct in_pktinfo in the message "ancilliary" control data
fd_set fdset;
FD_ZERO(&fdset);
FD_SET(sock, &fdset);
int opt = 1;
setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &opt, sizeof(opt));

Where "udpsocket_" is actually a boost asio udp socket. This is very convenient since on one hand I can have a function which gets the destination IP from the incoming UDP message without the need for using a raw socket:

int sock = udpsocket_.native();
char cmbuf[0x100];
struct sockaddr_in peeraddr;
struct msghdr mh;
mh.msg_name = &peeraddr;
mh.msg_namelen = sizeof(peeraddr);
mh.msg_control = cmbuf;
mh.msg_controllen = sizeof(cmbuf);
int received = recvmsg(sock, &mh, 0);
for ( // iterate through all the control headers
        struct cmsghdr *cmsg = CMSG_FIRSTHDR(&mh);
        cmsg != NULL;
        cmsg = CMSG_NXTHDR(&mh, cmsg))
{
    if (cmsg->cmsg_level != IPPROTO_IP ||
            cmsg->cmsg_type != IP_PKTINFO)
    {
        continue;
    }
    struct in_pktinfo *pi = (struct in_pktinfo*) CMSG_DATA(cmsg);
    char* destAddr = (char*) calloc(4, sizeof(char));
    destAddr = inet_ntoa(pi->ipi_spec_dst);

    stored_UDP_dest_ip_ = ip::address::from_string(destAddr);
}

Now here come the problems:

  • Could I call this "get_destination_IP" asynchronously, in a non-blocking way in the same way as I call "async_receive_from" ?

    • "recvmsg" stores the right destination IP info, but returns 0. In theory according to the man page, the "size_t numbytes" is returned there. Can I still read the datagram with "recvmsg"?
  • Is FD_ZERO necessary here?

  • Is FD_ZERO necessary at every call of the function?

Thank you beforehand for your help

Aucun commentaire:

Enregistrer un commentaire