mirror of
https://github.com/samba-team/samba.git
synced 2025-11-27 08:23:49 +03:00
r3304: changed the API to lib/socket/ a little.
The main change is to make socket_recv() take a pre-allocated buffer, rather than allocating one itself. This allows non-blocking users of this API to avoid a memcpy(). As a result our messaging code is now about 10% faster, and the ncacn_ip_tcp and ncalrpc code is also faster. The second change was to remove the unused mem_ctx argument from socket_send(). Having it there implied that memory could be allocated, which meant the caller had to worry about freeing that memory (if for example it is sending in a tight loop using the same memory context). Removing that unused argument keeps life simpler for users.
This commit is contained in:
committed by
Gerald (Jerry) Carter
parent
ee535b6801
commit
a16e4756cd
@@ -133,8 +133,8 @@ NTSTATUS socket_accept(struct socket_context *sock, struct socket_context **new_
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS socket_recv(struct socket_context *sock, TALLOC_CTX *mem_ctx,
|
||||
DATA_BLOB *blob, size_t wantlen, uint32_t flags)
|
||||
NTSTATUS socket_recv(struct socket_context *sock, void *buf,
|
||||
size_t wantlen, size_t *nread, uint32_t flags)
|
||||
{
|
||||
if (sock->type != SOCKET_TYPE_STREAM) {
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
@@ -149,11 +149,11 @@ NTSTATUS socket_recv(struct socket_context *sock, TALLOC_CTX *mem_ctx,
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
return sock->ops->recv(sock, mem_ctx, blob, wantlen, flags);
|
||||
return sock->ops->recv(sock, buf, wantlen, nread, flags);
|
||||
}
|
||||
|
||||
NTSTATUS socket_send(struct socket_context *sock, TALLOC_CTX *mem_ctx,
|
||||
const DATA_BLOB *blob, size_t *sendlen, uint32_t flags)
|
||||
NTSTATUS socket_send(struct socket_context *sock,
|
||||
const DATA_BLOB *blob, size_t *sendlen, uint32_t flags)
|
||||
{
|
||||
if (sock->type != SOCKET_TYPE_STREAM) {
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
@@ -168,7 +168,7 @@ NTSTATUS socket_send(struct socket_context *sock, TALLOC_CTX *mem_ctx,
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
return sock->ops->send(sock, mem_ctx, blob, sendlen, flags);
|
||||
return sock->ops->send(sock, blob, sendlen, flags);
|
||||
}
|
||||
|
||||
NTSTATUS socket_set_option(struct socket_context *sock, const char *option, const char *val)
|
||||
|
||||
@@ -46,10 +46,10 @@ struct socket_ops {
|
||||
struct socket_context **new_sock, uint32_t flags);
|
||||
|
||||
/* general ops */
|
||||
NTSTATUS (*recv)(struct socket_context *sock, TALLOC_CTX *mem_ctx,
|
||||
DATA_BLOB *blob, size_t wantlen, uint32_t flags);
|
||||
NTSTATUS (*send)(struct socket_context *sock, TALLOC_CTX *mem_ctx,
|
||||
const DATA_BLOB *blob, size_t *sendlen, uint32_t flags);
|
||||
NTSTATUS (*recv)(struct socket_context *sock, void *buf,
|
||||
size_t wantlen, size_t *nread, uint32_t flags);
|
||||
NTSTATUS (*send)(struct socket_context *sock,
|
||||
const DATA_BLOB *blob, size_t *sendlen, uint32_t flags);
|
||||
|
||||
void (*close)(struct socket_context *sock);
|
||||
|
||||
|
||||
@@ -166,18 +166,12 @@ static NTSTATUS ipv4_tcp_accept(struct socket_context *sock, struct socket_conte
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static NTSTATUS ipv4_tcp_recv(struct socket_context *sock, TALLOC_CTX *mem_ctx,
|
||||
DATA_BLOB *blob, size_t wantlen, uint32_t flags)
|
||||
static NTSTATUS ipv4_tcp_recv(struct socket_context *sock, void *buf,
|
||||
size_t wantlen, size_t *nread, uint32_t flags)
|
||||
{
|
||||
ssize_t gotlen;
|
||||
void *buf;
|
||||
int flgs = 0;
|
||||
|
||||
buf = talloc(mem_ctx, wantlen);
|
||||
if (!buf) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
/* TODO: we need to map all flags here */
|
||||
if (flags & SOCKET_FLAG_PEEK) {
|
||||
flgs |= MSG_PEEK;
|
||||
@@ -187,42 +181,21 @@ static NTSTATUS ipv4_tcp_recv(struct socket_context *sock, TALLOC_CTX *mem_ctx,
|
||||
flgs |= MSG_WAITALL;
|
||||
}
|
||||
|
||||
*nread = 0;
|
||||
|
||||
gotlen = recv(sock->fd, buf, wantlen, flgs);
|
||||
if (gotlen == 0) {
|
||||
talloc_free(buf);
|
||||
return NT_STATUS_END_OF_FILE;
|
||||
} else if (gotlen == -1) {
|
||||
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
|
||||
switch (errno) {
|
||||
case EBADF:
|
||||
case ENOTCONN:
|
||||
case ENOTSOCK:
|
||||
case EFAULT:
|
||||
case EINVAL:
|
||||
status = NT_STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
case EAGAIN:
|
||||
case EINTR:
|
||||
status = STATUS_MORE_ENTRIES;
|
||||
break;
|
||||
case ECONNREFUSED:
|
||||
status = NT_STATUS_CONNECTION_REFUSED;
|
||||
break;
|
||||
}
|
||||
talloc_free(buf);
|
||||
return status;
|
||||
return map_nt_error_from_unix(errno);
|
||||
}
|
||||
|
||||
blob->length = gotlen;
|
||||
blob->data = talloc_realloc(mem_ctx, buf, gotlen);
|
||||
if (!blob->data) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
*nread = gotlen;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static NTSTATUS ipv4_tcp_send(struct socket_context *sock, TALLOC_CTX *mem_ctx,
|
||||
static NTSTATUS ipv4_tcp_send(struct socket_context *sock,
|
||||
const DATA_BLOB *blob, size_t *sendlen, uint32_t flags)
|
||||
{
|
||||
ssize_t len;
|
||||
|
||||
@@ -155,18 +155,12 @@ static NTSTATUS unixdom_accept(struct socket_context *sock,
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static NTSTATUS unixdom_recv(struct socket_context *sock, TALLOC_CTX *mem_ctx,
|
||||
DATA_BLOB *blob, size_t wantlen, uint32_t flags)
|
||||
static NTSTATUS unixdom_recv(struct socket_context *sock, void *buf,
|
||||
size_t wantlen, size_t *nread, uint32_t flags)
|
||||
{
|
||||
ssize_t gotlen;
|
||||
void *buf;
|
||||
int flgs = 0;
|
||||
|
||||
buf = talloc(mem_ctx, wantlen);
|
||||
if (!buf) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
/* TODO: we need to map all flags here */
|
||||
if (flags & SOCKET_FLAG_PEEK) {
|
||||
flgs |= MSG_PEEK;
|
||||
@@ -176,26 +170,21 @@ static NTSTATUS unixdom_recv(struct socket_context *sock, TALLOC_CTX *mem_ctx,
|
||||
flgs |= MSG_WAITALL;
|
||||
}
|
||||
|
||||
*nread = 0;
|
||||
|
||||
gotlen = recv(sock->fd, buf, wantlen, flgs);
|
||||
if (gotlen == 0) {
|
||||
talloc_free(buf);
|
||||
return NT_STATUS_END_OF_FILE;
|
||||
} else if (gotlen == -1) {
|
||||
NTSTATUS status = unixdom_error(errno);
|
||||
talloc_free(buf);
|
||||
return status;
|
||||
return unixdom_error(errno);
|
||||
}
|
||||
|
||||
blob->length = gotlen;
|
||||
blob->data = talloc_realloc(mem_ctx, buf, gotlen);
|
||||
if (!blob->data) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
*nread = gotlen;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static NTSTATUS unixdom_send(struct socket_context *sock, TALLOC_CTX *mem_ctx,
|
||||
static NTSTATUS unixdom_send(struct socket_context *sock,
|
||||
const DATA_BLOB *blob, size_t *sendlen, uint32_t flags)
|
||||
{
|
||||
ssize_t len;
|
||||
|
||||
Reference in New Issue
Block a user