ctdb-common: Fix error handling
authorMartin Schwenke <martin@meltin.net>
Mon, 24 Jun 2019 06:36:47 +0000 (16:36 +1000)
committerAmitay Isaacs <amitay@samba.org>
Fri, 5 Jul 2019 05:03:24 +0000 (05:03 +0000)
According to the documentation, sendto() should either send the packet
as given or return with an error.  However, given that it can return
the number of bytes sent, treat the theoretical error of a short
packet send separately, since errno would not be set in this case.

Similarly, treat a short packet recv() separately from an error where
errno is set.

Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
ctdb/common/system_socket.c

index c6800431112b6850dc228995680e310e11ec04c1..86cbdaab6ad2154da1fe49bcba635b01687ee4b7 100644 (file)
@@ -681,10 +681,14 @@ int ctdb_sys_send_tcp(const ctdb_sock_addr *dest,
                             sizeof(dest->ip));
                saved_errno = errno;
                close(s);
-               if (ret != len) {
+               if (ret == -1) {
                        D_ERR("Failed sendto (%s)\n", strerror(saved_errno));
                        return -1;
                }
+               if ((size_t)ret != len) {
+                       DBG_ERR("Failed sendto - didn't send full packet\n");
+                       return -1;
+               }
                break;
 
        case AF_INET6:
@@ -722,11 +726,14 @@ int ctdb_sys_send_tcp(const ctdb_sock_addr *dest,
                             sizeof(tmpdest));
                saved_errno = errno;
                close(s);
-
-               if (ret != len) {
+               if (ret == -1) {
                        D_ERR("Failed sendto (%s)\n", strerror(saved_errno));
                        return -1;
                }
+               if ((size_t)ret != len) {
+                       DBG_ERR("Failed sendto - didn't send full packet\n");
+                       return -1;
+               }
                break;
 
        default:
@@ -914,7 +921,10 @@ int ctdb_sys_read_tcp_packet(int s, void *private_data,
        int ret;
 
        nread = recv(s, pkt, sizeof(pkt), MSG_TRUNC);
-       if (nread < sizeof(*eth)) {
+       if (nread == -1) {
+               return errno;
+       }
+       if ((size_t)nread < sizeof(*eth)) {
                return EMSGSIZE;
        }