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

[tyndur-devel] [PATCH 1/4] libc: POSIX: Server-Sockets



+ libc: POSIX: TCP-Server-Sockets

Signed-off-by: Kevin Wolf <kevin@xxxxxxxxxx>
---
 src/modules/include/sys/socket.h |   25 ++++++++
 src/modules/lib/posix/socket.c   |  116 +++++++++++++++++++++++++++++++++++++-
 2 files changed, 139 insertions(+), 2 deletions(-)

diff --git a/src/modules/include/sys/socket.h b/src/modules/include/sys/socket.h
index b58c58c..1d19b5a 100644
--- a/src/modules/include/sys/socket.h
+++ b/src/modules/include/sys/socket.h
@@ -119,4 +119,29 @@ ssize_t recvfrom(int socket, const void *buffer, size_t length, int flags,
 ssize_t sendto(int socket, const void *buffer, size_t length, int flags,
     const struct sockaddr* to, socklen_t to_len);
 
+/**
+ * Bindet einen Socket an einen bestimmten TCP-Port (bzw. allgemein an eine
+ * Adresse)
+ *
+ * @param sock Socket, dem die Adresse zugewiesen werden soll
+ * @param address Adresse fuer den Socket (Fuer IP: struct sockaddr_in)
+ * @param address_len Groesse der Adressstruktur
+ *
+ * @return 0 bei Erfolg. Im Fehlerfall -1 und errno wird gesetzt.
+ */
+int bind(int sock, const struct sockaddr* address, socklen_t address_len);
+
+/**
+ * Benutzt einen Socket, um auf eingehende Verbindungen zu warten
+ *
+ * @param sock Socket, der auf Verbindungen warten soll
+ * @param backlog Wird unter tyndur ignoriert
+ */
+int listen(int sock, int backlog);
+
+/**
+ * Nimmt eine eingehende Verbindung an
+ */
+int accept(int sock, struct sockaddr* address, socklen_t* address_len);
+
 #endif
diff --git a/src/modules/lib/posix/socket.c b/src/modules/lib/posix/socket.c
index 9a4d0e4..65194de 100644
--- a/src/modules/lib/posix/socket.c
+++ b/src/modules/lib/posix/socket.c
@@ -42,8 +42,10 @@ struct socket {
     uint64_t            id;
     struct tree_item    tinfo;
 
-    sa_family_t         sa_family;
-    struct lostio_internal_file conn;
+    sa_family_t                     sa_family;
+    struct lostio_internal_file     conn;
+    struct sockaddr*                local_address;
+    FILE*                           listen_file;
 };
 
 static tree_t* sockets = NULL;
@@ -169,6 +171,116 @@ out_ip_string:
 }
 
 /**
+ * Bindet einen Socket an einen bestimmten TCP-Port (bzw. allgemein an eine
+ * Adresse)
+ *
+ * @param sock Socket, dem die Adresse zugewiesen werden soll
+ * @param address Adresse fuer den Socket (Fuer IP: struct sockaddr_in)
+ * @param address_len Groesse der Adressstruktur
+ *
+ * @return 0 bei Erfolg. Im Fehlerfall -1 und errno wird gesetzt.
+ */
+int bind(int sock, const struct sockaddr* address, socklen_t address_len)
+{
+    struct socket* socket = get_socket(sock);
+
+    if (socket == NULL) {
+        errno = EBADF;
+        return -1;
+    }
+
+    // FIXME Das wird beim Schliessen geleakt
+    socket->local_address = malloc(address_len);
+    memcpy(socket->local_address, address, address_len);
+
+    return 0;
+}
+
+/**
+ * Benutzt einen Socket, um auf eingehende Verbindungen zu warten
+ *
+ * @param sock Socket, der auf Verbindungen warten soll
+ * @param backlog Wird unter tyndur ignoriert
+ */
+int listen(int sock, int backlog)
+{
+    char* path;
+    uint16_t port;
+    struct socket* socket = get_socket(sock);
+    struct sockaddr_in* inet_addr;
+
+    if (socket == NULL) {
+        errno = EBADF;
+        return -1;
+    }
+
+    inet_addr = (struct sockaddr_in*) socket->local_address;
+    port = big_endian_word(inet_addr->sin_port);
+    if (asprintf(&path, "tcpip:/tcp-listen/:%d", port) < 1) {
+        errno = ENOMEM;
+        return -1;
+    }
+
+    socket->listen_file = fopen(path, "r");
+    free(path);
+    if (socket->listen_file == NULL) {
+        errno = EACCES;
+        return -1;
+    }
+
+    return 0;
+}
+
+/**
+ * Nimmt eine eingehende Verbindung an
+ */
+int accept(int sock, struct sockaddr* address, socklen_t* address_len)
+{
+    char buf[64];
+    int clientsock;
+    struct socket* clientsocket;
+    struct lostio_internal_file* conn;
+
+    struct socket* socket = get_socket(sock);
+
+    if (socket == NULL) {
+        errno = EBADF;
+        return -1;
+    }
+
+    if (socket->listen_file == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    if (fgets(buf, sizeof(buf), socket->listen_file) == NULL) {
+        errno = EAGAIN;
+        return -1;
+    }
+
+    clientsocket = calloc(1, sizeof(*clientsocket));
+    clientsocket->sa_family = AF_INET;
+    clientsock = create_socket(socket);
+
+    conn = (struct lostio_internal_file*) fopen(buf, "r+");
+    if (conn == NULL) {
+        free(socket);
+        errno = EAGAIN;
+        return -1;
+    }
+    setvbuf((FILE*)conn, NULL, _IONBF, 0);
+
+    // FIXME Boeser Hack
+    memcpy(&socket->conn, conn, sizeof(*conn));
+    free(conn);
+
+    // TODO Adresse aus buf rausfummeln
+    *address_len = 0;
+
+    return clientsock;
+}
+
+/**
  * Liest eine Anzahl Bytes aus einem Socket
  *
  * TODO Mit den Flags was sinnvolles machen
-- 
1.6.0.2