summaryrefslogtreecommitdiff
path: root/source4/lib
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2004-10-28 04:00:43 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:04:52 -0500
commitc6888da1487ab301292c3d4d05d0464833f3ce57 (patch)
tree35660282f621edb23885c40bfc4634489def3d6d /source4/lib
parent9d1e2b29ebf14beae4fc63b2cb85f4e2d1798021 (diff)
downloadsamba-c6888da1487ab301292c3d4d05d0464833f3ce57.tar.gz
samba-c6888da1487ab301292c3d4d05d0464833f3ce57.tar.bz2
samba-c6888da1487ab301292c3d4d05d0464833f3ce57.zip
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 used to be commit a16e4756cd68ca8aab4ffc59d4d9db0b6e44dbd1)
Diffstat (limited to 'source4/lib')
-rw-r--r--source4/lib/messaging/messaging.c36
-rw-r--r--source4/lib/socket/socket.c12
-rw-r--r--source4/lib/socket/socket.h8
-rw-r--r--source4/lib/socket/socket_ipv4.c41
-rw-r--r--source4/lib/socket/socket_unix.c25
5 files changed, 41 insertions, 81 deletions
diff --git a/source4/lib/messaging/messaging.c b/source4/lib/messaging/messaging.c
index afd18b4f2f..09d0c43934 100644
--- a/source4/lib/messaging/messaging.c
+++ b/source4/lib/messaging/messaging.c
@@ -123,22 +123,21 @@ static void messaging_recv_handler(struct event_context *ev, struct fd_event *fd
if (rec->ndone < sizeof(rec->header)) {
/* receive the header */
- DATA_BLOB blob;
- blob.length = 0;
- status = socket_recv(rec->sock, rec,
- &blob, sizeof(rec->header) - rec->ndone, 0);
+ size_t nread;
+
+ status = socket_recv(rec->sock,
+ rec->ndone + (char *)&rec->header,
+ sizeof(rec->header) - rec->ndone, &nread, 0);
if (NT_STATUS_IS_ERR(status)) {
talloc_free(rec);
return;
}
- if (blob.length == 0) {
+ if (nread == 0) {
return;
}
- memcpy(rec->ndone + (char *)&rec->header, blob.data, blob.length);
- rec->ndone += blob.length;
- data_blob_free(&blob);
+ rec->ndone += nread;
if (rec->ndone == sizeof(rec->header)) {
if (rec->header.version != MESSAGING_VERSION) {
@@ -158,23 +157,22 @@ static void messaging_recv_handler(struct event_context *ev, struct fd_event *fd
if (rec->ndone >= sizeof(rec->header) &&
rec->ndone < sizeof(rec->header) + rec->header.length) {
/* receive the body, if any */
- DATA_BLOB blob;
- blob.length = 0;
- status = socket_recv(rec->sock, rec,
- &blob, sizeof(rec->header) + rec->header.length - rec->ndone, 0);
+ size_t nread;
+
+ status = socket_recv(rec->sock,
+ rec->data.data + (rec->ndone - sizeof(rec->header)),
+ sizeof(rec->header) + rec->header.length - rec->ndone,
+ &nread, 0);
if (NT_STATUS_IS_ERR(status)) {
talloc_free(rec);
return;
}
- if (blob.length == 0) {
+ if (nread == 0) {
return;
}
- memcpy(rec->data.data + (rec->ndone - sizeof(rec->header)),
- blob.data, blob.length);
-
- rec->ndone += blob.length;
+ rec->ndone += nread;
}
if (rec->ndone == sizeof(rec->header) + rec->header.length) {
@@ -283,7 +281,7 @@ static void messaging_send_handler(struct event_context *ev, struct fd_event *fd
blob.data = rec->ndone + (char *)&rec->header;
blob.length = sizeof(rec->header) - rec->ndone;
- status = socket_send(rec->sock, rec, &blob, &nsent, 0);
+ status = socket_send(rec->sock, &blob, &nsent, 0);
if (NT_STATUS_IS_ERR(status)) {
talloc_free(rec);
return;
@@ -305,7 +303,7 @@ static void messaging_send_handler(struct event_context *ev, struct fd_event *fd
blob.data = rec->data.data + (rec->ndone - sizeof(rec->header));
blob.length = rec->header.length - (rec->ndone - sizeof(rec->header));
- status = socket_send(rec->sock, rec, &blob, &nsent, 0);
+ status = socket_send(rec->sock, &blob, &nsent, 0);
if (NT_STATUS_IS_ERR(status)) {
talloc_free(rec);
return;
diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c
index f5ee84a7cc..94d8b5bada 100644
--- a/source4/lib/socket/socket.c
+++ b/source4/lib/socket/socket.c
@@ -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)
diff --git a/source4/lib/socket/socket.h b/source4/lib/socket/socket.h
index a089a1b78a..6562bb376b 100644
--- a/source4/lib/socket/socket.h
+++ b/source4/lib/socket/socket.h
@@ -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);
diff --git a/source4/lib/socket/socket_ipv4.c b/source4/lib/socket/socket_ipv4.c
index f280f804ef..4de0d8cebe 100644
--- a/source4/lib/socket/socket_ipv4.c
+++ b/source4/lib/socket/socket_ipv4.c
@@ -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;
diff --git a/source4/lib/socket/socket_unix.c b/source4/lib/socket/socket_unix.c
index eda1597df7..3a3ce5fe8a 100644
--- a/source4/lib/socket/socket_unix.c
+++ b/source4/lib/socket/socket_unix.c
@@ -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;