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

[tyndur-devel] [PATCH v2 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 |  106 +++++++++++++++++++++
 src/modules/lib/posix/socket.c   |  187 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 315 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..a52b8de
--- /dev/null
+++ b/src/modules/include/sys/socket.h
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ *
+ * 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;
+
+/**
+ *  Beschreibt die Adresse einer Gegenstelle fuer einen Socket.
+ *
+ *  Diese struct dient als "Vaterklasse" fuer weitere structs, die fuer die
+ *  einzelnen Adressfamilien definiert sind.
+ */
+struct sockaddr {
+    /// Adressfamilie (AF_*)
+    sa_family_t     sa_family;
+
+    /// Adressfamilienspezifische Daten
+    char            sa_data[];
+};
+
+struct sockaddr_storage {
+    sa_family_t     ss_family;
+};
+
+/// Protokolltypen
+enum {
+    /// Verbindungsoriertierter Socket (z.B. TCP)
+    SOCK_STREAM,
+};
+
+/// Adressfamilien
+enum {
+    /// IPv4
+    AF_INET,
+};
+
+/// Protokolle fuer IP
+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/socket.c b/src/modules/lib/posix/socket.c
new file mode 100644
index 0000000..b8941d7
--- /dev/null
+++ b/src/modules/lib/posix/socket.c
@@ -0,0 +1,187 @@
+/*
+ * 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.
+ *
+ * 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_ip_string;
+    }
+
+    conn = fopen(path, "r+");
+    if (conn == NULL) {
+        errno = ETIMEDOUT;
+        ret = -1;
+        goto out_path;
+    }
+
+    // FIXME Boeser Hack
+    memcpy(&socket->conn, conn, sizeof(*conn));
+    free(conn);
+
+out_path:
+    free(path);
+out_ip_string:
+    free(ip_string);
+
+    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