mirror of
https://github.com/samba-team/samba.git
synced 2025-07-30 19:42:05 +03:00
Handle EMSGSIZE on UNIX domain sockets.
On some systems (eg, FreeBSD) the default SO_SNDBUF for UNIX domain sockets is to small, and EMSGSIZE is returned. Other systems provide a larger default send buffer, but there is still no guarantee that the buffer will be sized appropriately. This patch modifies the sendto() path to attempt to resize the SO_SNDBUF dynamically upon an EMSGSIZE failure, and then retry the send. This fixes local DCE/RPC errors on FreeBSD, eg: https://lists.samba.org/archive/samba-technical/2013-January/089881.html Signed-Off-By: Landon Fuller <landonf@bikemonkey.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org> Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> Autobuild-Date(master): Sat Mar 2 23:34:03 CET 2013 on sn-devel-104
This commit is contained in:
committed by
Andrew Bartlett
parent
606f5d6cc6
commit
c692bb02b0
@ -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);
|
||||
|
||||
len = sendto(sock->fd, blob->data, blob->length, 0,
|
||||
(struct sockaddr *)&srv_addr, sizeof(srv_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);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user