[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