summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2004-10-28 07:55:33 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:04:53 -0500
commit990d76f7cbd4339c30f650781c40463234fc47e1 (patch)
treee65cae139e5028f46ea635c0aabd99d6efbe71c6 /source4
parent34cd0662f0340720fa45dd16c82496cd76e92268 (diff)
downloadsamba-990d76f7cbd4339c30f650781c40463234fc47e1.tar.gz
samba-990d76f7cbd4339c30f650781c40463234fc47e1.tar.bz2
samba-990d76f7cbd4339c30f650781c40463234fc47e1.zip
r3314: added a option "socket:testnonblock" to the generic socket code. If
you set this option (either on the command line using --option or in smb.conf) then every socket recv or send will return short by random amounts. This allows you to test that the non-blocking socket logic in your code works correctly. I also removed the flags argument to socket_accept(), and instead made the new socket inherit the flags of the old socket, which makes more sense to me. (This used to be commit 406d356e698da01c84e8aa5b7894752b4403f63c)
Diffstat (limited to 'source4')
-rw-r--r--source4/lib/messaging/messaging.c2
-rw-r--r--source4/lib/socket/socket.c22
-rw-r--r--source4/lib/socket/socket.h8
-rw-r--r--source4/lib/socket/socket_ipv4.c6
-rw-r--r--source4/lib/socket/socket_unix.c7
-rw-r--r--source4/smbd/process_single.c2
-rw-r--r--source4/smbd/process_standard.c2
-rw-r--r--source4/smbd/process_thread.c2
8 files changed, 34 insertions, 17 deletions
diff --git a/source4/lib/messaging/messaging.c b/source4/lib/messaging/messaging.c
index 09d0c43934..7f90bd4e40 100644
--- a/source4/lib/messaging/messaging.c
+++ b/source4/lib/messaging/messaging.c
@@ -208,7 +208,7 @@ static void messaging_listen_handler(struct event_context *ev, struct fd_event *
smb_panic("Unable to allocate messaging_rec");
}
- status = socket_accept(msg->sock, &rec->sock, 0);
+ status = socket_accept(msg->sock, &rec->sock);
if (!NT_STATUS_IS_OK(status)) {
smb_panic("Unable to accept messaging_rec");
}
diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c
index 94d8b5bada..22b40e076c 100644
--- a/source4/lib/socket/socket.c
+++ b/source4/lib/socket/socket.c
@@ -60,6 +60,14 @@ NTSTATUS socket_create(const char *name, enum socket_type type, struct socket_co
return status;
}
+ /* by enabling "testnonblock" mode, all socket receive and
+ send calls on non-blocking sockets will randomly recv/send
+ less data than requested */
+ if (!(flags & SOCKET_FLAG_BLOCK) &&
+ lp_parm_bool(-1, "socket", "testnonblock", False)) {
+ (*new_sock)->flags |= SOCKET_FLAG_TESTNONBLOCK;
+ }
+
talloc_set_destructor(*new_sock, socket_destructor);
return NT_STATUS_OK;
@@ -108,7 +116,7 @@ NTSTATUS socket_listen(struct socket_context *sock, const char *my_address, int
return sock->ops->listen(sock, my_address, port, queue_size, flags);
}
-NTSTATUS socket_accept(struct socket_context *sock, struct socket_context **new_sock, uint32_t flags)
+NTSTATUS socket_accept(struct socket_context *sock, struct socket_context **new_sock)
{
NTSTATUS status;
@@ -124,7 +132,7 @@ NTSTATUS socket_accept(struct socket_context *sock, struct socket_context **new_
return NT_STATUS_NOT_IMPLEMENTED;
}
- status = sock->ops->accept(sock, new_sock, flags);
+ status = sock->ops->accept(sock, new_sock);
if (NT_STATUS_IS_OK(status)) {
talloc_set_destructor(*new_sock, socket_destructor);
@@ -149,6 +157,10 @@ NTSTATUS socket_recv(struct socket_context *sock, void *buf,
return NT_STATUS_NOT_IMPLEMENTED;
}
+ if ((sock->flags & SOCKET_FLAG_TESTNONBLOCK) && wantlen > 1) {
+ return sock->ops->recv(sock, buf, 1+(random() % (wantlen-1)), nread, flags);
+ }
+
return sock->ops->recv(sock, buf, wantlen, nread, flags);
}
@@ -168,6 +180,12 @@ NTSTATUS socket_send(struct socket_context *sock,
return NT_STATUS_NOT_IMPLEMENTED;
}
+ if ((sock->flags & SOCKET_FLAG_TESTNONBLOCK) && blob->length > 1) {
+ DATA_BLOB blob2 = *blob;
+ blob2.length = 1+(random() % (blob2.length-1));
+ return sock->ops->send(sock, &blob2, sendlen, flags);
+ }
+
return sock->ops->send(sock, blob, sendlen, flags);
}
diff --git a/source4/lib/socket/socket.h b/source4/lib/socket/socket.h
index 6562bb376b..6e54a37b80 100644
--- a/source4/lib/socket/socket.h
+++ b/source4/lib/socket/socket.h
@@ -42,8 +42,7 @@ struct socket_ops {
/* server ops */
NTSTATUS (*listen)(struct socket_context *sock,
const char *my_address, int port, int queue_size, uint32_t flags);
- NTSTATUS (*accept)(struct socket_context *sock,
- struct socket_context **new_sock, uint32_t flags);
+ NTSTATUS (*accept)(struct socket_context *sock, struct socket_context **new_sock);
/* general ops */
NTSTATUS (*recv)(struct socket_context *sock, void *buf,
@@ -78,8 +77,9 @@ enum socket_state {
SOCKET_STATE_SERVER_ERROR
};
-#define SOCKET_FLAG_BLOCK 0x00000001
-#define SOCKET_FLAG_PEEK 0x00000002
+#define SOCKET_FLAG_BLOCK 0x00000001
+#define SOCKET_FLAG_PEEK 0x00000002
+#define SOCKET_FLAG_TESTNONBLOCK 0x00000004
struct socket_context {
enum socket_type type;
diff --git a/source4/lib/socket/socket_ipv4.c b/source4/lib/socket/socket_ipv4.c
index 71e1c62235..f9318a29bb 100644
--- a/source4/lib/socket/socket_ipv4.c
+++ b/source4/lib/socket/socket_ipv4.c
@@ -130,7 +130,7 @@ static NTSTATUS ipv4_tcp_listen(struct socket_context *sock,
return NT_STATUS_OK;
}
-static NTSTATUS ipv4_tcp_accept(struct socket_context *sock, struct socket_context **new_sock, uint32_t flags)
+static NTSTATUS ipv4_tcp_accept(struct socket_context *sock, struct socket_context **new_sock)
{
struct sockaddr_in cli_addr;
socklen_t cli_addr_len = sizeof(cli_addr);
@@ -141,7 +141,7 @@ static NTSTATUS ipv4_tcp_accept(struct socket_context *sock, struct socket_conte
return map_nt_error_from_unix(errno);
}
- if (!(flags & SOCKET_FLAG_BLOCK)) {
+ if (!(sock->flags & SOCKET_FLAG_BLOCK)) {
int ret = set_blocking(new_fd, False);
if (ret == -1) {
close(new_fd);
@@ -164,7 +164,7 @@ static NTSTATUS ipv4_tcp_accept(struct socket_context *sock, struct socket_conte
/* copy the socket_context */
(*new_sock)->type = sock->type;
(*new_sock)->state = SOCKET_STATE_SERVER_CONNECTED;
- (*new_sock)->flags = flags;
+ (*new_sock)->flags = sock->flags;
(*new_sock)->fd = new_fd;
diff --git a/source4/lib/socket/socket_unix.c b/source4/lib/socket/socket_unix.c
index 239e4eb069..d160d897ee 100644
--- a/source4/lib/socket/socket_unix.c
+++ b/source4/lib/socket/socket_unix.c
@@ -124,8 +124,7 @@ static NTSTATUS unixdom_listen(struct socket_context *sock,
}
static NTSTATUS unixdom_accept(struct socket_context *sock,
- struct socket_context **new_sock,
- uint32_t flags)
+ struct socket_context **new_sock)
{
struct sockaddr_un cli_addr;
socklen_t cli_addr_len = sizeof(cli_addr);
@@ -136,7 +135,7 @@ static NTSTATUS unixdom_accept(struct socket_context *sock,
return unixdom_error(errno);
}
- if (!(flags & SOCKET_FLAG_BLOCK)) {
+ if (!(sock->flags & SOCKET_FLAG_BLOCK)) {
int ret = set_blocking(new_fd, False);
if (ret == -1) {
close(new_fd);
@@ -153,7 +152,7 @@ static NTSTATUS unixdom_accept(struct socket_context *sock,
/* copy the socket_context */
(*new_sock)->type = sock->type;
(*new_sock)->state = SOCKET_STATE_SERVER_CONNECTED;
- (*new_sock)->flags = flags;
+ (*new_sock)->flags = sock->flags;
(*new_sock)->fd = new_fd;
diff --git a/source4/smbd/process_single.c b/source4/smbd/process_single.c
index b96a1d0b2c..603726e22d 100644
--- a/source4/smbd/process_single.c
+++ b/source4/smbd/process_single.c
@@ -42,7 +42,7 @@ static void single_accept_connection(struct event_context *ev, struct fd_event *
struct server_connection *conn;
/* accept an incoming connection. */
- status = socket_accept(server_socket->socket, &sock, 0);
+ status = socket_accept(server_socket->socket, &sock);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("accept_connection_single: accept: %s\n",
nt_errstr(status)));
diff --git a/source4/smbd/process_standard.c b/source4/smbd/process_standard.c
index 98810af028..106be77925 100644
--- a/source4/smbd/process_standard.c
+++ b/source4/smbd/process_standard.c
@@ -43,7 +43,7 @@ static void standard_accept_connection(struct event_context *ev, struct fd_event
pid_t pid;
/* accept an incoming connection. */
- status = socket_accept(server_socket->socket, &sock, 0);
+ status = socket_accept(server_socket->socket, &sock);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("standard_accept_connection: accept: %s\n",
nt_errstr(status)));
diff --git a/source4/smbd/process_thread.c b/source4/smbd/process_thread.c
index 108b098b8a..2b8746efb2 100644
--- a/source4/smbd/process_thread.c
+++ b/source4/smbd/process_thread.c
@@ -58,7 +58,7 @@ static void thread_accept_connection(struct event_context *ev, struct fd_event *
struct server_connection *conn;
/* accept an incoming connection. */
- status = socket_accept(server_socket->socket, &sock, 0);
+ status = socket_accept(server_socket->socket, &sock);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("accept_connection_single: accept: %s\n",
nt_errstr(status)));