1
0
mirror of https://github.com/samba-team/samba.git synced 2025-11-01 16:23:49 +03:00

r3307: fixed the send side of the smb_server code to be non-blocking. This

means the whole of the SMB handling code is now non-blocking.
This commit is contained in:
Andrew Tridgell
2004-10-28 05:09:42 +00:00
committed by Gerald (Jerry) Carter
parent bda978cc2a
commit 30acedb943
3 changed files with 49 additions and 18 deletions

View File

@@ -241,24 +241,16 @@ void req_grow_data(struct smbsrv_request *req, uint_t new_size)
*/
void req_send_reply_nosign(struct smbsrv_request *req)
{
NTSTATUS status;
DATA_BLOB tmp_blob;
size_t sendlen;
if (req->out.size > NBT_HDR_SIZE) {
_smb_setlen(req->out.buffer, req->out.size - NBT_HDR_SIZE);
}
tmp_blob.data = req->out.buffer;
tmp_blob.length = req->out.size;
/* add the request to the list of requests that need to be
sent to the client, then mark the socket event structure
ready for write events */
DLIST_ADD_END(req->smb_conn->pending_send, req, struct smbsrv_request *);
status = socket_send(req->smb_conn->connection->socket, &tmp_blob, &sendlen, SOCKET_FLAG_BLOCK);
if (!NT_STATUS_IS_OK(status) || (req->out.size != sendlen)) {
smbsrv_terminate_connection(req->smb_conn, "failed to send reply\n");
return;
}
req_destroy(req);
req->smb_conn->connection->event.fde->flags |= EVENT_FD_WRITE;
}
/*

View File

@@ -804,8 +804,42 @@ static void smbsrv_recv(struct server_connection *conn, time_t t, uint16_t flags
*/
static void smbsrv_send(struct server_connection *conn, time_t t, uint16_t flags)
{
DEBUG(10,("smbsrv_send\n"));
return;
struct smbsrv_connection *smb_conn = conn->private_data;
while (smb_conn->pending_send) {
struct smbsrv_request *req = smb_conn->pending_send;
DATA_BLOB blob;
NTSTATUS status;
size_t sendlen;
blob.data = req->out.buffer;
blob.length = req->out.size;
/* send as much of this request as we can */
status = socket_send(conn->socket, &blob, &sendlen, 0);
if (NT_STATUS_IS_ERR(status)) {
smbsrv_terminate_connection(req->smb_conn, nt_errstr(status));
return;
}
if (sendlen == 0) {
break;
}
req->out.buffer += sendlen;
req->out.size -= sendlen;
/* is the whole request gone? */
if (req->out.size == 0) {
DLIST_REMOVE(smb_conn->pending_send, req);
req_destroy(req);
}
}
/* if no more requests are pending to be sent then
we should stop select for write */
if (smb_conn->pending_send == NULL) {
conn->event.fde->flags &= ~EVENT_FD_WRITE;
}
}
/*
@@ -860,11 +894,9 @@ void smbsrv_accept(struct server_connection *conn)
DEBUG(5,("smbsrv_accept\n"));
smb_conn = talloc_p(conn, struct smbsrv_connection);
smb_conn = talloc_zero_p(conn, struct smbsrv_connection);
if (!smb_conn) return;
ZERO_STRUCTP(smb_conn);
smb_conn->pid = getpid();
sub_set_context(&smb_conn->substitute);

View File

@@ -74,6 +74,9 @@ struct smbsrv_tcon {
/* the context for a single SMB request. This is passed to any request-context
functions */
struct smbsrv_request {
/* the smbsrv_connection needs a list of requests queued for send */
struct smbsrv_request *next, *prev;
/* the server_context contains all context specific to this SMB socket */
struct smbsrv_connection *smb_conn;
@@ -289,4 +292,8 @@ struct smbsrv_connection {
/* this holds a partially received request */
struct smbsrv_request *partial_req;
/* this holds list of replies that are waiting to be sent
to the client */
struct smbsrv_request *pending_send;
};