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 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…