summaryrefslogtreecommitdiff
path: root/source4/lib/socket/socket_unix.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/socket/socket_unix.c')
-rw-r--r--source4/lib/socket/socket_unix.c35
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);
}