summaryrefslogtreecommitdiff
path: root/source4/lib/socket/socket.c
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2004-09-13 14:17:41 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:58:44 -0500
commitce694e7051dca90cdb5700e3865315d16931c3c1 (patch)
treec6c00e86d187bfda340e03559d3561cd434bd39c /source4/lib/socket/socket.c
parent360f125f255fd7d5a172d012c00b3cfbff5a6989 (diff)
downloadsamba-ce694e7051dca90cdb5700e3865315d16931c3c1.tar.gz
samba-ce694e7051dca90cdb5700e3865315d16931c3c1.tar.bz2
samba-ce694e7051dca90cdb5700e3865315d16931c3c1.zip
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)
Diffstat (limited to 'source4/lib/socket/socket.c')
-rw-r--r--source4/lib/socket/socket.c215
1 files changed, 215 insertions, 0 deletions
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;
+}