I've created connected UDP socket with this function
/* Creates connected udp socket */
int
udp_connect( const char *host, const char *serv)
{
int sockfd, n;
struct addrinfo hints, *res, *ressave;
bzero(&hints, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
if ( ( n = getaddrinfo( host, serv, &hints, &res)) != 0)
err_quit( "udp_connect error for %s, %s: %s",
host, serv, gai_strerror(n));
ressave = res;
do {
sockfd = socket( res->ai_family, res->ai_socktype, res->ai_protocol);
if ( sockfd < 0)
continue; /* ignore this one */
/* The call to connect with a UDP socket does not send anything
* to the peer. If something is wrong ( the peer is unreachable
* or there is no server at the specified port), the caller
* does not discover that until it sends
* a datagram to the peer */
if ( connect( sockfd, res->ai_addr, res->ai_addrlen) == 0)
break; /* success */
Close( sockfd); /* ignore this one */
} while ( ( res = res->ai_next) != NULL);
if ( res == NULL) /* errno set from final connect() */
err_sys( "udp_connect error for %s, %s", host, serv);
freeaddrinfo( ressave);
return( sockfd);
}
I would like to do a test how it behaves when peer is actually unreachable. Since call to connect()
cannot result in this information we need to actually send something. I will describe what do I do and what do I get in the following snippet:
printf( "sending to %s\n", Sock_ntop_host( sa, salen));
// prints: sending to 127.0.0.1
Sendto( sockfd, "", 1, 0, sa, salen); /* send 1-byte datagram */
// prints: nbytes:1
// it is sent, I check via tcpdump or with Wireshark that datagram
// has been sent and ICMP "destination unreachable" comes back from host
printf( "sent, errno:%d,%s\n", errno, strerror(errno));
// prints: sent, errno:0,Success
n = Recvfrom( sockfd, recvline, MAXLINE, 0, NULL, NULL);
// never gets here
printf( "received n=%d\n", n);
The Sendto
function is a wrapper over sendto
that just prints error and exits:
void
Sendto(int fd, const void *ptr, size_t nbytes, int flags,
const struct sockaddr *sa, socklen_t salen)
{
if ( sendto(fd, ptr, nbytes, flags, sa, salen) == -1)
exit(-1);//err_sys("sendto error");
printf( "nbytes:%d\n",nbytes); // prints: nbytes:1
}
ssize_t
Recvfrom(int fd, void *ptr, size_t nbytes, int flags,
struct sockaddr *sa, socklen_t *salenptr)
{
ssize_t n;
if ( (n = recvfrom(fd, ptr, nbytes, flags, sa, salenptr)) < 0)
err_sys("recvfrom error");
return(n);
}
So the call to Recvfrom
blocks forever while Sendto
returnes errno with code Success
. How then should I code this to get notification about ICMP response? is this possible without timeout on socket?
SendTo
() needs to check the return code ofsendmsg()
or whatever system call you are using, and if -1 checkerrno
forEUNREACH.
– user207421errno
is Success". Please post the actual code. – user207421errno
is never zero, except possibly when you first start executing your program: maybe not even then. It is invalid to even test it unless an immediately preceding system call has returned -1. That's why I keep asking you to post the actual code. I'm not interested in your description of what you think it does. It doesn't work, ergo your preconceptions about it aren't correct. Post the code. – user207421send(),
sendto(),
sendmsg()
,listen(),
bind(),
recv(),
whatever. I suggest you try it instead of arguing. I certainly can't help you if you're going to ignore my advice. – user207421