diff options
Diffstat (limited to 'source4/lib/socket')
-rw-r--r-- | source4/lib/socket/socket_unix.c | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/source4/lib/socket/socket_unix.c b/source4/lib/socket/socket_unix.c index 4755e796a4..049e5707c8 100644 --- a/source4/lib/socket/socket_unix.c +++ b/source4/lib/socket/socket_unix.c @@ -263,26 +263,43 @@ static NTSTATUS unixdom_sendto(struct socket_context *sock, const DATA_BLOB *blob, size_t *sendlen, const struct socket_address *dest) { + struct sockaddr_un srv_addr; + const struct sockaddr *sa; + socklen_t sa_len; ssize_t len; + *sendlen = 0; - + if (dest->sockaddr) { - len = sendto(sock->fd, blob->data, blob->length, 0, - dest->sockaddr, dest->sockaddrlen); + sa = dest->sockaddr; + sa_len = dest->sockaddrlen; } else { - struct sockaddr_un srv_addr; - if (strlen(dest->addr)+1 > sizeof(srv_addr.sun_path)) { return NT_STATUS_OBJECT_PATH_INVALID; } - + ZERO_STRUCT(srv_addr); srv_addr.sun_family = AF_UNIX; - snprintf(srv_addr.sun_path, sizeof(srv_addr.sun_path), "%s", dest->addr); + snprintf(srv_addr.sun_path, sizeof(srv_addr.sun_path), "%s", + dest->addr); + sa = (struct sockaddr *) &srv_addr; + sa_len = sizeof(srv_addr); + } + + len = sendto(sock->fd, blob->data, blob->length, 0, sa, sa_len); - len = sendto(sock->fd, blob->data, blob->length, 0, - (struct sockaddr *)&srv_addr, sizeof(srv_addr)); + /* retry once */ + if (len == -1 && errno == EMSGSIZE) { + /* round up in 1K increments */ + int bufsize = ((blob->length + 1023) & (~1023)); + if (setsockopt(sock->fd, SOL_SOCKET, SO_SNDBUF, &bufsize, + sizeof(bufsize)) == -1) + { + return map_nt_error_from_unix_common(errno); + } + len = sendto(sock->fd, blob->data, blob->length, 0, sa, sa_len); } + if (len == -1) { return map_nt_error_from_unix_common(errno); } |