Improve sendto(2) failure diagnostics

In MDP client and server MDP overlay code
This commit is contained in:
Andrew Bettison 2013-11-22 13:12:29 +10:30
parent 3805650736
commit 45450386db
3 changed files with 32 additions and 18 deletions

View File

@ -133,11 +133,15 @@ int overlay_mdp_send(int mdp_sockfd, overlay_mdp_frame *mdp, int flags, int time
set_nonblock(mdp_sockfd);
ssize_t result = sendto(mdp_sockfd, mdp, (size_t)len, 0, (struct sockaddr *)&addr, addrlen);
set_block(mdp_sockfd);
if (result == -1) {
if ((size_t)result != (size_t)len) {
if (result == -1)
WHYF_perror("sendto(fd=%d,len=%zu,addr=%s)", mdp_sockfd, (size_t)len, alloca_sockaddr(&addr, addrlen));
else
WHYF("sendto() sent %zu bytes of MDP reply (%zu) to socket=%d", (size_t)result, (size_t)len, mdp_sockfd);
mdp->packetTypeAndFlags=MDP_ERROR;
mdp->error.error=1;
snprintf(mdp->error.message,128,"Error sending frame to MDP server.");
return WHYF_perror("sendto(fd=%d,len=%zu,addr=%s)", mdp_sockfd, (size_t)len, alloca_sockaddr(&addr, addrlen));
return -1;
} else {
if (!(flags&MDP_AWAITREPLY)) {
return 0;

View File

@ -982,11 +982,16 @@ int overlay_broadcast_ensemble(struct network_destination *destination, struct o
(struct sockaddr *)&destination->address, sizeof(destination->address));
ob_free(buffer);
if (sent == -1 || (size_t)sent != (size_t)len) {
WHYF_perror("sendto(fd=%d,len=%zu,addr=%s)",
interface->alarm.poll.fd,
(size_t)len,
alloca_sockaddr((struct sockaddr *)&destination->address, sizeof destination->address)
);
if (sent == -1)
WHYF_perror("sendto(fd=%d,len=%zu,addr=%s) on interface %s",
interface->alarm.poll.fd,
(size_t)len,
alloca_sockaddr((struct sockaddr *)&destination->address, sizeof destination->address),
interface->name
);
else
WHYF("sendto() sent %zu bytes of overlay frame (%zu) to interface %s (socket=%d)",
(size_t)sent, (size_t)len, interface->name, interface->alarm.poll.fd);
// close the interface if we had any error while sending broadcast packets,
// unicast packets should not bring the interface down
if (destination == interface->destination)

View File

@ -160,10 +160,12 @@ int overlay_mdp_reply(int sock,struct sockaddr_un *recvaddr, socklen_t recvaddrl
if (replylen == -1)
return WHY("Invalid MDP frame (could not compute length)");
ssize_t r = sendto(sock, (char *)mdpreply, (size_t)replylen, 0, (struct sockaddr *)recvaddr, recvaddrlen);
if (r == -1 || (size_t)r < (size_t)replylen) {
if (r == -1) {
WHYF_perror("sendto(fd=%d,len=%zu,addr=%s)", sock, (size_t)replylen, alloca_sockaddr((struct sockaddr *)recvaddr, recvaddrlen));
return WHYF("sendto() failed when sending MDP reply, sock=%d, r=%d", sock, r);
return WHYF("sendto() failed when sending MDP reply");
}
if ((size_t)r != (size_t)replylen)
return WHYF("sendto() sent %zu bytes of MDP reply (%zu) to socket=%d", (size_t)r, (size_t)replylen, sock);
return 0;
}
@ -444,19 +446,22 @@ static int overlay_saw_mdp_frame(struct overlay_frame *frame, overlay_mdp_frame
addr.sun_family = AF_UNIX;
bcopy(mdp_bindings[match].socket_name, addr.sun_path, mdp_bindings[match].name_len);
ssize_t len = overlay_mdp_relevant_bytes(mdp);
if (len < 0)
if (len == -1)
RETURN(WHY("unsupported MDP packet type"));
socklen_t addrlen = sizeof addr.sun_family + mdp_bindings[match].name_len;
ssize_t r = sendto(mdp_sock.poll.fd, mdp, (size_t)len, 0, (struct sockaddr*)&addr, addrlen);
if ((size_t)r == (size_t)len)
RETURN(0);
if (r == -1 && errno == ENOENT) {
/* far-end of socket has died, so drop binding */
INFOF("Closing dead MDP client '%s'",mdp_bindings[match].socket_name);
overlay_mdp_releasebindings(&addr,mdp_bindings[match].name_len);
if ((size_t)r != (size_t)len) {
if (r == -1) {
WHYF_perror("sendto(fd=%d,len=%zu,addr=%s)", mdp_sock.poll.fd, (size_t)len, alloca_sockaddr(&addr, addrlen));
if (errno == ENOENT) {
/* far-end of socket has died, so drop binding */
INFOF("Closing dead MDP client '%s'",mdp_bindings[match].socket_name);
overlay_mdp_releasebindings(&addr,mdp_bindings[match].name_len);
}
} else
WHYF("sendto() sent %zu bytes of MDP frame (%zu) to client, socket=%d", (size_t)r, (size_t)len, mdp_sock.poll.fd);
RETURN(WHY("Failed to pass received MDP frame to client"));
}
WHYF_perror("sendto(fd=%d,len=%zu,addr=%s)", mdp_sock.poll.fd, (size_t)len, alloca_sockaddr(&addr, addrlen));
RETURN(WHY("Failed to pass received MDP frame to client"));
} else {
/* No socket is bound, ignore the packet ... except for magic sockets */
RETURN(overlay_mdp_try_interal_services(frame, mdp));