Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
366 views
in Technique[技术] by (71.8m points)

c - Is flag MSG_ERRQUEUE make socket having a non-blocking behavior on linux?

I have written a program in C for sending icmp echo request and then receiving icmp echo reply. I have tried to add the flag MSG_ERRQUEUE on my recvmsg() function call but it produce a behavior as if the socket I use is non blocking.

I have verified and I do not set the socket as non-blocking anywhere in the program and I do not set a timeout on sending and/or receiving (SO_RCVTIMEO/SO_SNDTIMEO).

Here is my code:

getaddrinfo

void get_addr()
{
    struct addrinfo hints;
    int ret;

    bzero(&hints, sizeof(hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_RAW;
    hints.ai_protocol = IPPROTO_ICMP;

    if ((ret = getaddrinfo(env.args.hostname, NULL, &hints, &(env.addr))) != 0)
        error_exit("getaddrinfo");
}

Socket setup

void set_socket()
{
    int on;
    int ttl;

    if ((env.sockfd = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
        error_exit("socket creation");

    env.ttl = 64;
    if ((setsockopt(env.sockfd, 0, IP_TTL, &(env), sizeof(env))) < 0)
        error_exit("socket TTL setup");

    on = 1;
    if ((setsockopt(env.sockfd, 0, IP_RECVERR, &(on), sizeof(on))) < 0)
        error_exit("socket RECVERR setup");

    on = 1;
    if ((setsockopt(env.sockfd, 0, IP_RECVTTL, &(on), sizeof(on))) < 0)
        error_exit("socket RECVTTL setup");
}

sendto() / recvmsg()

    int main()
    {
         int retsend;
         int retrecv;

         while (1)
         {
             if ((retsend = sendto(env.sockfd, &(env.icmp_req), sizeof(env.icmp_req), 0, (env.addr->ai_addr), env.addr->ai_addrlen)) < 0)
                 perror("Error sendto: ");
             if ((recvmsg(env.sockfd, &(env.r_data.msg), MSG_WAITALL | MSG_ERRQUEUE)) < 0)
                 perror("Error recvmsg: ");
             retrieve_info();
         }
    }

In the function retrieve_info(), I use struct sock_extended_err * to stock information about error if cmsg->cmsg_type == IP_RECVERR

With those two flags in recvmsg() call I do have a EAGAIN error on each call!

Thank you

question from:https://stackoverflow.com/questions/65890668/is-flag-msg-errqueue-make-socket-having-a-non-blocking-behavior-on-linux

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...