summaryrefslogtreecommitdiff
path: root/source4/lib/socket/socket.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2005-01-19 03:20:20 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:08:59 -0500
commit8783aa8ea57c3a6989e0722d5184e98d543352d4 (patch)
tree93df839740cf04b88ec6ff9f81fcde5c99e77951 /source4/lib/socket/socket.c
parent6c310003d21fe832da46bbfeb078f716d87be04f (diff)
downloadsamba-8783aa8ea57c3a6989e0722d5184e98d543352d4.tar.gz
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)
Diffstat (limited to 'source4/lib/socket/socket.c')
-rw-r--r--source4/lib/socket/socket.c69
1 files changed, 47 insertions, 22 deletions
diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c
index cc43348e79f..97176ea1504 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;