[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [tyndur-devel] [PATCH 1/4] libc: POSIX: Socket-Funktionen
Am Montag, 13. April 2009 20:16 schrieb Antoine Kaufmann:
> 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?
Ups. Good catch. Die Anfänge der Patchserie sind schon etwas älter. ;-)
> > + *
> > + * 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?
Hm, jo. git rebase hat sich heute irgendwann mal kräftig verschluckt, das
dürfte ein Überbleibsel davon sein. Mal sehen, in welchem anderen Patch es
dann fehlt.
> > 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... ;-)
An irgendwas muß man es ja als tyndur-Code erkennen ;-)
> > +
> > +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?
Dann programmierst du einen Hook in close(), der für Sockets das entsprechende
Element aus dem sockets-Baum rauswirft. ;-)