[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[tyndur-devel] [PATCH 1/4] libc: POSIX: Socket-Funktionen



+ libc: POSIX: Socket-Funktionen
---
 src/include/errno.h              |   12 +++
 src/modules/include/netinet/in.h |   10 ++
 src/modules/include/sys/socket.h |   99 +++++++++++++++++++
 src/modules/lib/posix/net.c      |    3 +
 src/modules/lib/posix/socket.c   |  193 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 317 insertions(+), 0 deletions(-)
 create mode 100644 src/modules/include/sys/socket.h
 create mode 100644 src/modules/lib/posix/socket.c

diff --git a/src/include/errno.h b/src/include/errno.h
index 2934ac1..3f8f16f 100644
--- a/src/include/errno.h
+++ b/src/include/errno.h
@@ -56,6 +56,18 @@
 #define ESRCH 25
 #define EPIPE 26
 #define EILSEQ 27
+
+
+#define EAFNOSUPPORT 28
+#define ETIMEDOUT 29
+#define EPROTOTYPE 30
+#define ECONNREFUSED 31
+#define ENOTCONN 32
+#define ECONNRESET 33
+#define EINPROGRESS 34
+#define EALREADY 35
+#define EISCONN 36
+
 extern int errno;
 
 #endif
diff --git a/src/modules/include/netinet/in.h b/src/modules/include/netinet/in.h
index b48125f..14963a4 100644
--- a/src/modules/include/netinet/in.h
+++ b/src/modules/include/netinet/in.h
@@ -29,6 +29,16 @@
 #ifndef _NETINET_IN_H_
 #define _NETINET_IN_H_
 
+#include <sys/socket.h>
+#include <stdint.h>
+
+/// Adresse fuer das INET-Protokol (IPv4)
+struct sockaddr_in {
+    sa_family_t     sin_family;
+    uint32_t        sin_addr;
+    uint32_t        sin_port;
+};
+
 unsigned long int htonl(unsigned long int hostlong);
 unsigned short int htons(unsigned short int hostshort);
 unsigned long int ntohl(unsigned long int netlong);
diff --git a/src/modules/include/sys/socket.h b/src/modules/include/sys/socket.h
new file mode 100644
index 0000000..38d12f6
--- /dev/null
+++ b/src/modules/include/sys/socket.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2009 The tyndur Project. All rights reserved.
+ *
+ * This code is derived from software contributed to the tyndur Project
+ * by Kevin Wolf.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the tyndur Project
+ *     and its contributors.
+ * 4. Neither the name of the tyndur Project nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _SYS_SOCKET_H_
+#define _SYS_SOCKET_H_
+
+#include <stdint.h>
+#include <sys/types.h>
+
+typedef int socklen_t;
+typedef unsigned int sa_family_t;
+
+struct sockaddr {
+    sa_family_t     sa_family;
+    char            sa_data[];
+};
+
+struct sockaddr_storage {
+    sa_family_t     ss_family;
+};
+
+enum {
+    SOCK_STREAM,
+};
+
+enum {
+    AF_INET,
+};
+
+enum {
+    IPPROTO_TCP,
+    IPPROTO_UDP,
+};
+
+/**
+ * Erstellt einen Socket
+ *
+ * @param domain Protokollfamilie (AF_*, z.B. AF_INET fuer IPv4)
+ * @param type Protokolltyp (SOCK_*, z.B. SOCK_STREAM fuer TCP)
+ * @param protocol Wird ignoriert; tyndur benutzt immer das Default-Protokoll,
+ * das zu domain und type passt
+ *
+ * @return Socketnummer. Im Fehlerfall -1 und errno wird gesetzt.
+ */
+int socket(int domain, int type, int protocol);
+
+/**
+ * Verbindet einen Socket (als Client) mit einer Gegenstelle
+ *
+ * @param socket Socket, der verbunden werden soll
+ * @param address Adresse der Gegenstelle (z.B. IP-Adresse/TCP-Port)
+ * @param address_len  Laenge der Adresse in Bytes
+ *
+ * @return 0 bei Erfolg. Im Fehlerfall -1 und errno wird gesetzt.
+ */
+int connect(int socket, struct sockaddr* address, socklen_t address_len);
+
+/**
+ * Liest eine Anzahl Bytes aus einem Socket
+ */
+ssize_t recv(int socket, const void *buffer, size_t length, int flags);
+
+/**
+ * Sendet eine Nachricht ueber einen Socket
+ */
+ssize_t send(int socket, const void *buffer, size_t length, int flags);
+
+#endif
diff --git a/src/modules/lib/posix/net.c b/src/modules/lib/posix/net.c
index 738eae8..2a41daf 100644
--- a/src/modules/lib/posix/net.c
+++ b/src/modules/lib/posix/net.c
@@ -29,6 +29,9 @@
 #include <netinet/in.h>
 #include <network.h>
 
+#include <stdlib.h>
+#include <string.h>
+
 unsigned long int htonl(unsigned long int hostlong)
 {
     return big_endian_dword(hostlong);
diff --git a/src/modules/lib/posix/socket.c b/src/modules/lib/posix/socket.c
new file mode 100644
index 0000000..61cd379
--- /dev/null
+++ b/src/modules/lib/posix/socket.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2009 The tyndur Project. All rights reserved.
+ *
+ * This code is derived from software contributed to the tyndur Project
+ * by Kevin Wolf.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the tyndur Project
+ *     and its contributors.
+ * 4. Neither the name of the tyndur Project nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <unistd.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <network.h>
+#include <collections.h>
+
+struct socket {
+    uint64_t            id;
+    struct tree_item    tinfo;
+
+    sa_family_t         sa_family;
+    FILE                conn;
+};
+
+static tree_t* sockets = NULL;
+
+/**
+ * Ruft die Socketstruktur anhand des Filedeskriptors ab
+ */
+static struct socket* get_socket(int sock)
+{
+    if (sockets == NULL) {
+        return NULL;
+    }
+
+    return tree_search(sockets, sock);
+}
+
+/**
+ * Ruft die Socketstruktur anhand des Filedeskriptors ab
+ */
+static int create_socket(struct socket* socket)
+{
+    if (sockets == NULL) {
+        sockets = tree_create(struct socket, tinfo, id);
+    }
+
+    socket->id = fileno(&socket->conn);
+    tree_insert(sockets, socket);
+    return socket->id;
+}
+
+/**
+ * Erstellt einen Socket
+ *
+ * @param domain Protokollfamilie (AF_*, z.B. AF_INET fuer IPv4)
+ * @param type Protokolltyp (SOCK_*, z.B. SOCK_STREAM fuer TCP)
+ * @param protocol Wird ignoriert; tyndur benutzt immer das Default-Protokoll,
+ * das zu domain und type passt
+ *
+ * @return Socketnummer. Im Fehlerfall -1 und errno wird gesetzt.
+ *
+ * FIXME protocol wird ignoriert
+ */
+int socket(int domain, int type, int protocol)
+{
+    int sock;
+    struct socket* socket;
+
+    if (domain != AF_INET) {
+        errno = EAFNOSUPPORT;
+        return -1;
+    }
+
+    if (type != SOCK_STREAM) {
+        errno = EPROTOTYPE;
+        return -1;
+    }
+
+    socket = calloc(1, sizeof(*socket));
+    socket->sa_family = domain;
+    memset(&socket->conn, 0, sizeof(socket->conn));
+
+    sock = create_socket(socket);
+
+    return sock;
+}
+
+/**
+ * Verbindet einen Socket (als Client) mit einer Gegenstelle
+ *
+ * @param socket Socket, der verbunden werden soll
+ * @param address Adresse der Gegenstelle (z.B. IP-Adresse/TCP-Port)
+ * @param address_len  Laenge der Adresse in Bytes
+ *
+ * @return 0 bei Erfolg. Im Fehlerfall -1 und errno wird gesetzt.
+ */
+int connect(int sock, struct sockaddr* address, socklen_t address_len)
+{
+    struct socket* socket = get_socket(sock);
+    struct sockaddr_in* inet_addr = (struct sockaddr_in*) address;
+    char* ip_string;
+    uint16_t port;
+    char* path;
+    int ret = 0;
+    FILE* conn;
+
+    if (socket == NULL) {
+        errno = EBADF;
+        return -1;
+    }
+
+    if (address->sa_family != socket->sa_family) {
+        errno = EAFNOSUPPORT;
+        return -1;
+    }
+
+    ip_string = ip_to_string(inet_addr->sin_addr);
+    port = big_endian_word(inet_addr->sin_port);
+    if (asprintf(&path, "tcpip:/%s:%d", ip_string, port) < 0)
+    {
+        errno = ENOMEM;
+        ret = -1;
+        goto out;
+    }
+
+    conn = fopen(path, "r+");
+    if (conn == NULL) {
+        errno = ETIMEDOUT;
+        ret = -1;
+        goto out;
+    }
+
+    // FIXME Boeser Hack
+    memcpy(&socket->conn, conn, sizeof(*conn));
+    free(conn);
+
+out:
+    free(ip_string);
+    free(path);
+
+    return 0;
+}
+
+/**
+ * Liest eine Anzahl Bytes aus einem Socket
+ *
+ * TODO Mit den Flags was sinnvolles machen
+ */
+ssize_t recv(int socket, const void *buffer, size_t length, int flags)
+{
+    return read(socket, (void*) buffer, length);
+}
+
+/**
+ * Sendet eine Anzahl Bytes ueber einen Socket
+ *
+ * TODO Mit den Flags was sinnvolles machen
+ */
+ssize_t send(int socket, const void *buffer, size_t length, int flags)
+{
+    return write(socket, buffer, length);
+}
-- 
1.6.0.2