From ce694e7051dca90cdb5700e3865315d16931c3c1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Sep 2004 14:17:41 +0000 Subject: r2328: add the start of a new system and protocol independent socket library. this is not used, but compiled currently there're maybe some api changes later... metze (This used to be commit de4447d7a57c614b80d0ac00dca900ea7e1c21ea) --- source4/lib/socket/socket.c | 215 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 source4/lib/socket/socket.c (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c new file mode 100644 index 0000000000..fefd7a14b2 --- /dev/null +++ b/source4/lib/socket/socket.c @@ -0,0 +1,215 @@ +/* + Unix SMB/CIFS implementation. + Socket functions + Copyright (C) Stefan Metzmacher 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +NTSTATUS socket_create(const char *name, enum socket_type type, struct socket_context **new_sock, uint32_t flags) +{ + NTSTATUS status; + + (*new_sock) = talloc_p(NULL, struct socket_context); + if (!(*new_sock)) { + return NT_STATUS_NO_MEMORY; + } + + (*new_sock)->type = type; + (*new_sock)->state = SOCKET_STATE_UNDEFINED; + (*new_sock)->flags = flags; + + (*new_sock)->fd = -1; + + (*new_sock)->private_data = NULL; + (*new_sock)->ops = socket_getops_byname(name, type); + if (!(*new_sock)->ops) { + talloc_free((*new_sock)); + return status; + } + + status = (*new_sock)->ops->init((*new_sock)); + if (!NT_STATUS_IS_OK(status)) { + talloc_free((*new_sock)); + return status; + } + + return NT_STATUS_OK; +} + +void socket_destroy(struct socket_context *sock) +{ + if (sock->ops->close) { + sock->ops->close(sock); + } + talloc_free(sock); +} + +NTSTATUS socket_connect(struct socket_context *sock, + const char *my_address, int my_port, + const char *server_address, int server_port, + uint32_t flags) +{ + if (sock->type != SOCKET_TYPE_STREAM) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (sock->state != SOCKET_STATE_UNDEFINED) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (!sock->ops->connect) { + return NT_STATUS_NOT_IMPLEMENTED; + } + + return sock->ops->connect(sock, my_address, my_port, server_address, server_port, flags); +} + +NTSTATUS socket_listen(struct socket_context *sock, const char *my_address, int port, int queue_size, uint32_t flags) +{ + if (sock->type != SOCKET_TYPE_STREAM) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (sock->state != SOCKET_STATE_UNDEFINED) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (!sock->ops->listen) { + return NT_STATUS_NOT_IMPLEMENTED; + } + + 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) +{ + if (sock->type != SOCKET_TYPE_STREAM) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (sock->state != SOCKET_STATE_SERVER_LISTEN) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (!sock->ops->accept) { + return NT_STATUS_NOT_IMPLEMENTED; + } + + return sock->ops->accept(sock, new_sock, flags); +} + +NTSTATUS socket_recv(struct socket_context *sock, TALLOC_CTX *mem_ctx, + DATA_BLOB *blob, size_t wantlen, uint32_t flags) +{ + if (sock->type != SOCKET_TYPE_STREAM) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (sock->state != SOCKET_STATE_CLIENT_CONNECTED || + sock->state != SOCKET_STATE_SERVER_CONNECTED) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (!sock->ops->recv) { + return NT_STATUS_NOT_IMPLEMENTED; + } + + return sock->ops->recv(sock, mem_ctx, blob, wantlen, flags); +} + +NTSTATUS socket_send(struct socket_context *sock, TALLOC_CTX *mem_ctx, + const DATA_BLOB *blob, size_t *sendlen, uint32_t flags) +{ + if (sock->type != SOCKET_TYPE_STREAM) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (sock->state != SOCKET_STATE_CLIENT_CONNECTED || + sock->state != SOCKET_STATE_SERVER_CONNECTED) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (!sock->ops->send) { + return NT_STATUS_NOT_IMPLEMENTED; + } + + return sock->ops->send(sock, mem_ctx, blob, sendlen, flags); +} + +NTSTATUS socket_set_option(struct socket_context *sock, const char *option, const char *val) +{ + if (!sock->ops->set_option) { + return NT_STATUS_NOT_IMPLEMENTED; + } + + return sock->ops->set_option(sock, option, val); +} + +const char *socket_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) +{ + if (!sock->ops->get_peer_addr) { + return NULL; + } + + return sock->ops->get_peer_addr(sock, mem_ctx); +} + +int socket_get_peer_port(struct socket_context *sock, TALLOC_CTX *mem_ctx) +{ + if (!sock->ops->get_peer_port) { + return -1; + } + + return sock->ops->get_peer_port(sock, mem_ctx); +} + +const char *socket_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) +{ + if (!sock->ops->get_my_addr) { + return NULL; + } + + return sock->ops->get_my_addr(sock, mem_ctx); +} + +int socket_get_my_port(struct socket_context *sock, TALLOC_CTX *mem_ctx) +{ + if (!sock->ops->get_my_port) { + return -1; + } + + return sock->ops->get_my_port(sock, mem_ctx); +} + +int socket_get_fd(struct socket_context *sock, TALLOC_CTX *mem_ctx) +{ + if (!sock->ops->get_fd) { + return -1; + } + + return sock->ops->get_fd(sock, mem_ctx); +} + +const struct socket_ops *socket_getops_byname(const char *name, enum socket_type type) +{ + if (strequal("ip", name) || strequal("ipv4", name)) { + return socket_ipv4_ops(); + } + + return NULL; +} -- cgit From 498ea8485f8763a1c4e39bf49cd0b68004b2f8c3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Sep 2004 12:14:47 +0000 Subject: r2343: - make socket_get_*_addr() return char * not const char * - add some error mappings - use some flags SOCKET_FLAG_PEEK ans SOCKET_FLAG_BLOCK metze (This used to be commit a375c6b0b1ec4d63251f63993f7798c1f2e7c717) --- source4/lib/socket/socket.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index fefd7a14b2..5fd587a635 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -160,7 +160,7 @@ NTSTATUS socket_set_option(struct socket_context *sock, const char *option, cons return sock->ops->set_option(sock, option, val); } -const char *socket_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) +char *socket_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) { if (!sock->ops->get_peer_addr) { return NULL; @@ -178,7 +178,7 @@ int socket_get_peer_port(struct socket_context *sock, TALLOC_CTX *mem_ctx) return sock->ops->get_peer_port(sock, mem_ctx); } -const char *socket_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) +char *socket_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) { if (!sock->ops->get_my_addr) { return NULL; -- cgit From be61c9d8773eb3d0dd97bcd5e9ccd3f1aabcd1d6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 20 Sep 2004 09:13:17 +0000 Subject: r2439: - function that return just an int don't need a TALLOC_CTX - fix some return and state bugs metze (This used to be commit 2757c593ab746b9dd7090f2cf5fcc31686adf67f) --- source4/lib/socket/socket.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 5fd587a635..6869114587 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -39,7 +39,7 @@ NTSTATUS socket_create(const char *name, enum socket_type type, struct socket_co (*new_sock)->ops = socket_getops_byname(name, type); if (!(*new_sock)->ops) { talloc_free((*new_sock)); - return status; + return NT_STATUS_INVALID_PARAMETER; } status = (*new_sock)->ops->init((*new_sock)); @@ -120,7 +120,7 @@ NTSTATUS socket_recv(struct socket_context *sock, TALLOC_CTX *mem_ctx, return NT_STATUS_INVALID_PARAMETER; } - if (sock->state != SOCKET_STATE_CLIENT_CONNECTED || + if (sock->state != SOCKET_STATE_CLIENT_CONNECTED && sock->state != SOCKET_STATE_SERVER_CONNECTED) { return NT_STATUS_INVALID_PARAMETER; } @@ -139,7 +139,7 @@ NTSTATUS socket_send(struct socket_context *sock, TALLOC_CTX *mem_ctx, return NT_STATUS_INVALID_PARAMETER; } - if (sock->state != SOCKET_STATE_CLIENT_CONNECTED || + if (sock->state != SOCKET_STATE_CLIENT_CONNECTED && sock->state != SOCKET_STATE_SERVER_CONNECTED) { return NT_STATUS_INVALID_PARAMETER; } @@ -169,13 +169,13 @@ char *socket_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) return sock->ops->get_peer_addr(sock, mem_ctx); } -int socket_get_peer_port(struct socket_context *sock, TALLOC_CTX *mem_ctx) +int socket_get_peer_port(struct socket_context *sock) { if (!sock->ops->get_peer_port) { return -1; } - return sock->ops->get_peer_port(sock, mem_ctx); + return sock->ops->get_peer_port(sock); } char *socket_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) @@ -187,22 +187,22 @@ char *socket_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) return sock->ops->get_my_addr(sock, mem_ctx); } -int socket_get_my_port(struct socket_context *sock, TALLOC_CTX *mem_ctx) +int socket_get_my_port(struct socket_context *sock) { if (!sock->ops->get_my_port) { return -1; } - return sock->ops->get_my_port(sock, mem_ctx); + return sock->ops->get_my_port(sock); } -int socket_get_fd(struct socket_context *sock, TALLOC_CTX *mem_ctx) +int socket_get_fd(struct socket_context *sock) { if (!sock->ops->get_fd) { return -1; } - return sock->ops->get_fd(sock, mem_ctx); + return sock->ops->get_fd(sock); } const struct socket_ops *socket_getops_byname(const char *name, enum socket_type type) -- cgit From fe45888e228d1452b8301b3b074794bd443a7fa5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 24 Sep 2004 03:34:55 +0000 Subject: r2581: added "hosts allow" and "hosts deny" checking in smbd. I needed this as my box keeps getting hit by viruses spreading on my companies internal network, which screws up my debug log badly (sigh). metze, I'm not sure if you think access.c should go in the socket library or not. It is closely tied to the socket functions, but you may prefer it separate. The access.c code is a port from Samba3, but with some cleanups to make it (slighly) less ugly. (This used to be commit 058b2fd99e3957d7d2a9544fd27071f1122eab68) --- source4/lib/socket/socket.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 6869114587..4814cc6a5a 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -160,6 +160,15 @@ NTSTATUS socket_set_option(struct socket_context *sock, const char *option, cons return sock->ops->set_option(sock, option, val); } +char *socket_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ctx) +{ + if (!sock->ops->get_peer_name) { + return NULL; + } + + return sock->ops->get_peer_name(sock, mem_ctx); +} + char *socket_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) { if (!sock->ops->get_peer_addr) { -- cgit From 764eddb69647681f784f343a122251ca1ecf62df Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 26 Sep 2004 03:05:04 +0000 Subject: r2646: - use a talloc destructor to ensure that sockets from the new socket library are closed on abnormal termination - convert the service.h structures to the new talloc methods (This used to be commit 2dc334a3284858eb1c7190f9687c9b6c879ecc9d) --- source4/lib/socket/socket.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 4814cc6a5a..4fde41a3c0 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -20,6 +20,18 @@ #include "includes.h" +/* + auto-close sockets on free +*/ +static int socket_destructor(void *ptr) +{ + struct socket_context *sock = ptr; + if (sock->ops->close) { + sock->ops->close(sock); + } + return 0; +} + NTSTATUS socket_create(const char *name, enum socket_type type, struct socket_context **new_sock, uint32_t flags) { NTSTATUS status; @@ -38,24 +50,24 @@ NTSTATUS socket_create(const char *name, enum socket_type type, struct socket_co (*new_sock)->private_data = NULL; (*new_sock)->ops = socket_getops_byname(name, type); if (!(*new_sock)->ops) { - talloc_free((*new_sock)); + talloc_free(*new_sock); return NT_STATUS_INVALID_PARAMETER; } status = (*new_sock)->ops->init((*new_sock)); if (!NT_STATUS_IS_OK(status)) { - talloc_free((*new_sock)); + talloc_free(*new_sock); return status; } + talloc_set_destructor(*new_sock, socket_destructor); + return NT_STATUS_OK; } void socket_destroy(struct socket_context *sock) { - if (sock->ops->close) { - sock->ops->close(sock); - } + /* the close is handled by the destructor */ talloc_free(sock); } @@ -98,6 +110,8 @@ NTSTATUS socket_listen(struct socket_context *sock, const char *my_address, int NTSTATUS socket_accept(struct socket_context *sock, struct socket_context **new_sock, uint32_t flags) { + NTSTATUS status; + if (sock->type != SOCKET_TYPE_STREAM) { return NT_STATUS_INVALID_PARAMETER; } @@ -110,7 +124,13 @@ NTSTATUS socket_accept(struct socket_context *sock, struct socket_context **new_ return NT_STATUS_NOT_IMPLEMENTED; } - return sock->ops->accept(sock, new_sock, flags); + status = sock->ops->accept(sock, new_sock, flags); + + if (NT_STATUS_IS_OK(status)) { + talloc_set_destructor(*new_sock, socket_destructor); + } + + return status; } NTSTATUS socket_recv(struct socket_context *sock, TALLOC_CTX *mem_ctx, -- cgit From f42402da83afa97f821d36b7974de98ddd5a2880 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 17 Oct 2004 05:07:07 +0000 Subject: r3013: added support for unix domain sockets in the generic socket library. I will shortly be using this for a rewrite of the intra-smbd messaging library, which is needed to get lock timeouts working properly (and share modes, oplocks etc) (This used to be commit 6f4926d846965a901e40d24546eab356c4a537c7) --- source4/lib/socket/socket.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 4fde41a3c0..f364ca7c9f 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -240,5 +240,9 @@ const struct socket_ops *socket_getops_byname(const char *name, enum socket_type return socket_ipv4_ops(); } + if (strequal("unix", name)) { + return socket_ipv4_ops(); + } + return NULL; } -- cgit From 844de2b65c931120a2408365c00fa80cb65959fc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 17 Oct 2004 05:29:03 +0000 Subject: r3015: fixed typo noticed by abartlett (This used to be commit b367209a9f94e471efed233639467babbb2b99d7) --- source4/lib/socket/socket.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index f364ca7c9f..f70a76262b 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -236,12 +236,13 @@ int socket_get_fd(struct socket_context *sock) const struct socket_ops *socket_getops_byname(const char *name, enum socket_type type) { - if (strequal("ip", name) || strequal("ipv4", name)) { + if (strcmp("ip", name) == 0 || + strcmp("ipv4", name) == 0) { return socket_ipv4_ops(); } - if (strequal("unix", name)) { - return socket_ipv4_ops(); + if (strcmp("unix", name) == 0) { + return socket_unixdom_ops(); } return NULL; -- cgit From 9d055846f225bea4953822f40fab1d2f1a2e2d07 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 27 Oct 2004 03:15:42 +0000 Subject: r3278: - rewrote the client side rpc connection code to use lib/socket/ rather than doing everything itself. This greatly simplifies the code, although I really don't like the socket_recv() interface (it always allocates memory for you, which means an extra memcpy in this code) - fixed several bugs in the socket_ipv4.c code, in particular client side code used a non-blocking connect but didn't handle EINPROGRESS, so it had no chance of working. Also fixed the error codes, using map_nt_error_from_unix() - cleaned up and expanded map_nt_error_from_unix() - changed interpret_addr2() to not take a mem_ctx. It makes absolutely no sense to allocate a fixed size 4 byte structure like this. Dozens of places in the code were also using interpret_addr2() incorrectly (precisely because the allocation made no sense) (This used to be commit 7f2c771b0e0e98c5c9e5cf662592d64d34ff1205) --- source4/lib/socket/socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index f70a76262b..f5ee84a7cc 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -134,7 +134,7 @@ NTSTATUS socket_accept(struct socket_context *sock, struct socket_context **new_ } NTSTATUS socket_recv(struct socket_context *sock, TALLOC_CTX *mem_ctx, - DATA_BLOB *blob, size_t wantlen, uint32_t flags) + DATA_BLOB *blob, size_t wantlen, uint32_t flags) { if (sock->type != SOCKET_TYPE_STREAM) { return NT_STATUS_INVALID_PARAMETER; -- cgit From c6888da1487ab301292c3d4d05d0464833f3ce57 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 28 Oct 2004 04:00:43 +0000 Subject: 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) --- source4/lib/socket/socket.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/lib/socket/socket.c') 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) -- cgit From 990d76f7cbd4339c30f650781c40463234fc47e1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 28 Oct 2004 07:55:33 +0000 Subject: 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) --- source4/lib/socket/socket.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'source4/lib/socket/socket.c') 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); } -- cgit From 8c752ec86156ebfa78f91ee17fab896215bc9322 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 28 Oct 2004 11:57:20 +0000 Subject: r3318: generate random STATUS_MORE_ENTRIES errors (1 in 10 packets) as well as randomly short recv/send when socket:testnonblock is enabled (This used to be commit 718175a265d34bfdbcbf0cc6b55dbf6b389f3194) --- source4/lib/socket/socket.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 22b40e076c..9bdd57d200 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -158,7 +158,11 @@ NTSTATUS socket_recv(struct socket_context *sock, void *buf, } if ((sock->flags & SOCKET_FLAG_TESTNONBLOCK) && wantlen > 1) { - return sock->ops->recv(sock, buf, 1+(random() % (wantlen-1)), nread, flags); + if (random() % 10 == 0) { + *nread = 0; + return STATUS_MORE_ENTRIES; + } + return sock->ops->recv(sock, buf, 1+(random() % wantlen), nread, flags); } return sock->ops->recv(sock, buf, wantlen, nread, flags); @@ -182,7 +186,11 @@ NTSTATUS socket_send(struct socket_context *sock, if ((sock->flags & SOCKET_FLAG_TESTNONBLOCK) && blob->length > 1) { DATA_BLOB blob2 = *blob; - blob2.length = 1+(random() % (blob2.length-1)); + if (random() % 10 == 0) { + *sendlen = 0; + return STATUS_MORE_ENTRIES; + } + blob2.length = 1+(random() % blob2.length); return sock->ops->send(sock, &blob2, sendlen, flags); } -- cgit From bb69e3bbe62209b95f06d7d296b9c9015ab1c9b5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 28 Oct 2004 18:57:48 +0000 Subject: r3329: Add support for IPv6 (This used to be commit d8298901243ca4ce2ec420fa523c8e1407e72513) --- source4/lib/socket/socket.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 9bdd57d200..c3cacbebd8 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -267,6 +267,10 @@ const struct socket_ops *socket_getops_byname(const char *name, enum socket_type return socket_ipv4_ops(); } + if (strcmp("ipv6", name) == 0) { + return socket_ipv6_ops(); + } + if (strcmp("unix", name) == 0) { return socket_unixdom_ops(); } -- cgit From 148f07c94b885412250bba7d955c423adac2e5b9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 28 Oct 2004 21:36:27 +0000 Subject: r3333: added configure tests for ipv6 support (This used to be commit 9794570c6d0646cc34147bf8128802b181f658f0) --- source4/lib/socket/socket.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index c3cacbebd8..84bb1ccafe 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -267,9 +267,11 @@ const struct socket_ops *socket_getops_byname(const char *name, enum socket_type return socket_ipv4_ops(); } +#if HAVE_SOCKET_IPV6 if (strcmp("ipv6", name) == 0) { return socket_ipv6_ops(); } +#endif if (strcmp("unix", name) == 0) { return socket_unixdom_ops(); -- cgit From 08c4d0db0c22e6432e793f88bb93cf631f31ea20 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 28 Oct 2004 21:41:21 +0000 Subject: r3334: Allow disabling IPv6 support using socket:noipv6 (This used to be commit 9c13f42c1fd489a6a663f614a41c59730c18a054) --- source4/lib/socket/socket.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 84bb1ccafe..dbbae5ea7e 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -269,6 +269,10 @@ const struct socket_ops *socket_getops_byname(const char *name, enum socket_type #if HAVE_SOCKET_IPV6 if (strcmp("ipv6", name) == 0) { + if (lp_parm_bool(-1, "socket", "noipv6", False)) { + DEBUG(3, ("IPv6 support was disabled in smb.conf")); + return NULL; + } return socket_ipv6_ops(); } #endif -- cgit From 0caeda53d37740d18b38e6d37d0ecef8c6336820 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 29 Oct 2004 07:00:14 +0000 Subject: r3356: in the standard process model we need to make sure we close all listening sockets after the fork to prevent the child still listening on incoming requests. I have also added an optimisation where we use dup()/close() to lower the file descriptor number of the new socket to the lowest possible after closing our listening sockets. This keeps the max fd num passed to select() low, which makes a difference to the speed of select(). (This used to be commit f2a9bbc317ba86ebe87c3ca27a3a0192de91014d) --- source4/lib/socket/socket.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index dbbae5ea7e..892695f6eb 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -260,6 +260,28 @@ int socket_get_fd(struct socket_context *sock) return sock->ops->get_fd(sock); } +/* + call dup() on a socket, and close the old fd. This is used to change + the fd to the lowest available number, to make select() more + efficient (select speed depends on the maxiumum fd number passed to + it) +*/ +NTSTATUS socket_dup(struct socket_context *sock) +{ + int fd; + if (sock->fd == -1) { + return NT_STATUS_INVALID_HANDLE; + } + fd = dup(sock->fd); + if (fd == -1) { + return map_nt_error_from_unix(errno); + } + close(sock->fd); + sock->fd = fd; + return NT_STATUS_OK; + +} + const struct socket_ops *socket_getops_byname(const char *name, enum socket_type type) { if (strcmp("ip", name) == 0 || -- cgit From 452ddd94ba22bebe0fda5ee6a7ddceae2057fe40 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 02:01:04 +0000 Subject: r3450: portability fixes - fix rep_inet_ntoa() for IRIX - lib/signal.c needs system/wait.h - some systems define a macro "accept", which breaks the lib/socket/ structures. use fn_ as a prefix for the structure elements to avoid the problem (This used to be commit ced1a0fcdc8d8e47755ce4391c19f8b12862eb60) --- source4/lib/socket/socket.c | 58 ++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 29 deletions(-) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 892695f6eb..c2865cd9f0 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -26,8 +26,8 @@ static int socket_destructor(void *ptr) { struct socket_context *sock = ptr; - if (sock->ops->close) { - sock->ops->close(sock); + if (sock->ops->fn_close) { + sock->ops->fn_close(sock); } return 0; } @@ -54,7 +54,7 @@ NTSTATUS socket_create(const char *name, enum socket_type type, struct socket_co return NT_STATUS_INVALID_PARAMETER; } - status = (*new_sock)->ops->init((*new_sock)); + status = (*new_sock)->ops->fn_init((*new_sock)); if (!NT_STATUS_IS_OK(status)) { talloc_free(*new_sock); return status; @@ -92,11 +92,11 @@ NTSTATUS socket_connect(struct socket_context *sock, return NT_STATUS_INVALID_PARAMETER; } - if (!sock->ops->connect) { + if (!sock->ops->fn_connect) { return NT_STATUS_NOT_IMPLEMENTED; } - return sock->ops->connect(sock, my_address, my_port, server_address, server_port, flags); + return sock->ops->fn_connect(sock, my_address, my_port, server_address, server_port, flags); } NTSTATUS socket_listen(struct socket_context *sock, const char *my_address, int port, int queue_size, uint32_t flags) @@ -109,11 +109,11 @@ NTSTATUS socket_listen(struct socket_context *sock, const char *my_address, int return NT_STATUS_INVALID_PARAMETER; } - if (!sock->ops->listen) { + if (!sock->ops->fn_listen) { return NT_STATUS_NOT_IMPLEMENTED; } - return sock->ops->listen(sock, my_address, port, queue_size, flags); + return sock->ops->fn_listen(sock, my_address, port, queue_size, flags); } NTSTATUS socket_accept(struct socket_context *sock, struct socket_context **new_sock) @@ -128,11 +128,11 @@ NTSTATUS socket_accept(struct socket_context *sock, struct socket_context **new_ return NT_STATUS_INVALID_PARAMETER; } - if (!sock->ops->accept) { + if (!sock->ops->fn_accept) { return NT_STATUS_NOT_IMPLEMENTED; } - status = sock->ops->accept(sock, new_sock); + status = sock->ops->fn_accept(sock, new_sock); if (NT_STATUS_IS_OK(status)) { talloc_set_destructor(*new_sock, socket_destructor); @@ -153,7 +153,7 @@ NTSTATUS socket_recv(struct socket_context *sock, void *buf, return NT_STATUS_INVALID_PARAMETER; } - if (!sock->ops->recv) { + if (!sock->ops->fn_recv) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -162,10 +162,10 @@ NTSTATUS socket_recv(struct socket_context *sock, void *buf, *nread = 0; return STATUS_MORE_ENTRIES; } - return sock->ops->recv(sock, buf, 1+(random() % wantlen), nread, flags); + return sock->ops->fn_recv(sock, buf, 1+(random() % wantlen), nread, flags); } - return sock->ops->recv(sock, buf, wantlen, nread, flags); + return sock->ops->fn_recv(sock, buf, wantlen, nread, flags); } NTSTATUS socket_send(struct socket_context *sock, @@ -180,7 +180,7 @@ NTSTATUS socket_send(struct socket_context *sock, return NT_STATUS_INVALID_PARAMETER; } - if (!sock->ops->send) { + if (!sock->ops->fn_send) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -191,73 +191,73 @@ NTSTATUS socket_send(struct socket_context *sock, return STATUS_MORE_ENTRIES; } blob2.length = 1+(random() % blob2.length); - return sock->ops->send(sock, &blob2, sendlen, flags); + return sock->ops->fn_send(sock, &blob2, sendlen, flags); } - return sock->ops->send(sock, blob, sendlen, flags); + return sock->ops->fn_send(sock, blob, sendlen, flags); } NTSTATUS socket_set_option(struct socket_context *sock, const char *option, const char *val) { - if (!sock->ops->set_option) { + if (!sock->ops->fn_set_option) { return NT_STATUS_NOT_IMPLEMENTED; } - return sock->ops->set_option(sock, option, val); + return sock->ops->fn_set_option(sock, option, val); } char *socket_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ctx) { - if (!sock->ops->get_peer_name) { + if (!sock->ops->fn_get_peer_name) { return NULL; } - return sock->ops->get_peer_name(sock, mem_ctx); + return sock->ops->fn_get_peer_name(sock, mem_ctx); } char *socket_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) { - if (!sock->ops->get_peer_addr) { + if (!sock->ops->fn_get_peer_addr) { return NULL; } - return sock->ops->get_peer_addr(sock, mem_ctx); + return sock->ops->fn_get_peer_addr(sock, mem_ctx); } int socket_get_peer_port(struct socket_context *sock) { - if (!sock->ops->get_peer_port) { + if (!sock->ops->fn_get_peer_port) { return -1; } - return sock->ops->get_peer_port(sock); + return sock->ops->fn_get_peer_port(sock); } char *socket_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) { - if (!sock->ops->get_my_addr) { + if (!sock->ops->fn_get_my_addr) { return NULL; } - return sock->ops->get_my_addr(sock, mem_ctx); + return sock->ops->fn_get_my_addr(sock, mem_ctx); } int socket_get_my_port(struct socket_context *sock) { - if (!sock->ops->get_my_port) { + if (!sock->ops->fn_get_my_port) { return -1; } - return sock->ops->get_my_port(sock); + return sock->ops->fn_get_my_port(sock); } int socket_get_fd(struct socket_context *sock) { - if (!sock->ops->get_fd) { + if (!sock->ops->fn_get_fd) { return -1; } - return sock->ops->get_fd(sock); + return sock->ops->fn_get_fd(sock); } /* -- cgit From ffb8c82424a9d58a3dee1c42b7a64ab15711345b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 11 Jan 2005 15:19:32 +0000 Subject: r4686: cerate a function to create a socket by specifying an socket_ops struct metze (This used to be commit 894f402b01c8d4e0bef9c29697b8d13e5b9ea150) --- source4/lib/socket/socket.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index c2865cd9f0..9be6faf084 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -32,27 +32,23 @@ static int socket_destructor(void *ptr) return 0; } -NTSTATUS socket_create(const char *name, enum socket_type type, struct socket_context **new_sock, uint32_t flags) +NTSTATUS socket_create_with_ops(TALLOC_CTX *mem_ctx, const struct socket_ops *ops, struct socket_context **new_sock, uint32_t flags) { NTSTATUS status; - (*new_sock) = talloc_p(NULL, struct socket_context); + (*new_sock) = talloc(mem_ctx, struct socket_context); if (!(*new_sock)) { return NT_STATUS_NO_MEMORY; } - (*new_sock)->type = type; + (*new_sock)->type = ops->type; (*new_sock)->state = SOCKET_STATE_UNDEFINED; (*new_sock)->flags = flags; (*new_sock)->fd = -1; (*new_sock)->private_data = NULL; - (*new_sock)->ops = socket_getops_byname(name, type); - if (!(*new_sock)->ops) { - talloc_free(*new_sock); - return NT_STATUS_INVALID_PARAMETER; - } + (*new_sock)->ops = ops; status = (*new_sock)->ops->fn_init((*new_sock)); if (!NT_STATUS_IS_OK(status)) { @@ -73,6 +69,18 @@ NTSTATUS socket_create(const char *name, enum socket_type type, struct socket_co return NT_STATUS_OK; } +NTSTATUS socket_create(const char *name, enum socket_type type, struct socket_context **new_sock, uint32_t flags) +{ + const struct socket_ops *ops; + + ops = socket_getops_byname(name, type); + if (!ops) { + return NT_STATUS_INVALID_PARAMETER; + } + + return socket_create_with_ops(NULL, ops, new_sock, flags); +} + void socket_destroy(struct socket_context *sock) { /* the close is handled by the destructor */ -- cgit From 21aafc3536cb8a172805f0dd5d23b100f1ecb493 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 15 Jan 2005 10:28:08 +0000 Subject: r4753: added the ability for the generic socket library to handle async connect(). This required a small API change (the addition of a socket_connect_complete() method) (This used to be commit b787dd166f5cca82b3710802eefb41e0a8851fc3) --- source4/lib/socket/socket.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 9be6faf084..cc43348e79 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -107,6 +107,14 @@ NTSTATUS socket_connect(struct socket_context *sock, return sock->ops->fn_connect(sock, my_address, my_port, server_address, server_port, flags); } +NTSTATUS socket_connect_complete(struct socket_context *sock, uint32_t flags) +{ + if (!sock->ops->fn_connect_complete) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return sock->ops->fn_connect_complete(sock, flags); +} + NTSTATUS socket_listen(struct socket_context *sock, const char *my_address, int port, int queue_size, uint32_t flags) { if (sock->type != SOCKET_TYPE_STREAM) { -- cgit From 8783aa8ea57c3a6989e0722d5184e98d543352d4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 19 Jan 2005 03:20:20 +0000 Subject: r4831: added udp support to our generic sockets library. I decided to incorporate the udp support into the socket_ipv4.c backend (and later in socket_ipv6.c) rather than doing a separate backend, as so much of the code is shareable. Basically this adds a socket_sendto() and a socket_recvfrom() call and not much all. For udp servers, I decided to keep the call as socket_listen(), even though dgram servers don't actually call listen(). This keeps the API consistent. I also added a simple local sockets testsuite in smbtorture, LOCAL-SOCKET (This used to be commit 9f12a45a05c5c447fb4ec18c8dd28f70e90e32a5) --- source4/lib/socket/socket.c | 69 ++++++++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 22 deletions(-) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index cc43348e79..97176ea150 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -32,7 +32,9 @@ static int socket_destructor(void *ptr) return 0; } -NTSTATUS socket_create_with_ops(TALLOC_CTX *mem_ctx, const struct socket_ops *ops, struct socket_context **new_sock, uint32_t flags) +static NTSTATUS socket_create_with_ops(TALLOC_CTX *mem_ctx, const struct socket_ops *ops, + struct socket_context **new_sock, + enum socket_type type, uint32_t flags) { NTSTATUS status; @@ -41,7 +43,7 @@ NTSTATUS socket_create_with_ops(TALLOC_CTX *mem_ctx, const struct socket_ops *op return NT_STATUS_NO_MEMORY; } - (*new_sock)->type = ops->type; + (*new_sock)->type = type; (*new_sock)->state = SOCKET_STATE_UNDEFINED; (*new_sock)->flags = flags; @@ -60,6 +62,7 @@ NTSTATUS socket_create_with_ops(TALLOC_CTX *mem_ctx, const struct socket_ops *op send calls on non-blocking sockets will randomly recv/send less data than requested */ if (!(flags & SOCKET_FLAG_BLOCK) && + type == SOCKET_TYPE_STREAM && lp_parm_bool(-1, "socket", "testnonblock", False)) { (*new_sock)->flags |= SOCKET_FLAG_TESTNONBLOCK; } @@ -69,7 +72,8 @@ NTSTATUS socket_create_with_ops(TALLOC_CTX *mem_ctx, const struct socket_ops *op return NT_STATUS_OK; } -NTSTATUS socket_create(const char *name, enum socket_type type, struct socket_context **new_sock, uint32_t flags) +NTSTATUS socket_create(const char *name, enum socket_type type, + struct socket_context **new_sock, uint32_t flags) { const struct socket_ops *ops; @@ -78,7 +82,7 @@ NTSTATUS socket_create(const char *name, enum socket_type type, struct socket_co return NT_STATUS_INVALID_PARAMETER; } - return socket_create_with_ops(NULL, ops, new_sock, flags); + return socket_create_with_ops(NULL, ops, new_sock, type, flags); } void socket_destroy(struct socket_context *sock) @@ -92,10 +96,6 @@ NTSTATUS socket_connect(struct socket_context *sock, const char *server_address, int server_port, uint32_t flags) { - if (sock->type != SOCKET_TYPE_STREAM) { - return NT_STATUS_INVALID_PARAMETER; - } - if (sock->state != SOCKET_STATE_UNDEFINED) { return NT_STATUS_INVALID_PARAMETER; } @@ -117,10 +117,6 @@ NTSTATUS socket_connect_complete(struct socket_context *sock, uint32_t flags) NTSTATUS socket_listen(struct socket_context *sock, const char *my_address, int port, int queue_size, uint32_t flags) { - if (sock->type != SOCKET_TYPE_STREAM) { - return NT_STATUS_INVALID_PARAMETER; - } - if (sock->state != SOCKET_STATE_UNDEFINED) { return NT_STATUS_INVALID_PARAMETER; } @@ -160,10 +156,6 @@ NTSTATUS socket_accept(struct socket_context *sock, struct socket_context **new_ 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; - } - if (sock->state != SOCKET_STATE_CLIENT_CONNECTED && sock->state != SOCKET_STATE_SERVER_CONNECTED) { return NT_STATUS_INVALID_PARAMETER; @@ -184,13 +176,25 @@ NTSTATUS socket_recv(struct socket_context *sock, void *buf, return sock->ops->fn_recv(sock, buf, wantlen, nread, flags); } -NTSTATUS socket_send(struct socket_context *sock, - const DATA_BLOB *blob, size_t *sendlen, uint32_t flags) +NTSTATUS socket_recvfrom(struct socket_context *sock, void *buf, + size_t wantlen, size_t *nread, uint32_t flags, + const char **src_addr, int *src_port) { - if (sock->type != SOCKET_TYPE_STREAM) { + if (sock->type != SOCKET_TYPE_DGRAM) { return NT_STATUS_INVALID_PARAMETER; } + if (!sock->ops->fn_recvfrom) { + return NT_STATUS_NOT_IMPLEMENTED; + } + + return sock->ops->fn_recvfrom(sock, buf, wantlen, nread, flags, + src_addr, src_port); +} + +NTSTATUS socket_send(struct socket_context *sock, + const DATA_BLOB *blob, size_t *sendlen, uint32_t flags) +{ if (sock->state != SOCKET_STATE_CLIENT_CONNECTED && sock->state != SOCKET_STATE_SERVER_CONNECTED) { return NT_STATUS_INVALID_PARAMETER; @@ -213,6 +217,27 @@ NTSTATUS socket_send(struct socket_context *sock, return sock->ops->fn_send(sock, blob, sendlen, flags); } + +NTSTATUS socket_sendto(struct socket_context *sock, + const DATA_BLOB *blob, size_t *sendlen, uint32_t flags, + const char *dest_addr, int dest_port) +{ + if (sock->type != SOCKET_TYPE_DGRAM) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (sock->state == SOCKET_STATE_CLIENT_CONNECTED || + sock->state == SOCKET_STATE_SERVER_CONNECTED) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (!sock->ops->fn_sendto) { + return NT_STATUS_NOT_IMPLEMENTED; + } + + return sock->ops->fn_sendto(sock, blob, sendlen, flags, dest_addr, dest_port); +} + NTSTATUS socket_set_option(struct socket_context *sock, const char *option, const char *val) { if (!sock->ops->fn_set_option) { @@ -302,7 +327,7 @@ const struct socket_ops *socket_getops_byname(const char *name, enum socket_type { if (strcmp("ip", name) == 0 || strcmp("ipv4", name) == 0) { - return socket_ipv4_ops(); + return socket_ipv4_ops(type); } #if HAVE_SOCKET_IPV6 @@ -311,12 +336,12 @@ const struct socket_ops *socket_getops_byname(const char *name, enum socket_type DEBUG(3, ("IPv6 support was disabled in smb.conf")); return NULL; } - return socket_ipv6_ops(); + return socket_ipv6_ops(type); } #endif if (strcmp("unix", name) == 0) { - return socket_unixdom_ops(); + return socket_unixdom_ops(type); } return NULL; -- cgit From e82aad1ce39a6b7a2e51b9e2cb494d74ec70e158 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Feb 2005 05:09:35 +0000 Subject: r5298: - got rid of pstring.h from includes.h. This at least makes it a bit less likely that anyone will use pstring for new code - got rid of winbind_client.h from includes.h. This one triggered a huge change, as winbind_client.h was including system/filesys.h and defining the old uint32 and uint16 types, as well as its own pstring and fstring. (This used to be commit 9db6c79e902ec538108d6b7d3324039aabe1704f) --- source4/lib/socket/socket.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 97176ea150..109a7cadc0 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "system/filesys.h" /* auto-close sockets on free -- cgit From bed7c9ec32b7d4083ba4ed2abbf3b6126bee7a25 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Feb 2005 06:59:29 +0000 Subject: r5304: removed lib/socket/socket.h from includes.h (This used to be commit b902ea546d2d1327b23f40ddaeeaa8e7e3662454) --- source4/lib/socket/socket.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 109a7cadc0..ddc2097f42 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "lib/socket/socket.h" #include "system/filesys.h" /* @@ -326,6 +327,10 @@ NTSTATUS socket_dup(struct socket_context *sock) const struct socket_ops *socket_getops_byname(const char *name, enum socket_type type) { + extern const struct socket_ops *socket_ipv4_ops(enum socket_type ); + extern const struct socket_ops *socket_ipv6_ops(enum socket_type ); + extern const struct socket_ops *socket_unixdom_ops(enum socket_type ); + if (strcmp("ip", name) == 0 || strcmp("ipv4", name) == 0) { return socket_ipv4_ops(type); -- cgit From b2584a403c6382ef478755979d955043fc9569a1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 1 May 2005 18:49:43 +0000 Subject: r6562: added support for datagram unix domain sockets in the socket library (This used to be commit 23b2046dcb5c4593cba6964f400a2e5246fb35f7) --- source4/lib/socket/socket.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index ddc2097f42..86e2f05962 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -159,7 +159,8 @@ NTSTATUS socket_recv(struct socket_context *sock, void *buf, size_t wantlen, size_t *nread, uint32_t flags) { if (sock->state != SOCKET_STATE_CLIENT_CONNECTED && - sock->state != SOCKET_STATE_SERVER_CONNECTED) { + sock->state != SOCKET_STATE_SERVER_CONNECTED && + sock->type != SOCKET_TYPE_DGRAM) { return NT_STATUS_INVALID_PARAMETER; } -- cgit From 5b18cf22680c76abb1262a6b75a30b8a37899467 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 15 May 2005 20:16:26 +0000 Subject: r6795: Make some functions static and remove some unused ones. (This used to be commit 46509eb89980bfe6dabd71264d570ea356ee5a22) --- source4/lib/socket/socket.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 86e2f05962..13d1640f51 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -87,12 +87,6 @@ NTSTATUS socket_create(const char *name, enum socket_type type, return socket_create_with_ops(NULL, ops, new_sock, type, flags); } -void socket_destroy(struct socket_context *sock) -{ - /* the close is handled by the destructor */ - talloc_free(sock); -} - NTSTATUS socket_connect(struct socket_context *sock, const char *my_address, int my_port, const char *server_address, int server_port, -- cgit From 1692bbf2e267eabd7099f0b6153da0c7cf209d1d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 3 Jun 2005 13:20:08 +0000 Subject: r7227: added a socket_pending() call to abstract away the FIONREAD ioctl. It will be interesting to see if this causes any portability problems, as it is a less commonly used call. (This used to be commit f6993db31d93059c70b44a23005ba444e205870f) --- source4/lib/socket/socket.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 13d1640f51..dd3175468d 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -235,6 +235,22 @@ NTSTATUS socket_sendto(struct socket_context *sock, return sock->ops->fn_sendto(sock, blob, sendlen, flags, dest_addr, dest_port); } + +/* + ask for the number of bytes in a pending incoming datagram +*/ +NTSTATUS socket_pending(struct socket_context *sock, size_t *npending) +{ + if (sock->type != SOCKET_TYPE_DGRAM) { + return NT_STATUS_INVALID_PARAMETER; + } + if (!sock->ops->fn_pending) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return sock->ops->fn_pending(sock, npending); +} + + NTSTATUS socket_set_option(struct socket_context *sock, const char *option, const char *val) { if (!sock->ops->fn_set_option) { -- cgit From b1b134084f96ba0765241091c47c6187f57f9867 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 11 Jun 2005 02:26:53 +0000 Subject: r7476: ensure dgram sockets are created non-blocking. As they usually skip the connect() stage, we were missing this (This used to be commit f5102b886c10fead0f6bcdc4460584ae53912ebc) --- source4/lib/socket/socket.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index dd3175468d..39379be678 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -69,6 +69,12 @@ static NTSTATUS socket_create_with_ops(TALLOC_CTX *mem_ctx, const struct socket_ (*new_sock)->flags |= SOCKET_FLAG_TESTNONBLOCK; } + /* we don't do a connect() on dgram sockets, so need to set + non-blocking at socket create time */ + if (!(flags & SOCKET_FLAG_BLOCK) && type == SOCKET_TYPE_DGRAM) { + set_blocking(socket_get_fd(*new_sock), False); + } + talloc_set_destructor(*new_sock, socket_destructor); return NT_STATUS_OK; -- cgit From bab977dad76e9204278c7afe0bb905cda064f488 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 16 Jun 2005 05:39:40 +0000 Subject: r7626: a new ldap client library. Main features are: - hooked into events system, so requests can be truly async and won't interfere with other processing happening at the same time - uses NTSTATUS codes for errors (previously errors were mostly ignored). In a similar fashion to the DOS error handling, I have reserved a range of the NTSTATUS code 32 bit space for LDAP error codes, so a function can return a LDAP error code in a NTSTATUS - much cleaner packet handling (This used to be commit 2e3c660b2fc20e046d82bf1cc296422b6e7dfad0) --- source4/lib/socket/socket.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 39379be678..9d5b67a966 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -243,13 +243,10 @@ NTSTATUS socket_sendto(struct socket_context *sock, /* - ask for the number of bytes in a pending incoming datagram + ask for the number of bytes in a pending incoming packet */ NTSTATUS socket_pending(struct socket_context *sock, size_t *npending) { - if (sock->type != SOCKET_TYPE_DGRAM) { - return NT_STATUS_INVALID_PARAMETER; - } if (!sock->ops->fn_pending) { return NT_STATUS_NOT_IMPLEMENTED; } -- cgit From d1291dacbd8c5e736e7d8288fb00b5368288b711 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 13 Jul 2005 03:25:36 +0000 Subject: r8408: its quite common in our code to free up a connection when we get an error, but sometimes a socket option may then happen on the NULL socket. This has been handled by the individual libraries up to now, but its cleaner to centralise it here (This used to be commit d9864e1f9aac1fb19f054c2da996a5099e90941e) --- source4/lib/socket/socket.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 9d5b67a966..db249522a2 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -98,6 +98,9 @@ NTSTATUS socket_connect(struct socket_context *sock, const char *server_address, int server_port, uint32_t flags) { + if (sock == NULL) { + return NT_STATUS_CONNECTION_DISCONNECTED; + } if (sock->state != SOCKET_STATE_UNDEFINED) { return NT_STATUS_INVALID_PARAMETER; } @@ -119,6 +122,9 @@ NTSTATUS socket_connect_complete(struct socket_context *sock, uint32_t flags) NTSTATUS socket_listen(struct socket_context *sock, const char *my_address, int port, int queue_size, uint32_t flags) { + if (sock == NULL) { + return NT_STATUS_CONNECTION_DISCONNECTED; + } if (sock->state != SOCKET_STATE_UNDEFINED) { return NT_STATUS_INVALID_PARAMETER; } @@ -134,6 +140,9 @@ NTSTATUS socket_accept(struct socket_context *sock, struct socket_context **new_ { NTSTATUS status; + if (sock == NULL) { + return NT_STATUS_CONNECTION_DISCONNECTED; + } if (sock->type != SOCKET_TYPE_STREAM) { return NT_STATUS_INVALID_PARAMETER; } @@ -158,6 +167,9 @@ NTSTATUS socket_accept(struct socket_context *sock, struct socket_context **new_ NTSTATUS socket_recv(struct socket_context *sock, void *buf, size_t wantlen, size_t *nread, uint32_t flags) { + if (sock == NULL) { + return NT_STATUS_CONNECTION_DISCONNECTED; + } if (sock->state != SOCKET_STATE_CLIENT_CONNECTED && sock->state != SOCKET_STATE_SERVER_CONNECTED && sock->type != SOCKET_TYPE_DGRAM) { @@ -183,6 +195,9 @@ NTSTATUS socket_recvfrom(struct socket_context *sock, void *buf, size_t wantlen, size_t *nread, uint32_t flags, const char **src_addr, int *src_port) { + if (sock == NULL) { + return NT_STATUS_CONNECTION_DISCONNECTED; + } if (sock->type != SOCKET_TYPE_DGRAM) { return NT_STATUS_INVALID_PARAMETER; } @@ -198,6 +213,9 @@ NTSTATUS socket_recvfrom(struct socket_context *sock, void *buf, NTSTATUS socket_send(struct socket_context *sock, const DATA_BLOB *blob, size_t *sendlen, uint32_t flags) { + if (sock == NULL) { + return NT_STATUS_CONNECTION_DISCONNECTED; + } if (sock->state != SOCKET_STATE_CLIENT_CONNECTED && sock->state != SOCKET_STATE_SERVER_CONNECTED) { return NT_STATUS_INVALID_PARAMETER; @@ -225,6 +243,9 @@ NTSTATUS socket_sendto(struct socket_context *sock, const DATA_BLOB *blob, size_t *sendlen, uint32_t flags, const char *dest_addr, int dest_port) { + if (sock == NULL) { + return NT_STATUS_CONNECTION_DISCONNECTED; + } if (sock->type != SOCKET_TYPE_DGRAM) { return NT_STATUS_INVALID_PARAMETER; } @@ -247,6 +268,9 @@ NTSTATUS socket_sendto(struct socket_context *sock, */ NTSTATUS socket_pending(struct socket_context *sock, size_t *npending) { + if (sock == NULL) { + return NT_STATUS_CONNECTION_DISCONNECTED; + } if (!sock->ops->fn_pending) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -256,6 +280,9 @@ NTSTATUS socket_pending(struct socket_context *sock, size_t *npending) NTSTATUS socket_set_option(struct socket_context *sock, const char *option, const char *val) { + if (sock == NULL) { + return NT_STATUS_CONNECTION_DISCONNECTED; + } if (!sock->ops->fn_set_option) { return NT_STATUS_NOT_IMPLEMENTED; } -- cgit From 1ef362c89d98777651c8789af4b74a0a6fb9fcdc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 28 Aug 2005 02:37:49 +0000 Subject: r9705: r9685@blu: tridge | 2005-08-27 19:43:44 +1000 set the backend_name on socket_accept() too (This used to be commit 10ac2732881ac73dd9cb8162beb1efd741bfe3d2) --- source4/lib/socket/socket.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index db249522a2..380071f46d 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -53,6 +53,7 @@ static NTSTATUS socket_create_with_ops(TALLOC_CTX *mem_ctx, const struct socket_ (*new_sock)->private_data = NULL; (*new_sock)->ops = ops; + (*new_sock)->backend_name = NULL; status = (*new_sock)->ops->fn_init((*new_sock)); if (!NT_STATUS_IS_OK(status)) { -- cgit From f55ea8bb3dca868e21663cd90eaea7a35cd7886c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 9 Jan 2006 22:12:53 +0000 Subject: r12804: This patch reworks the Samba4 sockets layer to use a socket_address structure that is more generic than just 'IP/port'. It now passes make test, and has been reviewed and updated by metze. (Thankyou *very* much). This passes 'make test' as well as kerberos use (not currently in the testsuite). The original purpose of this patch was to have Samba able to pass a socket address stucture from the BSD layer into the kerberos routines and back again. It also removes nbt_peer_addr, which was being used for a similar purpose. It is a large change, but worthwhile I feel. Andrew Bartlett (This used to be commit 88198c4881d8620a37086f80e4da5a5b71c5bbb2) --- source4/lib/socket/socket.c | 103 +++++++++++++++++++++++++++++--------------- 1 file changed, 69 insertions(+), 34 deletions(-) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 380071f46d..23117f2fa9 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -95,8 +95,8 @@ NTSTATUS socket_create(const char *name, enum socket_type type, } NTSTATUS socket_connect(struct socket_context *sock, - const char *my_address, int my_port, - const char *server_address, int server_port, + const struct socket_address *my_address, + const struct socket_address *server_address, uint32_t flags) { if (sock == NULL) { @@ -110,7 +110,7 @@ NTSTATUS socket_connect(struct socket_context *sock, return NT_STATUS_NOT_IMPLEMENTED; } - return sock->ops->fn_connect(sock, my_address, my_port, server_address, server_port, flags); + return sock->ops->fn_connect(sock, my_address, server_address, flags); } NTSTATUS socket_connect_complete(struct socket_context *sock, uint32_t flags) @@ -121,7 +121,9 @@ NTSTATUS socket_connect_complete(struct socket_context *sock, uint32_t flags) return sock->ops->fn_connect_complete(sock, flags); } -NTSTATUS socket_listen(struct socket_context *sock, const char *my_address, int port, int queue_size, uint32_t flags) +NTSTATUS socket_listen(struct socket_context *sock, + const struct socket_address *my_address, + int queue_size, uint32_t flags) { if (sock == NULL) { return NT_STATUS_CONNECTION_DISCONNECTED; @@ -134,7 +136,7 @@ NTSTATUS socket_listen(struct socket_context *sock, const char *my_address, int return NT_STATUS_NOT_IMPLEMENTED; } - return sock->ops->fn_listen(sock, my_address, port, queue_size, flags); + return sock->ops->fn_listen(sock, my_address, queue_size, flags); } NTSTATUS socket_accept(struct socket_context *sock, struct socket_context **new_sock) @@ -194,7 +196,7 @@ NTSTATUS socket_recv(struct socket_context *sock, void *buf, NTSTATUS socket_recvfrom(struct socket_context *sock, void *buf, size_t wantlen, size_t *nread, uint32_t flags, - const char **src_addr, int *src_port) + TALLOC_CTX *mem_ctx, struct socket_address **src_addr) { if (sock == NULL) { return NT_STATUS_CONNECTION_DISCONNECTED; @@ -208,7 +210,7 @@ NTSTATUS socket_recvfrom(struct socket_context *sock, void *buf, } return sock->ops->fn_recvfrom(sock, buf, wantlen, nread, flags, - src_addr, src_port); + mem_ctx, src_addr); } NTSTATUS socket_send(struct socket_context *sock, @@ -242,7 +244,7 @@ NTSTATUS socket_send(struct socket_context *sock, NTSTATUS socket_sendto(struct socket_context *sock, const DATA_BLOB *blob, size_t *sendlen, uint32_t flags, - const char *dest_addr, int dest_port) + const struct socket_address *dest_addr) { if (sock == NULL) { return NT_STATUS_CONNECTION_DISCONNECTED; @@ -260,7 +262,7 @@ NTSTATUS socket_sendto(struct socket_context *sock, return NT_STATUS_NOT_IMPLEMENTED; } - return sock->ops->fn_sendto(sock, blob, sendlen, flags, dest_addr, dest_port); + return sock->ops->fn_sendto(sock, blob, sendlen, flags, dest_addr); } @@ -300,7 +302,7 @@ char *socket_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ctx) return sock->ops->fn_get_peer_name(sock, mem_ctx); } -char *socket_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) +struct socket_address *socket_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) { if (!sock->ops->fn_get_peer_addr) { return NULL; @@ -309,16 +311,7 @@ char *socket_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) return sock->ops->fn_get_peer_addr(sock, mem_ctx); } -int socket_get_peer_port(struct socket_context *sock) -{ - if (!sock->ops->fn_get_peer_port) { - return -1; - } - - return sock->ops->fn_get_peer_port(sock); -} - -char *socket_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) +struct socket_address *socket_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) { if (!sock->ops->fn_get_my_addr) { return NULL; @@ -327,15 +320,6 @@ char *socket_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) return sock->ops->fn_get_my_addr(sock, mem_ctx); } -int socket_get_my_port(struct socket_context *sock) -{ - if (!sock->ops->fn_get_my_port) { - return -1; - } - - return sock->ops->fn_get_my_port(sock); -} - int socket_get_fd(struct socket_context *sock) { if (!sock->ops->fn_get_fd) { @@ -367,19 +351,70 @@ NTSTATUS socket_dup(struct socket_context *sock) } -const struct socket_ops *socket_getops_byname(const char *name, enum socket_type type) +/* Create a new socket_address. The type must match the socket type. + * The host parameter may be an IP or a hostname + */ + +struct socket_address *socket_address_from_strings(TALLOC_CTX *mem_ctx, + const char *family, + const char *host, + int port) +{ + struct socket_address *addr = talloc(mem_ctx, struct socket_address); + if (!addr) { + return NULL; + } + + addr->family = family; + addr->addr = talloc_strdup(addr, host); + if (!addr->addr) { + talloc_free(addr); + return NULL; + } + addr->port = port; + addr->sockaddr = NULL; + addr->sockaddrlen = 0; + + return addr; +} + +/* Create a new socket_address. Copy the struct sockaddr into the new + * structure. Used for hooks in the kerberos libraries, where they + * supply only a struct sockaddr */ + +struct socket_address *socket_address_from_sockaddr(TALLOC_CTX *mem_ctx, + struct sockaddr *sockaddr, + size_t sockaddrlen) +{ + struct socket_address *addr = talloc(mem_ctx, struct socket_address); + if (!addr) { + return NULL; + } + addr->family = NULL; + addr->addr = NULL; + addr->port = 0; + addr->sockaddr = talloc_memdup(addr, sockaddr, sockaddrlen); + if (!addr->sockaddr) { + talloc_free(addr); + return NULL; + } + addr->sockaddrlen = sockaddrlen; + return addr; +} + +const struct socket_ops *socket_getops_byname(const char *family, enum socket_type type) { extern const struct socket_ops *socket_ipv4_ops(enum socket_type ); extern const struct socket_ops *socket_ipv6_ops(enum socket_type ); extern const struct socket_ops *socket_unixdom_ops(enum socket_type ); - if (strcmp("ip", name) == 0 || - strcmp("ipv4", name) == 0) { + if (strcmp("ip", family) == 0 || + strcmp("ipv4", family) == 0) { return socket_ipv4_ops(type); } #if HAVE_SOCKET_IPV6 - if (strcmp("ipv6", name) == 0) { + if (strcmp("ipv6", family) == 0) { if (lp_parm_bool(-1, "socket", "noipv6", False)) { DEBUG(3, ("IPv6 support was disabled in smb.conf")); return NULL; @@ -388,7 +423,7 @@ const struct socket_ops *socket_getops_byname(const char *name, enum socket_type } #endif - if (strcmp("unix", name) == 0) { + if (strcmp("unix", family) == 0) { return socket_unixdom_ops(type); } -- cgit From bdfbcf5d8afad8ad1b088fea44bc03334def089e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Mar 2006 16:28:39 +0000 Subject: r13956: make more functions public metze (This used to be commit d099282d4956e7dc1134abf0632b01c40160e114) --- source4/lib/socket/socket.c | 78 ++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 39 deletions(-) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 23117f2fa9..3c9524a162 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -81,8 +81,8 @@ static NTSTATUS socket_create_with_ops(TALLOC_CTX *mem_ctx, const struct socket_ return NT_STATUS_OK; } -NTSTATUS socket_create(const char *name, enum socket_type type, - struct socket_context **new_sock, uint32_t flags) +_PUBLIC_ NTSTATUS socket_create(const char *name, enum socket_type type, + struct socket_context **new_sock, uint32_t flags) { const struct socket_ops *ops; @@ -94,10 +94,10 @@ NTSTATUS socket_create(const char *name, enum socket_type type, return socket_create_with_ops(NULL, ops, new_sock, type, flags); } -NTSTATUS socket_connect(struct socket_context *sock, - const struct socket_address *my_address, - const struct socket_address *server_address, - uint32_t flags) +_PUBLIC_ NTSTATUS socket_connect(struct socket_context *sock, + const struct socket_address *my_address, + const struct socket_address *server_address, + uint32_t flags) { if (sock == NULL) { return NT_STATUS_CONNECTION_DISCONNECTED; @@ -113,7 +113,7 @@ NTSTATUS socket_connect(struct socket_context *sock, return sock->ops->fn_connect(sock, my_address, server_address, flags); } -NTSTATUS socket_connect_complete(struct socket_context *sock, uint32_t flags) +_PUBLIC_ NTSTATUS socket_connect_complete(struct socket_context *sock, uint32_t flags) { if (!sock->ops->fn_connect_complete) { return NT_STATUS_NOT_IMPLEMENTED; @@ -121,9 +121,9 @@ NTSTATUS socket_connect_complete(struct socket_context *sock, uint32_t flags) return sock->ops->fn_connect_complete(sock, flags); } -NTSTATUS socket_listen(struct socket_context *sock, - const struct socket_address *my_address, - int queue_size, uint32_t flags) +_PUBLIC_ NTSTATUS socket_listen(struct socket_context *sock, + const struct socket_address *my_address, + int queue_size, uint32_t flags) { if (sock == NULL) { return NT_STATUS_CONNECTION_DISCONNECTED; @@ -139,7 +139,7 @@ NTSTATUS socket_listen(struct socket_context *sock, return sock->ops->fn_listen(sock, my_address, queue_size, flags); } -NTSTATUS socket_accept(struct socket_context *sock, struct socket_context **new_sock) +_PUBLIC_ NTSTATUS socket_accept(struct socket_context *sock, struct socket_context **new_sock) { NTSTATUS status; @@ -167,8 +167,8 @@ NTSTATUS socket_accept(struct socket_context *sock, struct socket_context **new_ return status; } -NTSTATUS socket_recv(struct socket_context *sock, void *buf, - size_t wantlen, size_t *nread, uint32_t flags) +_PUBLIC_ NTSTATUS socket_recv(struct socket_context *sock, void *buf, + size_t wantlen, size_t *nread, uint32_t flags) { if (sock == NULL) { return NT_STATUS_CONNECTION_DISCONNECTED; @@ -194,9 +194,9 @@ NTSTATUS socket_recv(struct socket_context *sock, void *buf, return sock->ops->fn_recv(sock, buf, wantlen, nread, flags); } -NTSTATUS socket_recvfrom(struct socket_context *sock, void *buf, - size_t wantlen, size_t *nread, uint32_t flags, - TALLOC_CTX *mem_ctx, struct socket_address **src_addr) +_PUBLIC_ NTSTATUS socket_recvfrom(struct socket_context *sock, void *buf, + size_t wantlen, size_t *nread, uint32_t flags, + TALLOC_CTX *mem_ctx, struct socket_address **src_addr) { if (sock == NULL) { return NT_STATUS_CONNECTION_DISCONNECTED; @@ -213,8 +213,8 @@ NTSTATUS socket_recvfrom(struct socket_context *sock, void *buf, mem_ctx, src_addr); } -NTSTATUS socket_send(struct socket_context *sock, - const DATA_BLOB *blob, size_t *sendlen, uint32_t flags) +_PUBLIC_ NTSTATUS socket_send(struct socket_context *sock, + const DATA_BLOB *blob, size_t *sendlen, uint32_t flags) { if (sock == NULL) { return NT_STATUS_CONNECTION_DISCONNECTED; @@ -242,9 +242,9 @@ NTSTATUS socket_send(struct socket_context *sock, } -NTSTATUS socket_sendto(struct socket_context *sock, - const DATA_BLOB *blob, size_t *sendlen, uint32_t flags, - const struct socket_address *dest_addr) +_PUBLIC_ NTSTATUS socket_sendto(struct socket_context *sock, + const DATA_BLOB *blob, size_t *sendlen, uint32_t flags, + const struct socket_address *dest_addr) { if (sock == NULL) { return NT_STATUS_CONNECTION_DISCONNECTED; @@ -269,7 +269,7 @@ NTSTATUS socket_sendto(struct socket_context *sock, /* ask for the number of bytes in a pending incoming packet */ -NTSTATUS socket_pending(struct socket_context *sock, size_t *npending) +_PUBLIC_ NTSTATUS socket_pending(struct socket_context *sock, size_t *npending) { if (sock == NULL) { return NT_STATUS_CONNECTION_DISCONNECTED; @@ -281,7 +281,7 @@ NTSTATUS socket_pending(struct socket_context *sock, size_t *npending) } -NTSTATUS socket_set_option(struct socket_context *sock, const char *option, const char *val) +_PUBLIC_ NTSTATUS socket_set_option(struct socket_context *sock, const char *option, const char *val) { if (sock == NULL) { return NT_STATUS_CONNECTION_DISCONNECTED; @@ -293,7 +293,7 @@ NTSTATUS socket_set_option(struct socket_context *sock, const char *option, cons return sock->ops->fn_set_option(sock, option, val); } -char *socket_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ctx) +_PUBLIC_ char *socket_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ctx) { if (!sock->ops->fn_get_peer_name) { return NULL; @@ -302,7 +302,7 @@ char *socket_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ctx) return sock->ops->fn_get_peer_name(sock, mem_ctx); } -struct socket_address *socket_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) +_PUBLIC_ struct socket_address *socket_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) { if (!sock->ops->fn_get_peer_addr) { return NULL; @@ -311,7 +311,7 @@ struct socket_address *socket_get_peer_addr(struct socket_context *sock, TALLOC_ return sock->ops->fn_get_peer_addr(sock, mem_ctx); } -struct socket_address *socket_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) +_PUBLIC_ struct socket_address *socket_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) { if (!sock->ops->fn_get_my_addr) { return NULL; @@ -320,7 +320,7 @@ struct socket_address *socket_get_my_addr(struct socket_context *sock, TALLOC_CT return sock->ops->fn_get_my_addr(sock, mem_ctx); } -int socket_get_fd(struct socket_context *sock) +_PUBLIC_ int socket_get_fd(struct socket_context *sock) { if (!sock->ops->fn_get_fd) { return -1; @@ -335,7 +335,7 @@ int socket_get_fd(struct socket_context *sock) efficient (select speed depends on the maxiumum fd number passed to it) */ -NTSTATUS socket_dup(struct socket_context *sock) +_PUBLIC_ NTSTATUS socket_dup(struct socket_context *sock) { int fd; if (sock->fd == -1) { @@ -355,10 +355,10 @@ NTSTATUS socket_dup(struct socket_context *sock) * The host parameter may be an IP or a hostname */ -struct socket_address *socket_address_from_strings(TALLOC_CTX *mem_ctx, - const char *family, - const char *host, - int port) +_PUBLIC_ struct socket_address *socket_address_from_strings(TALLOC_CTX *mem_ctx, + const char *family, + const char *host, + int port) { struct socket_address *addr = talloc(mem_ctx, struct socket_address); if (!addr) { @@ -382,9 +382,9 @@ struct socket_address *socket_address_from_strings(TALLOC_CTX *mem_ctx, * structure. Used for hooks in the kerberos libraries, where they * supply only a struct sockaddr */ -struct socket_address *socket_address_from_sockaddr(TALLOC_CTX *mem_ctx, - struct sockaddr *sockaddr, - size_t sockaddrlen) +_PUBLIC_ struct socket_address *socket_address_from_sockaddr(TALLOC_CTX *mem_ctx, + struct sockaddr *sockaddr, + size_t sockaddrlen) { struct socket_address *addr = talloc(mem_ctx, struct socket_address); if (!addr) { @@ -402,11 +402,11 @@ struct socket_address *socket_address_from_sockaddr(TALLOC_CTX *mem_ctx, return addr; } -const struct socket_ops *socket_getops_byname(const char *family, enum socket_type type) +_PUBLIC_ const struct socket_ops *socket_getops_byname(const char *family, enum socket_type type) { - extern const struct socket_ops *socket_ipv4_ops(enum socket_type ); - extern const struct socket_ops *socket_ipv6_ops(enum socket_type ); - extern const struct socket_ops *socket_unixdom_ops(enum socket_type ); + extern const struct socket_ops *socket_ipv4_ops(enum socket_type); + extern const struct socket_ops *socket_ipv6_ops(enum socket_type); + extern const struct socket_ops *socket_unixdom_ops(enum socket_type); if (strcmp("ip", family) == 0 || strcmp("ipv4", family) == 0) { -- cgit From f4e403440a08f5da3328bbbe5601967bf8705137 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 30 Apr 2006 01:32:59 +0000 Subject: r15349: Integrate set_socket_options() into the socket library (This used to be commit 598ea173cd718dad0df24505796ca50cb728a2e9) --- source4/lib/socket/socket.c | 108 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 3c9524a162..9d18377db1 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -1,6 +1,8 @@ /* Unix SMB/CIFS implementation. Socket functions + Copyright (C) Andrew Tridgell 1992-1998 + Copyright (C) Tim Potter 2000-2001 Copyright (C) Stefan Metzmacher 2004 This program is free software; you can redistribute it and/or modify @@ -21,6 +23,7 @@ #include "includes.h" #include "lib/socket/socket.h" #include "system/filesys.h" +#include "system/network.h" /* auto-close sockets on free @@ -429,3 +432,108 @@ _PUBLIC_ const struct socket_ops *socket_getops_byname(const char *family, enum return NULL; } + +enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON}; + +static const struct { + const char *name; + int level; + int option; + int value; + int opttype; +} socket_options[] = { + {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL}, + {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL}, + {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL}, +#ifdef TCP_NODELAY + {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL}, +#endif +#ifdef IPTOS_LOWDELAY + {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON}, +#endif +#ifdef IPTOS_THROUGHPUT + {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON}, +#endif +#ifdef SO_REUSEPORT + {"SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT, 0, OPT_BOOL}, +#endif +#ifdef SO_SNDBUF + {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT}, +#endif +#ifdef SO_RCVBUF + {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT}, +#endif +#ifdef SO_SNDLOWAT + {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT}, +#endif +#ifdef SO_RCVLOWAT + {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT}, +#endif +#ifdef SO_SNDTIMEO + {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT}, +#endif +#ifdef SO_RCVTIMEO + {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT}, +#endif + {NULL,0,0,0,0}}; + + +/** + Set user socket options. +**/ +_PUBLIC_ void set_socket_options(int fd, const char *options) +{ + const char **options_list = str_list_make(NULL, options, " \t,"); + int j; + + if (!options_list) + return; + + for (j = 0; options_list[j]; j++) { + const char *tok = options_list[j]; + int ret=0,i; + int value = 1; + char *p; + BOOL got_value = False; + + if ((p = strchr(tok,'='))) { + *p = 0; + value = atoi(p+1); + got_value = True; + } + + for (i=0;socket_options[i].name;i++) + if (strequal(socket_options[i].name,tok)) + break; + + if (!socket_options[i].name) { + DEBUG(0,("Unknown socket option %s\n",tok)); + continue; + } + + switch (socket_options[i].opttype) { + case OPT_BOOL: + case OPT_INT: + ret = setsockopt(fd,socket_options[i].level, + socket_options[i].option,(char *)&value,sizeof(int)); + break; + + case OPT_ON: + if (got_value) + DEBUG(0,("syntax error - %s does not take a value\n",tok)); + + { + int on = socket_options[i].value; + ret = setsockopt(fd,socket_options[i].level, + socket_options[i].option,(char *)&on,sizeof(int)); + } + break; + } + + if (ret != 0) + DEBUG(0,("Failed to set socket option %s (Error %s)\n",tok, strerror(errno) )); + } + + talloc_free(options_list); +} + -- cgit From c2cc10c7869221c7f43cbbb151feb4c4db173cb9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 30 Apr 2006 05:58:31 +0000 Subject: r15356: Remove unused 'flags' argument from socket_send() and friends. This is in preperation for making TLS a socket library. Andrew Bartlett (This used to be commit a312812b92f5ac7e6bd2c4af725dbbbc900d4452) --- source4/lib/socket/socket.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 9d18377db1..4f7f4ef4b9 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -171,7 +171,7 @@ _PUBLIC_ NTSTATUS socket_accept(struct socket_context *sock, struct socket_conte } _PUBLIC_ NTSTATUS socket_recv(struct socket_context *sock, void *buf, - size_t wantlen, size_t *nread, uint32_t flags) + size_t wantlen, size_t *nread) { if (sock == NULL) { return NT_STATUS_CONNECTION_DISCONNECTED; @@ -191,14 +191,14 @@ _PUBLIC_ NTSTATUS socket_recv(struct socket_context *sock, void *buf, *nread = 0; return STATUS_MORE_ENTRIES; } - return sock->ops->fn_recv(sock, buf, 1+(random() % wantlen), nread, flags); + return sock->ops->fn_recv(sock, buf, 1+(random() % wantlen), nread); } - return sock->ops->fn_recv(sock, buf, wantlen, nread, flags); + return sock->ops->fn_recv(sock, buf, wantlen, nread); } _PUBLIC_ NTSTATUS socket_recvfrom(struct socket_context *sock, void *buf, - size_t wantlen, size_t *nread, uint32_t flags, + size_t wantlen, size_t *nread, TALLOC_CTX *mem_ctx, struct socket_address **src_addr) { if (sock == NULL) { @@ -212,12 +212,12 @@ _PUBLIC_ NTSTATUS socket_recvfrom(struct socket_context *sock, void *buf, return NT_STATUS_NOT_IMPLEMENTED; } - return sock->ops->fn_recvfrom(sock, buf, wantlen, nread, flags, + return sock->ops->fn_recvfrom(sock, buf, wantlen, nread, mem_ctx, src_addr); } _PUBLIC_ NTSTATUS socket_send(struct socket_context *sock, - const DATA_BLOB *blob, size_t *sendlen, uint32_t flags) + const DATA_BLOB *blob, size_t *sendlen) { if (sock == NULL) { return NT_STATUS_CONNECTION_DISCONNECTED; @@ -238,15 +238,15 @@ _PUBLIC_ NTSTATUS socket_send(struct socket_context *sock, return STATUS_MORE_ENTRIES; } blob2.length = 1+(random() % blob2.length); - return sock->ops->fn_send(sock, &blob2, sendlen, flags); + return sock->ops->fn_send(sock, &blob2, sendlen); } - return sock->ops->fn_send(sock, blob, sendlen, flags); + return sock->ops->fn_send(sock, blob, sendlen); } _PUBLIC_ NTSTATUS socket_sendto(struct socket_context *sock, - const DATA_BLOB *blob, size_t *sendlen, uint32_t flags, + const DATA_BLOB *blob, size_t *sendlen, const struct socket_address *dest_addr) { if (sock == NULL) { @@ -265,7 +265,7 @@ _PUBLIC_ NTSTATUS socket_sendto(struct socket_context *sock, return NT_STATUS_NOT_IMPLEMENTED; } - return sock->ops->fn_sendto(sock, blob, sendlen, flags, dest_addr); + return sock->ops->fn_sendto(sock, blob, sendlen, dest_addr); } -- cgit From 742c110cd67f4995639822981e8bfcb1f652f2c4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 2 May 2006 20:15:47 +0000 Subject: r15400: Move the TLS code behind the socket interface. This reduces caller complexity, because the TLS code is now called just like any other socket. (A new socket context is returned by the tls_init_server and tls_init_client routines). When TLS is not available, the original socket is returned. Andrew Bartlett (This used to be commit 09b2f30dfa7a640f5187b4933204e9680be61497) --- source4/lib/socket/socket.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 4f7f4ef4b9..b7d4431c94 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -37,9 +37,9 @@ static int socket_destructor(void *ptr) return 0; } -static NTSTATUS socket_create_with_ops(TALLOC_CTX *mem_ctx, const struct socket_ops *ops, - struct socket_context **new_sock, - enum socket_type type, uint32_t flags) +_PUBLIC_ NTSTATUS socket_create_with_ops(TALLOC_CTX *mem_ctx, const struct socket_ops *ops, + struct socket_context **new_sock, + enum socket_type type, uint32_t flags) { NTSTATUS status; -- cgit From 971d30bb201f5c3faff5f575d26882eb79f7955a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 24 May 2006 07:34:11 +0000 Subject: r15854: more talloc_set_destructor() typesafe fixes (This used to be commit 61c6100617589ac6df4f527877241464cacbf8b3) --- source4/lib/socket/socket.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index b7d4431c94..e1f8bb4d86 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -28,9 +28,8 @@ /* auto-close sockets on free */ -static int socket_destructor(void *ptr) +static int socket_destructor(struct socket_context *sock) { - struct socket_context *sock = ptr; if (sock->ops->fn_close) { sock->ops->fn_close(sock); } -- cgit From a1a842eb44b5bbb59af445af7a2c4a00e8c0188a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 21 Jul 2006 01:34:56 +0000 Subject: r17168: Now that TLS (and soon SASL) is below the socket layer, we need to make the testnonblock skip some things. The socket *under* the tls socket is still tested. Andrew Bartlett (This used to be commit 9c33c6a20a77e3f15eac3d62488117517afad940) --- source4/lib/socket/socket.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index e1f8bb4d86..ac64bc4ddc 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -66,6 +66,7 @@ _PUBLIC_ NTSTATUS socket_create_with_ops(TALLOC_CTX *mem_ctx, const struct socke /* 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) && type == SOCKET_TYPE_STREAM && lp_parm_bool(-1, "socket", "testnonblock", False)) { @@ -185,14 +186,21 @@ _PUBLIC_ NTSTATUS socket_recv(struct socket_context *sock, void *buf, return NT_STATUS_NOT_IMPLEMENTED; } - if ((sock->flags & SOCKET_FLAG_TESTNONBLOCK) && wantlen > 1) { - if (random() % 10 == 0) { - *nread = 0; - return STATUS_MORE_ENTRIES; + if ((sock->flags & SOCKET_FLAG_TESTNONBLOCK) + && wantlen > 1) { + + /* The returning of 0 and MORE_ENTRIES is incompatible + with TLS and SASL sockets, as there is not a + constant event source to re-trigger the reads */ + + if (!(sock->flags & SOCKET_FLAG_FAKE)) { + if (random() % 10 == 0) { + *nread = 0; + return STATUS_MORE_ENTRIES; + } } return sock->ops->fn_recv(sock, buf, 1+(random() % wantlen), nread); } - return sock->ops->fn_recv(sock, buf, wantlen, nread); } @@ -229,17 +237,21 @@ _PUBLIC_ NTSTATUS socket_send(struct socket_context *sock, if (!sock->ops->fn_send) { return NT_STATUS_NOT_IMPLEMENTED; } - - if ((sock->flags & SOCKET_FLAG_TESTNONBLOCK) && blob->length > 1) { - DATA_BLOB blob2 = *blob; + + if ((sock->flags & SOCKET_FLAG_TESTNONBLOCK) + && blob->length > 1) { if (random() % 10 == 0) { *sendlen = 0; return STATUS_MORE_ENTRIES; } - blob2.length = 1+(random() % blob2.length); - return sock->ops->fn_send(sock, &blob2, sendlen); + /* The variable size sends are incompatilbe with TLS and SASL + * sockets, which require re-sends to be consistant */ + if (!(sock->flags & SOCKET_FLAG_FAKE)) { + DATA_BLOB blob2 = *blob; + blob2.length = 1+(random() % blob2.length); + return sock->ops->fn_send(sock, &blob2, sendlen); + } } - return sock->ops->fn_send(sock, blob, sendlen); } -- cgit From ba07fa43d0b0090f5e686d8c1822468049f52416 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 23 Jul 2006 02:50:08 +0000 Subject: r17197: This patch moves the encryption of bulk data on SASL negotiated security contexts from the application layer into the socket layer. This improves a number of correctness aspects, as we now allow LDAP packets to cross multiple SASL packets. It should also make it much easier to write async LDAP tests from windows clients, as they use SASL by default. It is also vital to allowing OpenLDAP clients to use GSSAPI against Samba4, as it negotiates a rather small SASL buffer size. This patch mirrors the earlier work done to move TLS into the socket layer. Unusual in this pstch is the extra read callback argument I take. As SASL is a layer on top of a socket, it is entirely possible for the SASL layer to drain a socket dry, but for the caller not to have read all the decrypted data. This would leave the system without an event to restart the read (as the socket is dry). As such, I re-invoke the read handler from a timed callback, which should trigger on the next running of the event loop. I believe that the TLS code does require a similar callback. In trying to understand why this is required, imagine a SASL-encrypted LDAP packet in the following formation: +-----------------+---------------------+ | SASL Packet #1 | SASL Packet #2 | ----------------------------------------+ | LDAP Packet #1 | LDAP Packet #2 | ----------------------------------------+ In the old code, this was illegal, but it is perfectly standard SASL-encrypted LDAP. Without the callback, we would read and process the first LDAP packet, and the SASL code would have read the second SASL packet (to decrypt enough data for the LDAP packet), and no data would remain on the socket. Without data on the socket, read events stop. That is why I add timed events, until the SASL buffer is drained. Another approach would be to add a hack to the event system, to have it pretend there remained data to read off the network (but that is ugly). In improving the code, to handle more real-world cases, I've been able to remove almost all the special-cases in the testnonblock code. The only special case is that we must use a deterministic partial packet when calling send, rather than a random length. (1 + n/2). This is needed because of the way the SASL and TLS code works, and the 'resend on failure' requirements. Andrew Bartlett (This used to be commit 5d7c9c12cb2b39673172a357092b80cd814850b0) --- source4/lib/socket/socket.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index ac64bc4ddc..eca668885c 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -189,15 +189,9 @@ _PUBLIC_ NTSTATUS socket_recv(struct socket_context *sock, void *buf, if ((sock->flags & SOCKET_FLAG_TESTNONBLOCK) && wantlen > 1) { - /* The returning of 0 and MORE_ENTRIES is incompatible - with TLS and SASL sockets, as there is not a - constant event source to re-trigger the reads */ - - if (!(sock->flags & SOCKET_FLAG_FAKE)) { - if (random() % 10 == 0) { - *nread = 0; - return STATUS_MORE_ENTRIES; - } + if (random() % 10 == 0) { + *nread = 0; + return STATUS_MORE_ENTRIES; } return sock->ops->fn_recv(sock, buf, 1+(random() % wantlen), nread); } @@ -240,17 +234,22 @@ _PUBLIC_ NTSTATUS socket_send(struct socket_context *sock, if ((sock->flags & SOCKET_FLAG_TESTNONBLOCK) && blob->length > 1) { + DATA_BLOB blob2 = *blob; if (random() % 10 == 0) { *sendlen = 0; return STATUS_MORE_ENTRIES; } - /* The variable size sends are incompatilbe with TLS and SASL + /* The random size sends are incompatible with TLS and SASL * sockets, which require re-sends to be consistant */ - if (!(sock->flags & SOCKET_FLAG_FAKE)) { - DATA_BLOB blob2 = *blob; + if (!(sock->flags & SOCKET_FLAG_ENCRYPT)) { blob2.length = 1+(random() % blob2.length); - return sock->ops->fn_send(sock, &blob2, sendlen); + } else { + /* This is particularly stressful on buggy + * LDAP clients, that don't expect on LDAP + * packet in many SASL packets */ + blob2.length = 1 + blob2.length/2; } + return sock->ops->fn_send(sock, &blob2, sendlen); } return sock->ops->fn_send(sock, blob, sendlen); } -- cgit From b481b29a1a8279d70efa1e1b6e13520336336f53 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 30 Apr 2007 11:27:41 +0000 Subject: r22602: s/HAVE_SOCKET_IPV6/HAVE_IPV6/ to match the define used by Heimdal. (This used to be commit 5ff665b6531fdb4c7e56c49b7f923546d93b384c) --- source4/lib/socket/socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index eca668885c..d975eae2dc 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -426,7 +426,7 @@ _PUBLIC_ const struct socket_ops *socket_getops_byname(const char *family, enum return socket_ipv4_ops(type); } -#if HAVE_SOCKET_IPV6 +#if HAVE_IPV6 if (strcmp("ipv6", family) == 0) { if (lp_parm_bool(-1, "socket", "noipv6", False)) { DEBUG(3, ("IPv6 support was disabled in smb.conf")); -- cgit From 59d1a2b30ef3a57536876d2c58c108b6da19e4fa Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 17 May 2007 02:19:28 +0000 Subject: r22960: added a SOCKET_FLAG_NOCLOSE to allow us to tell the socket layer that we will handle the close of the socket (This used to be commit d57aaf5ba60464e5e782353a0879a84f8c70dd32) --- source4/lib/socket/socket.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index d975eae2dc..548b11ebcc 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -30,7 +30,8 @@ */ static int socket_destructor(struct socket_context *sock) { - if (sock->ops->fn_close) { + if (sock->ops->fn_close && + !(sock->flags & SOCKET_FLAG_NOCLOSE)) { sock->ops->fn_close(sock); } return 0; @@ -547,3 +548,10 @@ _PUBLIC_ void set_socket_options(int fd, const char *options) talloc_free(options_list); } +/* + set some flags on a socket + */ +void socket_set_flags(struct socket_context *sock, unsigned flags) +{ + sock->flags |= flags; +} -- cgit From 3381a5c3a45e7c7d1c6cf65325b7fb6f6d5ef3a6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 4 Jul 2007 07:43:26 +0000 Subject: r23701: when we create a new socket with socket_accept(), clear any flags that were set in the old one. Otherwise SOCKET_FLAG_NOCLOSE causes a major fd leak (This used to be commit 4e31eda055781a710d285c509d0c51b42e351431) --- source4/lib/socket/socket.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 548b11ebcc..89f8fe5a56 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -166,6 +166,7 @@ _PUBLIC_ NTSTATUS socket_accept(struct socket_context *sock, struct socket_conte if (NT_STATUS_IS_OK(status)) { talloc_set_destructor(*new_sock, socket_destructor); + (*new_sock)->flags = 0; } return status; -- cgit From 0479a2f1cbae51fcd8dbdc3c148c808421fb4d25 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 02:07:03 +0000 Subject: r23792: convert Samba4 to GPLv3 There are still a few tidyups of old FSF addresses to come (in both s3 and s4). More commits soon. (This used to be commit fcf38a38ac691abd0fa51b89dc951a08e89fdafa) --- source4/lib/socket/socket.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 89f8fe5a56..a60171ccd1 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" -- cgit From bd5a802a26f427779663a3de5f6d49f352b7c473 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 7 Sep 2007 11:47:03 +0000 Subject: r24992: Remove some uses of lp_*(). (This used to be commit a5a1a5540510cdb1bfbb3e89b84f4ba5b2812c55) --- source4/lib/socket/socket.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index a60171ccd1..5e19485ec6 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -429,10 +429,6 @@ _PUBLIC_ const struct socket_ops *socket_getops_byname(const char *family, enum #if HAVE_IPV6 if (strcmp("ipv6", family) == 0) { - if (lp_parm_bool(-1, "socket", "noipv6", False)) { - DEBUG(3, ("IPv6 support was disabled in smb.conf")); - return NULL; - } return socket_ipv6_ops(type); } #endif -- cgit From ffeee68e4b72dd94fee57366bd8d38b8c284c3d4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Sep 2007 12:42:09 +0000 Subject: r25026: Move param/param.h out of includes.h (This used to be commit abe8349f9b4387961ff3665d8c589d61cd2edf31) --- source4/lib/socket/socket.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 5e19485ec6..640d195d27 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -23,6 +23,7 @@ #include "lib/socket/socket.h" #include "system/filesys.h" #include "system/network.h" +#include "param/param.h" /* auto-close sockets on free -- cgit From dccf3f99e45137b6cd18c1de1c79808ad67130d1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Sep 2007 13:27:14 +0000 Subject: r25027: Fix more warnings. (This used to be commit 5085c53fcfade614e83d21fc2c1a5bc43bb2a729) --- source4/lib/socket/socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 640d195d27..184c89f3ed 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -408,7 +408,7 @@ _PUBLIC_ struct socket_address *socket_address_from_sockaddr(TALLOC_CTX *mem_ctx addr->family = NULL; addr->addr = NULL; addr->port = 0; - addr->sockaddr = talloc_memdup(addr, sockaddr, sockaddrlen); + addr->sockaddr = (struct sockaddr *)talloc_memdup(addr, sockaddr, sockaddrlen); if (!addr->sockaddr) { talloc_free(addr); return NULL; -- cgit From 98b57d5eb61094a9c88e2f7d90d3e21b7e74e9d8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Sep 2007 16:46:30 +0000 Subject: r25035: Fix some more warnings, use service pointer rather than service number in more places. (This used to be commit df9cebcb97e20564359097148665bd519f31bc6f) --- source4/lib/socket/socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 184c89f3ed..55a1b6394b 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -70,7 +70,7 @@ _PUBLIC_ NTSTATUS socket_create_with_ops(TALLOC_CTX *mem_ctx, const struct socke if (!(flags & SOCKET_FLAG_BLOCK) && type == SOCKET_TYPE_STREAM && - lp_parm_bool(-1, "socket", "testnonblock", False)) { + lp_parm_bool(NULL, "socket", "testnonblock", false)) { (*new_sock)->flags |= SOCKET_FLAG_TESTNONBLOCK; } -- cgit From 60a1046c5c5783799bd64fe18e03534670f83d82 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 29 Sep 2007 18:00:19 +0000 Subject: r25430: Add the loadparm context to all parametric options. (This used to be commit fd697d77c9fe67a00939a1f04b35c451316fff58) --- source4/lib/socket/socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 55a1b6394b..6da35f3af8 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -70,7 +70,7 @@ _PUBLIC_ NTSTATUS socket_create_with_ops(TALLOC_CTX *mem_ctx, const struct socke if (!(flags & SOCKET_FLAG_BLOCK) && type == SOCKET_TYPE_STREAM && - lp_parm_bool(NULL, "socket", "testnonblock", false)) { + lp_parm_bool(global_loadparm, NULL, "socket", "testnonblock", false)) { (*new_sock)->flags |= SOCKET_FLAG_TESTNONBLOCK; } -- cgit From 719a4ae0d32ab9ba817fd01f2b8f4cba220a8c60 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 5 Oct 2007 18:03:01 +0000 Subject: r25522: Convert to standard bool types. (This used to be commit 5e814287ba475e12f8cc934fdd09b199dcdfdb86) --- source4/lib/socket/socket.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/lib/socket/socket.c') diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 6da35f3af8..92f0a44005 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -77,7 +77,7 @@ _PUBLIC_ NTSTATUS socket_create_with_ops(TALLOC_CTX *mem_ctx, const struct socke /* we don't do a connect() on dgram sockets, so need to set non-blocking at socket create time */ if (!(flags & SOCKET_FLAG_BLOCK) && type == SOCKET_TYPE_DGRAM) { - set_blocking(socket_get_fd(*new_sock), False); + set_blocking(socket_get_fd(*new_sock), false); } talloc_set_destructor(*new_sock, socket_destructor); @@ -502,12 +502,12 @@ _PUBLIC_ void set_socket_options(int fd, const char *options) int ret=0,i; int value = 1; char *p; - BOOL got_value = False; + bool got_value = false; if ((p = strchr(tok,'='))) { *p = 0; value = atoi(p+1); - got_value = True; + got_value = true; } for (i=0;socket_options[i].name;i++) -- cgit