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

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



On Mon, Apr 13 18:21, Kevin Wolf wrote:
> + 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/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.

Hast du hier absichtlich 4 Klauseln drin?

> + *
> + * 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;
> +};
> +

Zu diesen Strukturen wären ein paar Kommentare vielleich auch noch
hilfreich...

> +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);

Hat eigentlich nichts mit der änderung zu tun, oder sehe ich das falsch?

> 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)
> +    {

In dem fall ist aber das free(path) eher ungeschickt.

> +        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);

Uäh... ;-)

> +
> +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);
> +}

Was mache ich eigentlich mit so einen Socket wenn ich genug davon habe?
Kann ich das dann irgendwie loswerden?

-- 
Antoine Kaufmann
<toni@xxxxxxxxxxxxxxxx>

Attachment: pgpZMprNMl2d2.pgp
Description: PGP signature