mirror of
https://github.com/samba-team/samba.git
synced 2025-12-03 04:23:50 +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
@@ -155,10 +155,17 @@ static BOOL read_into_buf(struct socket_context *sock, struct rw_buffer *buf)
|
|||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
DATA_BLOB tmp_blob;
|
DATA_BLOB tmp_blob;
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
size_t nread;
|
||||||
|
|
||||||
status = socket_recv(sock, sock, &tmp_blob, 1024, 0);
|
tmp_blob = data_blob_talloc(sock, NULL, 1024);
|
||||||
|
if (tmp_blob.data == NULL) {
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = socket_recv(sock, tmp_blob.data, tmp_blob.length, &nread, 0);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
DEBUG(10,("socket_recv: %s\n",nt_errstr(status)));
|
DEBUG(10,("socket_recv: %s\n",nt_errstr(status)));
|
||||||
|
talloc_free(tmp_blob.data);
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,6 +186,7 @@ static BOOL ldapsrv_read_buf(struct ldapsrv_connection *conn)
|
|||||||
int buf_length, sasl_length;
|
int buf_length, sasl_length;
|
||||||
struct socket_context *sock = conn->connection->socket;
|
struct socket_context *sock = conn->connection->socket;
|
||||||
TALLOC_CTX *mem_ctx;
|
TALLOC_CTX *mem_ctx;
|
||||||
|
size_t nread;
|
||||||
|
|
||||||
if (!conn->gensec || !conn->session_info ||
|
if (!conn->gensec || !conn->session_info ||
|
||||||
!(gensec_have_feature(conn->gensec, GENSEC_WANT_SIGN) &&
|
!(gensec_have_feature(conn->gensec, GENSEC_WANT_SIGN) &&
|
||||||
@@ -192,12 +200,19 @@ static BOOL ldapsrv_read_buf(struct ldapsrv_connection *conn)
|
|||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = socket_recv(sock, mem_ctx, &tmp_blob, 1024, 0);
|
tmp_blob = data_blob_talloc(mem_ctx, NULL, 1024);
|
||||||
|
if (tmp_blob.data == NULL) {
|
||||||
|
talloc_free(mem_ctx);
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = socket_recv(sock, tmp_blob.data, tmp_blob.length, &nread, 0);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
DEBUG(10,("socket_recv: %s\n",nt_errstr(status)));
|
DEBUG(10,("socket_recv: %s\n",nt_errstr(status)));
|
||||||
talloc_free(mem_ctx);
|
talloc_free(mem_ctx);
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
tmp_blob.length = nread;
|
||||||
|
|
||||||
ret = ldapsrv_append_to_buf(&conn->sasl_in_buffer, tmp_blob.data, tmp_blob.length);
|
ret = ldapsrv_append_to_buf(&conn->sasl_in_buffer, tmp_blob.data, tmp_blob.length);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
@@ -276,7 +291,7 @@ static BOOL write_from_buf(struct socket_context *sock, struct rw_buffer *buf)
|
|||||||
tmp_blob.data = buf->data;
|
tmp_blob.data = buf->data;
|
||||||
tmp_blob.length = buf->length;
|
tmp_blob.length = buf->length;
|
||||||
|
|
||||||
status = socket_send(sock, sock, &tmp_blob, &sendlen, 0);
|
status = socket_send(sock, &tmp_blob, &sendlen, 0);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
DEBUG(10,("socket_send() %s\n",nt_errstr(status)));
|
DEBUG(10,("socket_send() %s\n",nt_errstr(status)));
|
||||||
return False;
|
return False;
|
||||||
@@ -360,7 +375,7 @@ nodata:
|
|||||||
tmp_blob.data = conn->sasl_out_buffer.data;
|
tmp_blob.data = conn->sasl_out_buffer.data;
|
||||||
tmp_blob.length = conn->sasl_out_buffer.length;
|
tmp_blob.length = conn->sasl_out_buffer.length;
|
||||||
|
|
||||||
status = socket_send(sock, mem_ctx, &tmp_blob, &sendlen, 0);
|
status = socket_send(sock, &tmp_blob, &sendlen, 0);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
DEBUG(10,("socket_send() %s\n",nt_errstr(status)));
|
DEBUG(10,("socket_send() %s\n",nt_errstr(status)));
|
||||||
talloc_free(mem_ctx);
|
talloc_free(mem_ctx);
|
||||||
|
|||||||
@@ -123,22 +123,21 @@ static void messaging_recv_handler(struct event_context *ev, struct fd_event *fd
|
|||||||
|
|
||||||
if (rec->ndone < sizeof(rec->header)) {
|
if (rec->ndone < sizeof(rec->header)) {
|
||||||
/* receive the header */
|
/* receive the header */
|
||||||
DATA_BLOB blob;
|
size_t nread;
|
||||||
blob.length = 0;
|
|
||||||
status = socket_recv(rec->sock, rec,
|
status = socket_recv(rec->sock,
|
||||||
&blob, sizeof(rec->header) - rec->ndone, 0);
|
rec->ndone + (char *)&rec->header,
|
||||||
|
sizeof(rec->header) - rec->ndone, &nread, 0);
|
||||||
if (NT_STATUS_IS_ERR(status)) {
|
if (NT_STATUS_IS_ERR(status)) {
|
||||||
talloc_free(rec);
|
talloc_free(rec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blob.length == 0) {
|
if (nread == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(rec->ndone + (char *)&rec->header, blob.data, blob.length);
|
rec->ndone += nread;
|
||||||
rec->ndone += blob.length;
|
|
||||||
data_blob_free(&blob);
|
|
||||||
|
|
||||||
if (rec->ndone == sizeof(rec->header)) {
|
if (rec->ndone == sizeof(rec->header)) {
|
||||||
if (rec->header.version != MESSAGING_VERSION) {
|
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) &&
|
if (rec->ndone >= sizeof(rec->header) &&
|
||||||
rec->ndone < sizeof(rec->header) + rec->header.length) {
|
rec->ndone < sizeof(rec->header) + rec->header.length) {
|
||||||
/* receive the body, if any */
|
/* receive the body, if any */
|
||||||
DATA_BLOB blob;
|
size_t nread;
|
||||||
blob.length = 0;
|
|
||||||
status = socket_recv(rec->sock, rec,
|
status = socket_recv(rec->sock,
|
||||||
&blob, sizeof(rec->header) + rec->header.length - rec->ndone, 0);
|
rec->data.data + (rec->ndone - sizeof(rec->header)),
|
||||||
|
sizeof(rec->header) + rec->header.length - rec->ndone,
|
||||||
|
&nread, 0);
|
||||||
if (NT_STATUS_IS_ERR(status)) {
|
if (NT_STATUS_IS_ERR(status)) {
|
||||||
talloc_free(rec);
|
talloc_free(rec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blob.length == 0) {
|
if (nread == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(rec->data.data + (rec->ndone - sizeof(rec->header)),
|
rec->ndone += nread;
|
||||||
blob.data, blob.length);
|
|
||||||
|
|
||||||
rec->ndone += blob.length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rec->ndone == sizeof(rec->header) + rec->header.length) {
|
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.data = rec->ndone + (char *)&rec->header;
|
||||||
blob.length = sizeof(rec->header) - rec->ndone;
|
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)) {
|
if (NT_STATUS_IS_ERR(status)) {
|
||||||
talloc_free(rec);
|
talloc_free(rec);
|
||||||
return;
|
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.data = rec->data.data + (rec->ndone - sizeof(rec->header));
|
||||||
blob.length = rec->header.length - (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)) {
|
if (NT_STATUS_IS_ERR(status)) {
|
||||||
talloc_free(rec);
|
talloc_free(rec);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -133,8 +133,8 @@ NTSTATUS socket_accept(struct socket_context *sock, struct socket_context **new_
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS socket_recv(struct socket_context *sock, TALLOC_CTX *mem_ctx,
|
NTSTATUS socket_recv(struct socket_context *sock, void *buf,
|
||||||
DATA_BLOB *blob, size_t wantlen, uint32_t flags)
|
size_t wantlen, size_t *nread, uint32_t flags)
|
||||||
{
|
{
|
||||||
if (sock->type != SOCKET_TYPE_STREAM) {
|
if (sock->type != SOCKET_TYPE_STREAM) {
|
||||||
return NT_STATUS_INVALID_PARAMETER;
|
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 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,
|
NTSTATUS socket_send(struct socket_context *sock,
|
||||||
const DATA_BLOB *blob, size_t *sendlen, uint32_t flags)
|
const DATA_BLOB *blob, size_t *sendlen, uint32_t flags)
|
||||||
{
|
{
|
||||||
if (sock->type != SOCKET_TYPE_STREAM) {
|
if (sock->type != SOCKET_TYPE_STREAM) {
|
||||||
return NT_STATUS_INVALID_PARAMETER;
|
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 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)
|
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);
|
struct socket_context **new_sock, uint32_t flags);
|
||||||
|
|
||||||
/* general ops */
|
/* general ops */
|
||||||
NTSTATUS (*recv)(struct socket_context *sock, TALLOC_CTX *mem_ctx,
|
NTSTATUS (*recv)(struct socket_context *sock, void *buf,
|
||||||
DATA_BLOB *blob, size_t wantlen, uint32_t flags);
|
size_t wantlen, size_t *nread, uint32_t flags);
|
||||||
NTSTATUS (*send)(struct socket_context *sock, TALLOC_CTX *mem_ctx,
|
NTSTATUS (*send)(struct socket_context *sock,
|
||||||
const DATA_BLOB *blob, size_t *sendlen, uint32_t flags);
|
const DATA_BLOB *blob, size_t *sendlen, uint32_t flags);
|
||||||
|
|
||||||
void (*close)(struct socket_context *sock);
|
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;
|
return NT_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS ipv4_tcp_recv(struct socket_context *sock, TALLOC_CTX *mem_ctx,
|
static NTSTATUS ipv4_tcp_recv(struct socket_context *sock, void *buf,
|
||||||
DATA_BLOB *blob, size_t wantlen, uint32_t flags)
|
size_t wantlen, size_t *nread, uint32_t flags)
|
||||||
{
|
{
|
||||||
ssize_t gotlen;
|
ssize_t gotlen;
|
||||||
void *buf;
|
|
||||||
int flgs = 0;
|
int flgs = 0;
|
||||||
|
|
||||||
buf = talloc(mem_ctx, wantlen);
|
|
||||||
if (!buf) {
|
|
||||||
return NT_STATUS_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: we need to map all flags here */
|
/* TODO: we need to map all flags here */
|
||||||
if (flags & SOCKET_FLAG_PEEK) {
|
if (flags & SOCKET_FLAG_PEEK) {
|
||||||
flgs |= MSG_PEEK;
|
flgs |= MSG_PEEK;
|
||||||
@@ -187,42 +181,21 @@ static NTSTATUS ipv4_tcp_recv(struct socket_context *sock, TALLOC_CTX *mem_ctx,
|
|||||||
flgs |= MSG_WAITALL;
|
flgs |= MSG_WAITALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*nread = 0;
|
||||||
|
|
||||||
gotlen = recv(sock->fd, buf, wantlen, flgs);
|
gotlen = recv(sock->fd, buf, wantlen, flgs);
|
||||||
if (gotlen == 0) {
|
if (gotlen == 0) {
|
||||||
talloc_free(buf);
|
|
||||||
return NT_STATUS_END_OF_FILE;
|
return NT_STATUS_END_OF_FILE;
|
||||||
} else if (gotlen == -1) {
|
} else if (gotlen == -1) {
|
||||||
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
|
return map_nt_error_from_unix(errno);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
blob->length = gotlen;
|
*nread = gotlen;
|
||||||
blob->data = talloc_realloc(mem_ctx, buf, gotlen);
|
|
||||||
if (!blob->data) {
|
|
||||||
return NT_STATUS_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NT_STATUS_OK;
|
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)
|
const DATA_BLOB *blob, size_t *sendlen, uint32_t flags)
|
||||||
{
|
{
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
|
|||||||
@@ -155,18 +155,12 @@ static NTSTATUS unixdom_accept(struct socket_context *sock,
|
|||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS unixdom_recv(struct socket_context *sock, TALLOC_CTX *mem_ctx,
|
static NTSTATUS unixdom_recv(struct socket_context *sock, void *buf,
|
||||||
DATA_BLOB *blob, size_t wantlen, uint32_t flags)
|
size_t wantlen, size_t *nread, uint32_t flags)
|
||||||
{
|
{
|
||||||
ssize_t gotlen;
|
ssize_t gotlen;
|
||||||
void *buf;
|
|
||||||
int flgs = 0;
|
int flgs = 0;
|
||||||
|
|
||||||
buf = talloc(mem_ctx, wantlen);
|
|
||||||
if (!buf) {
|
|
||||||
return NT_STATUS_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: we need to map all flags here */
|
/* TODO: we need to map all flags here */
|
||||||
if (flags & SOCKET_FLAG_PEEK) {
|
if (flags & SOCKET_FLAG_PEEK) {
|
||||||
flgs |= MSG_PEEK;
|
flgs |= MSG_PEEK;
|
||||||
@@ -176,26 +170,21 @@ static NTSTATUS unixdom_recv(struct socket_context *sock, TALLOC_CTX *mem_ctx,
|
|||||||
flgs |= MSG_WAITALL;
|
flgs |= MSG_WAITALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*nread = 0;
|
||||||
|
|
||||||
gotlen = recv(sock->fd, buf, wantlen, flgs);
|
gotlen = recv(sock->fd, buf, wantlen, flgs);
|
||||||
if (gotlen == 0) {
|
if (gotlen == 0) {
|
||||||
talloc_free(buf);
|
|
||||||
return NT_STATUS_END_OF_FILE;
|
return NT_STATUS_END_OF_FILE;
|
||||||
} else if (gotlen == -1) {
|
} else if (gotlen == -1) {
|
||||||
NTSTATUS status = unixdom_error(errno);
|
return unixdom_error(errno);
|
||||||
talloc_free(buf);
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
blob->length = gotlen;
|
*nread = gotlen;
|
||||||
blob->data = talloc_realloc(mem_ctx, buf, gotlen);
|
|
||||||
if (!blob->data) {
|
|
||||||
return NT_STATUS_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NT_STATUS_OK;
|
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)
|
const DATA_BLOB *blob, size_t *sendlen, uint32_t flags)
|
||||||
{
|
{
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ static void sock_process_send(struct dcerpc_pipe *p)
|
|||||||
struct sock_blob *blob = sock->pending_send;
|
struct sock_blob *blob = sock->pending_send;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
size_t sent;
|
size_t sent;
|
||||||
status = socket_send(sock->sock, blob, &blob->data, &sent, 0);
|
status = socket_send(sock->sock, &blob->data, &sent, 0);
|
||||||
if (NT_STATUS_IS_ERR(status)) {
|
if (NT_STATUS_IS_ERR(status)) {
|
||||||
sock_dead(p, NT_STATUS_NET_WRITE_FAULT);
|
sock_dead(p, NT_STATUS_NET_WRITE_FAULT);
|
||||||
break;
|
break;
|
||||||
@@ -116,7 +116,7 @@ static void sock_process_recv(struct dcerpc_pipe *p)
|
|||||||
{
|
{
|
||||||
struct sock_private *sock = p->transport.private;
|
struct sock_private *sock = p->transport.private;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
DATA_BLOB blob;
|
size_t nread;
|
||||||
|
|
||||||
if (sock->recv.data.data == NULL) {
|
if (sock->recv.data.data == NULL) {
|
||||||
sock->recv.data = data_blob_talloc(sock, NULL, MIN_HDR_SIZE);
|
sock->recv.data = data_blob_talloc(sock, NULL, MIN_HDR_SIZE);
|
||||||
@@ -126,19 +126,19 @@ static void sock_process_recv(struct dcerpc_pipe *p)
|
|||||||
if (sock->recv.received < MIN_HDR_SIZE) {
|
if (sock->recv.received < MIN_HDR_SIZE) {
|
||||||
uint32_t frag_length;
|
uint32_t frag_length;
|
||||||
|
|
||||||
status = socket_recv(sock->sock, sock, &blob, MIN_HDR_SIZE - sock->recv.received, 0);
|
status = socket_recv(sock->sock,
|
||||||
|
sock->recv.data.data + sock->recv.received,
|
||||||
|
MIN_HDR_SIZE - sock->recv.received,
|
||||||
|
&nread, 0);
|
||||||
if (NT_STATUS_IS_ERR(status)) {
|
if (NT_STATUS_IS_ERR(status)) {
|
||||||
sock_dead(p, NT_STATUS_NET_WRITE_FAULT);
|
sock_dead(p, NT_STATUS_NET_WRITE_FAULT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (blob.length == 0) {
|
if (nread == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(sock->recv.data.data + sock->recv.received,
|
sock->recv.received += nread;
|
||||||
blob.data, blob.length);
|
|
||||||
sock->recv.received += blob.length;
|
|
||||||
talloc_free(blob.data);
|
|
||||||
|
|
||||||
if (sock->recv.received != MIN_HDR_SIZE) {
|
if (sock->recv.received != MIN_HDR_SIZE) {
|
||||||
return;
|
return;
|
||||||
@@ -155,18 +155,18 @@ static void sock_process_recv(struct dcerpc_pipe *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* read in the rest of the packet */
|
/* read in the rest of the packet */
|
||||||
status = socket_recv(sock->sock, sock, &blob, sock->recv.data.length - sock->recv.received, 0);
|
status = socket_recv(sock->sock,
|
||||||
|
sock->recv.data.data + sock->recv.received,
|
||||||
|
sock->recv.data.length - sock->recv.received,
|
||||||
|
&nread, 0);
|
||||||
if (NT_STATUS_IS_ERR(status)) {
|
if (NT_STATUS_IS_ERR(status)) {
|
||||||
sock_dead(p, NT_STATUS_NET_WRITE_FAULT);
|
sock_dead(p, NT_STATUS_NET_WRITE_FAULT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (blob.length == 0) {
|
if (nread == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memcpy(sock->recv.data.data + sock->recv.received,
|
sock->recv.received += nread;
|
||||||
blob.data, blob.length);
|
|
||||||
sock->recv.received += blob.length;
|
|
||||||
talloc_free(blob.data);
|
|
||||||
|
|
||||||
if (sock->recv.received != sock->recv.data.length) {
|
if (sock->recv.received != sock->recv.data.length) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ static ssize_t dcerpc_write_fn(void *private, DATA_BLOB *out)
|
|||||||
struct socket_context *sock = private;
|
struct socket_context *sock = private;
|
||||||
size_t sendlen;
|
size_t sendlen;
|
||||||
|
|
||||||
status = socket_send(sock, sock, out, &sendlen, 0);
|
status = socket_send(sock, out, &sendlen, 0);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -131,7 +131,7 @@ static void add_socket_rpc_tcp_iface(struct server_service *service,
|
|||||||
struct server_socket *sock;
|
struct server_socket *sock;
|
||||||
struct dcesrv_socket_context *dcesrv_sock;
|
struct dcesrv_socket_context *dcesrv_sock;
|
||||||
uint16_t port = 0;
|
uint16_t port = 0;
|
||||||
const char *ip_str = talloc_strdup(service, inet_ntoa(*ifip));
|
char *ip_str = talloc_strdup(service, inet_ntoa(*ifip));
|
||||||
|
|
||||||
if (e->ep_description.endpoint)
|
if (e->ep_description.endpoint)
|
||||||
port = atoi(e->ep_description.endpoint);
|
port = atoi(e->ep_description.endpoint);
|
||||||
@@ -251,22 +251,30 @@ void dcesrv_sock_recv(struct server_connection *conn, time_t t, uint16_t flags)
|
|||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
struct dcesrv_connection *dce_conn = conn->private_data;
|
struct dcesrv_connection *dce_conn = conn->private_data;
|
||||||
DATA_BLOB tmp_blob;
|
DATA_BLOB tmp_blob;
|
||||||
|
size_t nread;
|
||||||
|
|
||||||
DEBUG(10,("dcesrv_sock_recv\n"));
|
tmp_blob = data_blob_talloc(conn->socket, NULL, 0x1000);
|
||||||
|
if (tmp_blob.data == NULL) {
|
||||||
status = socket_recv(conn->socket, conn->socket, &tmp_blob, 0x4000, 0);
|
dcesrv_terminate_connection(dce_conn, "out of memory");
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
|
||||||
if (NT_STATUS_IS_ERR(status)) {
|
|
||||||
dcesrv_terminate_connection(dce_conn, "eof on socket");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status = socket_recv(conn->socket, tmp_blob.data, tmp_blob.length, &nread, 0);
|
||||||
|
if (NT_STATUS_IS_ERR(status)) {
|
||||||
|
dcesrv_terminate_connection(dce_conn, nt_errstr(status));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (nread == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp_blob.length = nread;
|
||||||
|
|
||||||
status = dcesrv_input(dce_conn, &tmp_blob);
|
status = dcesrv_input(dce_conn, &tmp_blob);
|
||||||
talloc_free(tmp_blob.data);
|
talloc_free(tmp_blob.data);
|
||||||
|
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
dcesrv_terminate_connection(dce_conn, "eof on socket");
|
dcesrv_terminate_connection(dce_conn, nt_errstr(status));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -252,7 +252,7 @@ void req_send_reply_nosign(struct smbsrv_request *req)
|
|||||||
tmp_blob.data = req->out.buffer;
|
tmp_blob.data = req->out.buffer;
|
||||||
tmp_blob.length = req->out.size;
|
tmp_blob.length = req->out.size;
|
||||||
|
|
||||||
status = socket_send(req->smb_conn->connection->socket, req, &tmp_blob, &sendlen, SOCKET_FLAG_BLOCK);
|
status = socket_send(req->smb_conn->connection->socket, &tmp_blob, &sendlen, SOCKET_FLAG_BLOCK);
|
||||||
if (!NT_STATUS_IS_OK(status) || (req->out.size != sendlen)) {
|
if (!NT_STATUS_IS_OK(status) || (req->out.size != sendlen)) {
|
||||||
smbsrv_terminate_connection(req->smb_conn, "failed to send reply\n");
|
smbsrv_terminate_connection(req->smb_conn, "failed to send reply\n");
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -64,17 +64,19 @@ static struct smbsrv_request *receive_smb_request(struct smbsrv_connection *smb_
|
|||||||
ssize_t len, len2;
|
ssize_t len, len2;
|
||||||
DATA_BLOB tmp_blob;
|
DATA_BLOB tmp_blob;
|
||||||
struct smbsrv_request *req;
|
struct smbsrv_request *req;
|
||||||
|
char hdr[4];
|
||||||
|
size_t nread;
|
||||||
|
|
||||||
status = socket_recv(smb_conn->connection->socket, smb_conn, &tmp_blob, 4, SOCKET_FLAG_BLOCK|SOCKET_FLAG_PEEK);
|
status = socket_recv(smb_conn->connection->socket, hdr,
|
||||||
|
4, &nread, SOCKET_FLAG_BLOCK|SOCKET_FLAG_PEEK);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (tmp_blob.length != 4) {
|
if (nread != 4) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = smb_len(tmp_blob.data);
|
len = smb_len(hdr);
|
||||||
talloc_free(tmp_blob.data);
|
|
||||||
|
|
||||||
req = init_smb_request(smb_conn);
|
req = init_smb_request(smb_conn);
|
||||||
|
|
||||||
@@ -83,11 +85,18 @@ static struct smbsrv_request *receive_smb_request(struct smbsrv_connection *smb_
|
|||||||
|
|
||||||
len2 = len + NBT_HDR_SIZE;
|
len2 = len + NBT_HDR_SIZE;
|
||||||
|
|
||||||
status = socket_recv(smb_conn->connection->socket, req, &tmp_blob, len2, SOCKET_FLAG_BLOCK);
|
tmp_blob = data_blob_talloc(req, NULL, len2);
|
||||||
|
if (tmp_blob.data == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = socket_recv(smb_conn->connection->socket,
|
||||||
|
tmp_blob.data, len2,
|
||||||
|
&nread, SOCKET_FLAG_BLOCK);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (tmp_blob.length != len2) {
|
if (nread != len2) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user