Commit 760537940532b738297eb46fd6dd55c8d688580f

Authored by Georg Hopp
1 parent 2b983646

create new more elaborated socket code. This is not 100% interface compatible.

... ... @@ -39,3 +39,4 @@ gmon.out
39 39 test-driver
40 40 /assets/html/_documentation.html
41 41 tags
  42 +trio.h
... ...
  1 +/**
  2 + * \file
  3 + * Inteface for common socket operations. (bind, send, recv)
  4 + *
  5 + * \author Georg Hopp
  6 + *
  7 + * \copyright
  8 + * Copyright © 2012 Georg Hopp
  9 + *
  10 + * This program is free software: you can redistribute it and/or modify
  11 + * it under the terms of the GNU General Public License as published by
  12 + * the Free Software Foundation, either version 3 of the License, or
  13 + * (at your option) any later version.
  14 + *
  15 + * This program is distributed in the hope that it will be useful,
  16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18 + * GNU General Public License for more details.
  19 + *
  20 + * You should have received a copy of the GNU General Public License
  21 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  22 + */
  23 +
  24 +#ifndef __TR_INTERFACE_SOCKET_H__
  25 +#define __TR_INTERFACE_SOCKET_H__
  26 +
  27 +#include <sys/types.h>
  28 +
  29 +#include "trbase.h"
  30 +#include "tr/remote_data.h"
  31 +
  32 +typedef int (* fptr_TR_socketBind)(void *);
  33 +typedef int (* fptr_TR_socketConnect)(void *);
  34 +typedef TR_RemoteData (* fptr_TR_socketRecv)(void *, size_t);
  35 +typedef ssize_t (* fptr_TR_socketSend)(void *, TR_RemoteData);
  36 +
  37 +TR_INTERFACE(TR_Socket) {
  38 + TR_IFID;
  39 + fptr_TR_socketBind bind;
  40 + fptr_TR_socketConnect connect;
  41 + fptr_TR_socketRecv recv;
  42 + fptr_TR_socketSend send;
  43 +};
  44 +
  45 +extern int TR_socketBindAction(void *);
  46 +extern int TR_socketConnectAction(void *);
  47 +extern TR_RemoteData TR_socketRecv(void *, size_t);
  48 +extern ssize_t TR_socketSend(void *, TR_RemoteData);
  49 +
  50 +#endif // __TR_INTERFACE_SOCKET_H__
  51 +
  52 +// vim: set ts=4 sw=4:
... ...
  1 +/**
  2 + * \file
  3 + * Abstraction layer above BSD sockets. Capsules and simplifies connect
  4 + * accept and listen.
  5 + *
  6 + * \author Georg Hopp
  7 + *
  8 + * \copyright
  9 + * Copyright © 2012 Georg Hopp
  10 + *
  11 + * This program is free software: you can redistribute it and/or modify
  12 + * it under the terms of the GNU General Public License as published by
  13 + * the Free Software Foundation, either version 3 of the License, or
  14 + * (at your option) any later version.
  15 + *
  16 + * This program is distributed in the hope that it will be useful,
  17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19 + * GNU General Public License for more details.
  20 + *
  21 + * You should have received a copy of the GNU General Public License
  22 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  23 + */
  24 +
  25 +#ifndef __TR_REMOTE_DATA_H__
  26 +#define __TR_REMOTE_DATA_H__
  27 +
  28 +#include <sys/types.h>
  29 +#include <sys/socket.h>
  30 +#include <netdb.h>
  31 +
  32 +#include "trbase.h"
  33 +
  34 +TR_CLASS(TR_RemoteData) {
  35 + unsigned char * data;
  36 + size_t ndata;
  37 + struct sockaddr_in addr; // for now... should be more generic
  38 + socklen_t addrlen;
  39 +};
  40 +
  41 +extern TR_RemoteData TR_emptyRemoteData;
  42 +
  43 +void TR_remoteDataSetData(TR_RemoteData, unsigned char *, size_t);
  44 +
  45 +#endif // __TR_REMOTE_DATA_H__
  46 +
  47 +// vim: set ts=4 sw=4:
  48 +
... ...
1 1 /**
2 2 * \file
3 3 * Abstraction layer above BSD sockets. Capsules and simplifies connect
4   - * accept and listen.
  4 + * accept and listen for TCP and UDP sockets.
  5 + * It also provides a mostly unified interface to both types of sockets.
5 6 *
6 7 * \author Georg Hopp
7 8 *
... ... @@ -25,24 +26,82 @@
25 26 #ifndef __TR_SOCKET_H__
26 27 #define __TR_SOCKET_H__
27 28
28   -#include <arpa/inet.h> // for in_port_t
  29 +#include <arpa/inet.h>
  30 +#include <sys/types.h>
  31 +#include <sys/socket.h>
  32 +#include <netdb.h>
  33 +
  34 +//#include <arpa/inet.h> // for in_port_t
29 35
30 36 #include "trbase.h"
  37 +#include "tr/interface/socket.h"
31 38 #include "tr/logger.h"
32 39
33   -TR_CLASS(TR_Sock) {
34   - TR_Logger log;
35   - in_port_t port;
36   - struct sockaddr_in addr;
37   - int handle;
  40 +typedef enum TR_e_socket_fin {
  41 + TR_FIN_NO = 0,
  42 + TR_FIN_RD = 1,
  43 + TR_FIN_WR = 2,
  44 + TR_FIN_RDWR = 3
  45 +} TR_SocketFin;
  46 +
  47 +TR_CLASS(TR_Socket) {
  48 + TR_Logger log;
  49 + int flags;
  50 + int type;
  51 + char * host;
  52 + char * cname;
  53 + int port;
  54 + time_t ttl;
  55 + struct sockaddr_in addr; // for now... should be more generic.
  56 + socklen_t addrlen;
  57 + int handle;
  58 + TR_SocketFin fin_state;
  59 +};
  60 +
  61 +#define TR_socketLog(socket) (((TR_Socket)(socket))->log)
  62 +#define TR_socketFlags(socket) (((TR_Socket)(socket))->flags)
  63 +#define TR_socketType(socket) (((TR_Socket)(socket))->type)
  64 +#define TR_socketHost(socket) (((TR_Socket)(socket))->host)
  65 +#define TR_socketPort(socket) (((TR_Socket)(socket))->port)
  66 +#define TR_socketCname(socket) (((TR_Socket)(socket))->cname)
  67 +#define TR_socketTtl(socket) (((TR_Socket)(socket))->ttl)
  68 +#define TR_socketAddr(socket) (((TR_Socket)(socket))->addr)
  69 +#define TR_socketAddrlen(socket) (((TR_Socket)(socket))->addrlen)
  70 +#define TR_socketHandle(socket) (((TR_Socket)(socket))->handle)
  71 +#define TR_socketFinState(socket) (((TR_Socket)(socket))->fin_state)
  72 +#define TR_socketFinRd(socket) ((TR_socketFinState((socket)) & 1) == 1)
  73 +#define TR_socketFinWr(socket) ((TR_socketFinState((socket)) & 2) == 2)
  74 +#define TR_socketFinRdWr(socket) ((TR_socketFinState((socket)) & 3) == 3)
  75 +
  76 +#define TR_socketGetIp(socket) (TR_socketAddr(socket).sin_addr.s_addr)
  77 +#define TR_socketGetIpStr(socket) (inet_ntoa(TR_socketGetIp(socket)))
  78 +
  79 +TR_CLASS(TR_TcpSocket) {
  80 + TR_EXTENDS(TR_Socket);
  81 + int listen;
  82 + int connected;
38 83 };
39 84
40   -void TR_socketConnect(TR_Sock this, const char * addr, char (*)[16]);
41   -void TR_socketListen(TR_Sock this, int backlog);
42   -TR_Sock TR_socketAccept(TR_Sock this, char (*remoteAddr)[16]);
43   -void TR_socketNonblock(TR_Sock this);
44   -in_addr_t TR_socketGetIp(TR_Sock this);
45   -const char * const TR_socketGetIpStr(TR_Sock this);
  85 +TR_CLASS(TR_UdpSocket) {
  86 + TR_EXTENDS(TR_Socket);
  87 +};
  88 +
  89 +typedef int (* TR_socketAction_fptr)(void *);
  90 +
  91 +int TR_socketInit(TR_Socket, TR_socketAction_fptr);
  92 +TR_SocketFin TR_socketShutdownRead(TR_Socket);
  93 +TR_SocketFin TR_socketShutdownWrite(TR_Socket);
  94 +TR_SocketFin TR_socketShutdown(TR_Socket);
  95 +void TR_socketClose(TR_Socket);
  96 +void TR_socketNonblock(TR_Socket);
  97 +
  98 +#define TR_socketBind(socket) \
  99 + (TR_socketInit((socket), TR_socketBindAction))
  100 +
  101 +TR_TcpSocket TR_socketAccept(TR_TcpSocket);
  102 +
  103 +#define TR_socketConnect(socket) \
  104 + (TR_socketInit((socket), TR_socketConnectAction))
46 105
47 106 #endif // __TR_SOCKET_H__
48 107
... ...
1 1 #ifndef __TR_IO_H__
2 2 #define __TR_IO_H__
3 3
4   -#include "tr/logger.h"
5 4 #include "tr/socket.h"
  5 +#include "tr/remote_data.h"
6 6 #include "tr/stream.h"
7   -#include "tr/interface/logger.h"
  7 +#include "tr/interface/socket.h"
8 8 #include "tr/interface/reader.h"
9 9 #include "tr/interface/writer.h"
10 10
... ...
... ... @@ -7,12 +7,18 @@ TRIO = stream.c \
7 7 read.c \
8 8 write.c \
9 9 socket.c \
10   - accept.c \
11   - connect.c \
12   - listen.c \
13   - get_ip.c \
14   - get_ip_str.c \
15   - nonblock.c \
  10 + socket_init.c \
  11 + socket_accept.c \
  12 + socket_nonblock.c \
  13 + socket_close.c \
  14 + socket_shutdown.c \
  15 + socket_shutdown_read.c \
  16 + socket_shutdown_write.c \
  17 + tcp_socket.c \
  18 + udp_socket.c \
  19 + remote_data.c \
  20 + remote_data_set_data.c \
  21 + i_socket.c \
16 22 i_reader.c \
17 23 i_writer.c
18 24
... ...
  1 +/**
  2 + * \file
  3 + *
  4 + * \author Georg Hopp
  5 + *
  6 + * \copyright
  7 + * Copyright © 2012 Georg Hopp
  8 + *
  9 + * This program is free software: you can redistribute it and/or modify
  10 + * it under the terms of the GNU General Public License as published by
  11 + * the Free Software Foundation, either version 3 of the License, or
  12 + * (at your option) any later version.
  13 + *
  14 + * This program is distributed in the hope that it will be useful,
  15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17 + * GNU General Public License for more details.
  18 + *
  19 + * You should have received a copy of the GNU General Public License
  20 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21 + */
  22 +
  23 +#include <errno.h>
  24 +
  25 +#include "tr/interface/socket.h"
  26 +#include "tr/remote_data.h"
  27 +#include "trbase.h"
  28 +
  29 +TR_CREATE_INTERFACE(TR_Socket, 4);
  30 +
  31 +int
  32 +TR_socketBindAction(void * _this)
  33 +{
  34 + int callret;
  35 +
  36 + TR_RETCALL(_this, TR_Socket, bind, callret);
  37 +
  38 + return callret;
  39 +}
  40 +
  41 +int
  42 +TR_socketConnectAction(void * _this)
  43 +{
  44 + int callret;
  45 +
  46 + TR_RETCALL(_this, TR_Socket, connect, callret);
  47 +
  48 + return callret;
  49 +}
  50 +
  51 +TR_RemoteData
  52 +TR_socketRecv(void * _this, size_t size)
  53 +{
  54 + TR_RemoteData remote_data;
  55 +
  56 + TR_RETCALL(_this, TR_Socket, recv, remote_data, size);
  57 +
  58 + if (remote_data->ndata < 0) {
  59 + switch (errno) {
  60 + case (EAGAIN|EWOULDBLOCK):
  61 + TR_delete(remote_data);
  62 + return TR_emptyRemoteData;
  63 +
  64 + case EINTR:
  65 + case ENOMEM:
  66 + // these are fatal and should lead to a shutown
  67 + // of the whole application...
  68 + TR_delete(remote_data);
  69 + return NULL;
  70 +
  71 + default:
  72 + TR_delete(remote_data);
  73 + return NULL;
  74 + }
  75 + } else if (remote_data->ndata == 0) {
  76 + // this is a remote close...
  77 + TR_delete(remote_data);
  78 + return NULL;
  79 + }
  80 +
  81 + return remote_data;
  82 +}
  83 +
  84 +ssize_t
  85 +TR_socketSend(void * _this, TR_RemoteData data)
  86 +{
  87 + ssize_t size;
  88 +
  89 + TR_RETCALL(_this, TR_Socket, send, size, data);
  90 + TR_delete(data);
  91 +
  92 + if (size < 0) {
  93 + switch (errno) {
  94 + case EINTR:
  95 + case ENOMEM:
  96 + // these are fatal and should lead to a shutown
  97 + // of the whole application...
  98 + return 0;
  99 +
  100 + case (EAGAIN|EWOULDBLOCK):
  101 + return -1;
  102 +
  103 + case ECONNRESET:
  104 + // this is a remote close...
  105 + return -2;
  106 +
  107 + default:
  108 + return -2;
  109 + }
  110 + }
  111 +
  112 + return size;
  113 +}
  114 +
  115 +// vim: set ts=4 sw=4:
... ...
  1 +/**
  2 + * \file
  3 + *
  4 + * \author Georg Hopp
  5 + *
  6 + * \copyright
  7 + * Copyright © 2012 Georg Hopp
  8 + *
  9 + * This program is free software: you can redistribute it and/or modify
  10 + * it under the terms of the GNU General Public License as published by
  11 + * the Free Software Foundation, either version 3 of the License, or
  12 + * (at your option) any later version.
  13 + *
  14 + * This program is distributed in the hope that it will be useful,
  15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17 + * GNU General Public License for more details.
  18 + *
  19 + * You should have received a copy of the GNU General Public License
  20 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21 + */
  22 +
  23 +#include <errno.h>
  24 +#include <stdlib.h>
  25 +#include <unistd.h>
  26 +#include <stdio.h>
  27 +#include <string.h>
  28 +
  29 +#include <sys/types.h>
  30 +#include <sys/socket.h>
  31 +#include <netdb.h>
  32 +
  33 +#include "tr/remote_data.h"
  34 +#include "trbase.h"
  35 +
  36 +static
  37 +int
  38 +remoteDataCtor(void * _this, va_list * params)
  39 +{
  40 + TR_RemoteData this = _this;
  41 + struct sockaddr * addr_ptr = va_arg(*params, struct sockaddr *);
  42 +
  43 + this->addrlen = va_arg(*params, socklen_t);
  44 + memcpy(&(this->addr), addr_ptr, this->addrlen);
  45 +
  46 + this->data = NULL;
  47 + this->ndata = 0;
  48 +
  49 + return 0;
  50 +}
  51 +
  52 +static
  53 +void
  54 +remoteDataDtor(void * _this)
  55 +{
  56 + TR_RemoteData this = _this;
  57 +
  58 + TR_MEM_FREE(this->data);
  59 +}
  60 +
  61 +TR_INIT_IFACE(TR_Class, remoteDataCtor, remoteDataDtor, NULL);
  62 +TR_CREATE_CLASS(TR_RemoteData, NULL, TR_IF(TR_Class));
  63 +
  64 +TR_INSTANCE(TR_RemoteData, TR_emptyRemoteData, NULL, 0, NULL, NULL);
  65 +
  66 +// vim: set ts=4 sw=4:
... ...
... ... @@ -20,40 +20,24 @@
20 20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 21 */
22 22
23   -#include <stdlib.h> // for atoi() and exit()
  23 +#include <string.h> // for atoi() and exit()
24 24 #include <errno.h> // for errno
  25 +#include <stdio.h>
  26 +#include <unistd.h>
25 27
26   -#include "tr/socket.h"
  28 +#include "tr/remote_data.h"
27 29 #include "tr/logger.h"
28 30
29   -
30 31 void
31   -TR_socketListen(TR_Sock this, int backlog)
  32 +TR_remoteDataSetData(TR_RemoteData this, unsigned char * data, size_t size)
32 33 {
33   - (this->addr).sin_family = AF_INET; // Internet address family
34   - (this->addr).sin_addr.s_addr = htonl(INADDR_ANY); // Any incoming interface
35   - //(this->addr).sin_addr.s_addr = inet_addr("127.0.0.1"); // Any incoming interface
36   - (this->addr).sin_port = htons(this->port); // Local port
37   -
38   - /**
39   - * Bind to the local address
40   - */
41   - if (-1 == bind(this->handle, (struct sockaddr *) &(this->addr), sizeof(this->addr))) {
42   - TR_loggerLog(this->log, TR_LOGGER_CRIT,
43   - "error binding socket: %s - service terminated",
44   - strerror(errno));
45   - exit(EXIT_FAILURE);
46   - }
  34 + if (this->data && TR_getSize(this->data) < size) {
  35 + TR_MEM_FREE(this->data);
  36 + }
47 37
48   - /**
49   - * Mark the socket so it will listen for incoming connections
50   - */
51   - if (-1 == listen(this->handle, backlog)) {
52   - TR_loggerLog(this->log, TR_LOGGER_CRIT,
53   - "error binding socket: %s - service terminated",
54   - strerror(errno));
55   - exit(EXIT_FAILURE);
56   - }
  38 + this->data = TR_malloc(size);
  39 + this->ndata = size;
  40 + memcpy(this->data, data, size);
57 41 }
58 42
59 43 // vim: set ts=4 sw=4:
... ...
... ... @@ -23,7 +23,14 @@
23 23 #include <errno.h>
24 24 #include <stdlib.h>
25 25 #include <unistd.h>
  26 +#include <stdio.h>
  27 +#include <fcntl.h>
26 28
  29 +#include <sys/types.h>
  30 +#include <sys/socket.h>
  31 +#include <netdb.h>
  32 +
  33 +#include "tr/remote_data.h"
27 34 #include "tr/socket.h"
28 35 #include "tr/logger.h"
29 36 #include "trbase.h"
... ... @@ -32,30 +39,15 @@ static
32 39 int
33 40 socketCtor(void * _this, va_list * params)
34 41 {
35   - TR_Sock this = _this;
36   - int reUse = 1; //! \todo make this configurable
37   - int port;
38   -
39   - this->log = va_arg(* params, TR_Logger);
40   - port = va_arg(* params, int);
41   -
42   - //! if port is -1 do not initialize the socket. (Used with accept)
43   - if (-1 == port) {
44   - return 0;
45   - } else {
46   - this->port = port;
47   - }
  42 + TR_Socket this = _this;
48 43
49   - //! Create socket for incoming connections
50   - if (-1 == (this->handle = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))) {
51   - TR_loggerLog(this->log, TR_LOGGER_CRIT,
52   - "error opening socket: %s - service terminated",
53   - strerror(errno));
54   - return -1;
55   - }
56   -
57   - //! Make the socket REUSE a TIME_WAIT socket
58   - setsockopt(this->handle, SOL_SOCKET, SO_REUSEADDR, &reUse, sizeof(reUse));
  44 + this->type = 0;
  45 + this->handle = -1;
  46 + this->log = va_arg(*params, TR_Logger);
  47 + this->host = va_arg(*params, char*);
  48 + this->port = va_arg(*params, int);
  49 + this->flags = va_arg(*params, int);
  50 + this->fin_state = TR_FIN_RDWR;
59 51
60 52 return 0;
61 53 }
... ... @@ -64,15 +56,33 @@ static
64 56 void
65 57 socketDtor(void * _this)
66 58 {
67   - TR_Sock this = _this;
  59 + TR_Socket this = _this;
  60 +
  61 + TR_MEM_FREE(this->cname);
68 62
69 63 if (STDERR_FILENO < this->handle) {
70   - shutdown(this->handle, SHUT_RDWR);
71   - close(this->handle);
  64 + TR_socketClose(this);
  65 + }
  66 +}
  67 +
  68 +static
  69 +int
  70 +socketBind(void * _this)
  71 +{
  72 + TR_Socket this = _this;
  73 + int state;
  74 +
  75 + state = bind(this->handle, (struct sockaddr *)&(this->addr), this->addrlen);
  76 +
  77 + if (-1 == state) {
  78 + perror("bind");
72 79 }
  80 +
  81 + return state;
73 82 }
74 83
75 84 TR_INIT_IFACE(TR_Class, socketCtor, socketDtor, NULL);
76   -TR_CREATE_CLASS(TR_Sock, NULL, TR_IF(TR_Class));
  85 +TR_INIT_IFACE(TR_Socket, socketBind, NULL, NULL);
  86 +TR_CREATE_CLASS(TR_Socket, NULL, TR_IF(TR_Class), TR_IF(TR_Socket));
77 87
78 88 // vim: set ts=4 sw=4:
... ...
  1 +/**
  2 + * \file
  3 + *
  4 + * \author Georg Hopp
  5 + *
  6 + * \copyright
  7 + * Copyright © 2012 Georg Hopp
  8 + *
  9 + * This program is free software: you can redistribute it and/or modify
  10 + * it under the terms of the GNU General Public License as published by
  11 + * the Free Software Foundation, either version 3 of the License, or
  12 + * (at your option) any later version.
  13 + *
  14 + * This program is distributed in the hope that it will be useful,
  15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17 + * GNU General Public License for more details.
  18 + *
  19 + * You should have received a copy of the GNU General Public License
  20 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21 + */
  22 +
  23 +#define _POSIX_SOURCE 1
  24 +
  25 +#include <stdio.h> // for atoi() and exit()
  26 +#include <errno.h> // for errno
  27 +#include <stdio.h>
  28 +#include <unistd.h>
  29 +#include <fcntl.h>
  30 +
  31 +#include <sys/types.h>
  32 +#include <sys/socket.h>
  33 +#include <netdb.h>
  34 +#include <netinet/in.h>
  35 +#include <arpa/inet.h>
  36 +
  37 +#include "tr/socket.h"
  38 +#include "tr/logger.h"
  39 +
  40 +TR_TcpSocket
  41 +TR_socketAccept(TR_TcpSocket this)
  42 +{
  43 + TR_Socket remote = TR_new(TR_TcpSocket, TR_socketLog(this), NULL, 0, 0);
  44 + //int flags;
  45 +
  46 + remote->handle = accept(
  47 + TR_socketHandle(this),
  48 + (struct sockaddr *)&(remote->addr),
  49 + &(remote->addrlen));
  50 +
  51 + //flags = fcntl(remote->handle, F_GETFL, 0);
  52 + //fcntl(remote->handle, F_SETFL, flags | O_NONBLOCK);
  53 +
  54 + remote->host = TR_strdup(inet_ntoa(remote->addr.sin_addr));
  55 + remote->port = ntohs(remote->addr.sin_port);
  56 + remote->type = TR_socketType(this);
  57 + remote->flags = TR_socketFlags(this);
  58 +
  59 + if (-1 == remote->handle) {
  60 + perror("accept");
  61 + TR_delete(remote);
  62 + }
  63 +
  64 + return (TR_TcpSocket)remote;
  65 +}
  66 +
  67 +// vim: set ts=4 sw=4:
... ...
... ... @@ -20,16 +20,20 @@
20 20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 21 */
22 22
23   -#include <arpa/inet.h>
  23 +#include <stdlib.h> // for atoi() and exit()
  24 +#include <errno.h> // for errno
  25 +#include <stdio.h>
  26 +#include <unistd.h>
24 27
25   -#include "trbase.h"
26 28 #include "tr/socket.h"
27 29 #include "tr/logger.h"
28 30
29   -in_addr_t
30   -TR_socketGetIp(TR_Sock this)
  31 +void
  32 +TR_socketClose(TR_Socket this)
31 33 {
32   - return this->addr.sin_addr.s_addr;
  34 + TR_socketShutdown(this);
  35 + close(this->handle);
  36 + this->handle = -1;
33 37 }
34 38
35 39 // vim: set ts=4 sw=4:
... ...
  1 +/**
  2 + * \file
  3 + *
  4 + * \author Georg Hopp
  5 + *
  6 + * \copyright
  7 + * Copyright © 2012 Georg Hopp
  8 + *
  9 + * This program is free software: you can redistribute it and/or modify
  10 + * it under the terms of the GNU General Public License as published by
  11 + * the Free Software Foundation, either version 3 of the License, or
  12 + * (at your option) any later version.
  13 + *
  14 + * This program is distributed in the hope that it will be useful,
  15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17 + * GNU General Public License for more details.
  18 + *
  19 + * You should have received a copy of the GNU General Public License
  20 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21 + */
  22 +
  23 +#define _POSIX_SOURCE 1
  24 +
  25 +#include <stdlib.h> // for atoi() and exit()
  26 +#include <errno.h> // for errno
  27 +#include <stdio.h>
  28 +#include <unistd.h>
  29 +#include <fcntl.h>
  30 +
  31 +#include <sys/types.h>
  32 +#include <sys/socket.h>
  33 +#include <netdb.h>
  34 +
  35 +#include "tr/socket.h"
  36 +#include "tr/logger.h"
  37 +
  38 +int
  39 +TR_socketInit(TR_Socket this, TR_socketAction_fptr action)
  40 +{
  41 + struct addrinfo hint;
  42 + struct addrinfo * info, * current_info;
  43 + char port_str[6];
  44 +
  45 + hint.ai_socktype = this->type;
  46 + hint.ai_flags = this->flags;
  47 + hint.ai_family = AF_UNSPEC;
  48 + hint.ai_protocol = 0;
  49 + hint.ai_addrlen = 0;
  50 + hint.ai_canonname = NULL;
  51 + hint.ai_addr = NULL;
  52 + hint.ai_next = NULL;
  53 +
  54 + sprintf(port_str, "%u", this->port);
  55 + if (0 != getaddrinfo(this->host, port_str, &hint, &info)) {
  56 + // TODO error handling...
  57 + return FALSE;
  58 + }
  59 +
  60 + current_info = info;
  61 + for (
  62 + current_info = info;
  63 + current_info;
  64 + current_info = current_info->ai_next)
  65 + {
  66 + this->handle = socket(
  67 + current_info->ai_family,
  68 + current_info->ai_socktype,
  69 + current_info->ai_protocol);
  70 +
  71 + if (-1 == this->handle) {
  72 + continue;
  73 + }
  74 +
  75 + this->addrlen = current_info->ai_addrlen;
  76 + memcpy(&(this->addr), current_info->ai_addr, this->addrlen);
  77 +
  78 + if (0 == action(this)) {
  79 + break; // success / open and bind or open and connect...
  80 + }
  81 +
  82 + close(this->handle);
  83 + this->handle = -1;
  84 + }
  85 +
  86 + if (NULL != current_info) {
  87 + int reUse = 1; //! \todo make this configurable
  88 + //int flags = fcntl(this->handle, F_GETFL, 0);
  89 +
  90 + //fcntl(this->handle, F_SETFL, flags | O_NONBLOCK);
  91 + this->cname = TR_strdup(current_info->ai_canonname);
  92 + this->fin_state = TR_FIN_NO;
  93 +
  94 + //! Make the socket REUSE a TIME_WAIT socket
  95 + setsockopt(this->handle, SOL_SOCKET, SO_REUSEADDR, &reUse, sizeof(reUse));
  96 + }
  97 +
  98 + freeaddrinfo(info);
  99 +
  100 + return TRUE;
  101 +}
  102 +
  103 +// vim: set ts=4 sw=4:
... ...
... ... @@ -28,7 +28,7 @@
28 28 #include "tr/logger.h"
29 29
30 30 void
31   -TR_socketNonblock(TR_Sock this)
  31 +TR_socketNonblock(TR_Socket this)
32 32 {
33 33 int flags = fcntl(this->handle, F_GETFL, 0);
34 34 fcntl(this->handle, F_SETFL, flags | O_NONBLOCK);
... ...
... ... @@ -20,16 +20,25 @@
20 20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 21 */
22 22
23   -#include <arpa/inet.h>
  23 +#include <stdlib.h> // for atoi() and exit()
  24 +#include <errno.h> // for errno
  25 +#include <stdio.h>
  26 +#include <unistd.h>
24 27
25   -#include "trbase.h"
26 28 #include "tr/socket.h"
27 29 #include "tr/logger.h"
28 30
29   -const char * const
30   -TR_socketGetIpStr(TR_Sock this)
  31 +TR_SocketFin
  32 +TR_socketShutdown(TR_Socket this)
31 33 {
32   - return inet_ntoa(this->addr.sin_addr);
  34 + if (TR_socketFinRdWr(this)) {
  35 + return this->fin_state;
  36 + }
  37 +
  38 + shutdown(this->handle, SHUT_RDWR);
  39 + this->fin_state |= TR_FIN_RDWR;
  40 +
  41 + return this->fin_state;
33 42 }
34 43
35 44 // vim: set ts=4 sw=4:
... ...
... ... @@ -22,32 +22,26 @@
22 22
23 23 #include <stdlib.h> // for atoi() and exit()
24 24 #include <errno.h> // for errno
  25 +#include <stdio.h>
  26 +#include <unistd.h>
25 27
26 28 #include "tr/socket.h"
27 29 #include "tr/logger.h"
28 30
29   -void
30   -TR_socketConnect(TR_Sock this, const char * addr, char (*remoteAddr)[16])
  31 +TR_SocketFin
  32 +TR_socketShutdownRead(TR_Socket this)
31 33 {
32   - inet_pton(AF_INET, addr, &((this->addr).sin_addr));
33   - (this->addr).sin_family = AF_INET; // Internet address family
34   - (this->addr).sin_port = htons(this->port); // Local port
  34 + if (TR_socketFinRd(this)) {
  35 + return this->fin_state;
  36 + }
35 37
36   - if (-1 == connect(
37   - this->handle,
38   - (struct sockaddr*) &(this->addr),
39   - sizeof(this->addr)))
40   - {
41   - TR_loggerLog(this->log, TR_LOGGER_CRIT,
42   - "error connection socket: %s - service terminated",
43   - strerror(errno));
44   - exit(EXIT_FAILURE);
45   - } else {
46   - strcpy(*remoteAddr, inet_ntoa((this->addr).sin_addr));
  38 + if (0 == shutdown(this->handle, SHUT_RD)) {
  39 + this->fin_state |= TR_FIN_RD;
  40 + } else {
  41 + this->fin_state |= TR_FIN_RDWR;
  42 + }
47 43
48   - TR_loggerLog(this->log, TR_LOGGER_INFO,
49   - "handling connection %s\n", inet_ntoa((this->addr).sin_addr));
50   - }
  44 + return this->fin_state;
51 45 }
52 46
53 47 // vim: set ts=4 sw=4:
... ...
... ... @@ -20,38 +20,28 @@
20 20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 21 */
22 22
  23 +#include <stdlib.h> // for atoi() and exit()
23 24 #include <errno.h> // for errno
  25 +#include <stdio.h>
24 26 #include <unistd.h>
25   -#include <fcntl.h>
26 27
27   -#include "trbase.h"
28 28 #include "tr/socket.h"
29 29 #include "tr/logger.h"
30 30
31   -TR_Sock
32   -TR_socketAccept(TR_Sock this, char (*remoteAddr)[16])
  31 +TR_SocketFin
  32 +TR_socketShutdownWrite(TR_Socket this)
33 33 {
34   - TR_Sock sock; // Socket for client
35   - unsigned int len; // Length of client address data structure
  34 + if (TR_socketFinWr(this)) {
  35 + return this->fin_state;
  36 + }
36 37
37   - // Set the size of the in-out parameter
38   - len = sizeof(this->addr);
  38 + if (0 == shutdown(this->handle, SHUT_WR)) {
  39 + this->fin_state |= TR_FIN_WR;
  40 + } else {
  41 + this->fin_state |= TR_FIN_RDWR;
  42 + }
39 43
40   - sock = TR_new(TR_Sock, this->log, -1);
41   -
42   - // Wait for a client to connect
43   - sock->handle = accept(this->handle, (struct sockaddr *) &(sock->addr), &len);
44   - if (-1 == sock->handle) {
45   - TR_loggerLog(this->log, TR_LOGGER_WARNING,
46   - "error accepting connection: %s", strerror(errno));
47   - } else {
48   - strcpy(*remoteAddr, inet_ntoa((sock->addr).sin_addr));
49   -
50   - //loggerLog(this->log, LOGGER_INFO,
51   - // "handling client %s\n", inet_ntoa((sock->addr).sin_addr));
52   - }
53   -
54   - return sock;
  44 + return this->fin_state;
55 45 }
56 46
57 47 // vim: set ts=4 sw=4:
... ...
  1 +/**
  2 + * \file
  3 + *
  4 + * \author Georg Hopp
  5 + *
  6 + * \copyright
  7 + * Copyright © 2012 Georg Hopp
  8 + *
  9 + * This program is free software: you can redistribute it and/or modify
  10 + * it under the terms of the GNU General Public License as published by
  11 + * the Free Software Foundation, either version 3 of the License, or
  12 + * (at your option) any later version.
  13 + *
  14 + * This program is distributed in the hope that it will be useful,
  15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17 + * GNU General Public License for more details.
  18 + *
  19 + * You should have received a copy of the GNU General Public License
  20 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21 + */
  22 +
  23 +#include <errno.h>
  24 +#include <stdlib.h>
  25 +#include <unistd.h>
  26 +#include <stdio.h>
  27 +
  28 +#include <sys/types.h>
  29 +#include <sys/socket.h>
  30 +#include <netdb.h>
  31 +
  32 +#include "tr/socket.h"
  33 +#include "tr/logger.h"
  34 +#include "trbase.h"
  35 +
  36 +static
  37 +int
  38 +tcpSocketCtor(void * _this, va_list * params)
  39 +{
  40 + TR_TcpSocket this = _this;
  41 +
  42 + TR_PARENTCALL(_this, TR_Class, ctor, params);
  43 +
  44 + TR_socketType(this) = SOCK_STREAM;
  45 + this->listen = FALSE;
  46 + this->connected = FALSE;
  47 +
  48 + return 0;
  49 +}
  50 +
  51 +static
  52 +int
  53 +tcpSocketBind(void * _this)
  54 +{
  55 + TR_TcpSocket this = _this;
  56 + int bind_ret;
  57 +
  58 + TR_PARENTRETCALL(_this, TR_Socket, bind, bind_ret);
  59 +
  60 + if (bind_ret != 0) {
  61 + return -1;
  62 + }
  63 +
  64 + if (listen(TR_socketHandle(this), 128) != 0) {
  65 + // error
  66 + return -1;
  67 + }
  68 + this->listen = TRUE;
  69 +
  70 + return 0;
  71 +}
  72 +
  73 +static
  74 +int
  75 +tcpSocketConnect(void * _this)
  76 +{
  77 + TR_Socket this = _this;
  78 +
  79 + return connect(
  80 + this->handle,
  81 + (struct sockaddr *)&(this->addr),
  82 + this->addrlen);
  83 +}
  84 +
  85 +static
  86 +TR_RemoteData
  87 +tcpSocketRecv(TR_Socket this, size_t size)
  88 +{
  89 + TR_RemoteData rdata = TR_new(TR_RemoteData, &(this->addr), this->addrlen);
  90 + unsigned char buffer[size];
  91 + ssize_t received;
  92 +
  93 + received = recv(this->handle, buffer, size, this->flags);
  94 +
  95 + if (-1 == received) {
  96 + perror("recv");
  97 + TR_delete(rdata);
  98 + } else {
  99 + TR_remoteDataSetData(rdata, buffer, received);
  100 + }
  101 +
  102 + return rdata;
  103 +}
  104 +
  105 +static
  106 +ssize_t
  107 +tcpSocketSend(TR_Socket this, TR_RemoteData data)
  108 +{
  109 + return send(this->handle, data->data, data->ndata, this->flags);
  110 +}
  111 +
  112 +TR_INIT_IFACE(TR_Class, tcpSocketCtor, NULL, NULL);
  113 +TR_INIT_IFACE(
  114 + TR_Socket,
  115 + tcpSocketBind,
  116 + tcpSocketConnect,
  117 + tcpSocketRecv,
  118 + tcpSocketSend);
  119 +TR_CREATE_CLASS(TR_TcpSocket, TR_Socket, TR_IF(TR_Class), TR_IF(TR_Socket));
  120 +
  121 +// vim: set ts=4 sw=4:
... ...
  1 +/**
  2 + * \file
  3 + *
  4 + * \author Georg Hopp
  5 + *
  6 + * \copyright
  7 + * Copyright © 2012 Georg Hopp
  8 + *
  9 + * This program is free software: you can redistribute it and/or modify
  10 + * it under the terms of the GNU General Public License as published by
  11 + * the Free Software Foundation, either version 3 of the License, or
  12 + * (at your option) any later version.
  13 + *
  14 + * This program is distributed in the hope that it will be useful,
  15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17 + * GNU General Public License for more details.
  18 + *
  19 + * You should have received a copy of the GNU General Public License
  20 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21 + */
  22 +
  23 +#include <errno.h>
  24 +#include <stdlib.h>
  25 +#include <unistd.h>
  26 +#include <stdio.h>
  27 +
  28 +#include <sys/types.h>
  29 +#include <sys/socket.h>
  30 +#include <netdb.h>
  31 +
  32 +#include "tr/socket.h"
  33 +#include "tr/logger.h"
  34 +#include "trbase.h"
  35 +
  36 +static
  37 +int
  38 +udpSocketCtor(void * _this, va_list * params)
  39 +{
  40 + TR_Socket this = _this;
  41 +
  42 + TR_PARENTCALL(_this, TR_Class, ctor, params);
  43 +
  44 + this->type = SOCK_DGRAM;
  45 +
  46 + return 0;
  47 +}
  48 +
  49 +static
  50 +TR_RemoteData
  51 +udpSocketRecv(TR_Socket this, size_t size)
  52 +{
  53 + TR_RemoteData rdata;
  54 + struct sockaddr_in addr;
  55 + socklen_t addrlen = this->addrlen;
  56 + unsigned char buffer[size];
  57 + ssize_t received;
  58 +
  59 + received = recvfrom(
  60 + this->handle,
  61 + buffer,
  62 + size,
  63 + this->flags,
  64 + (struct sockaddr *)&addr,
  65 + &addrlen);
  66 +
  67 + if (-1 == received) {
  68 + perror("recvfrom");
  69 + } else {
  70 + rdata = TR_new(TR_RemoteData, &addr, addrlen);
  71 + TR_remoteDataSetData(rdata, buffer, received);
  72 + }
  73 +
  74 + return rdata;
  75 +}
  76 +
  77 +static
  78 +ssize_t
  79 +udpSocketSend(TR_Socket this, TR_RemoteData data)
  80 +{
  81 + ssize_t send;
  82 +
  83 + send = sendto(
  84 + this->handle,
  85 + data->data,
  86 + data->ndata,
  87 + this->flags,
  88 + (struct sockaddr *)&(data->addr),
  89 + data->addrlen);
  90 +
  91 + if (-1 == send) {
  92 + perror("sendto");
  93 + }
  94 +
  95 + return send;
  96 +}
  97 +
  98 +TR_INIT_IFACE(TR_Class, udpSocketCtor, NULL, NULL);
  99 +TR_INIT_IFACE(TR_Socket, NULL, NULL, udpSocketRecv, udpSocketSend);
  100 +TR_CREATE_CLASS(TR_UdpSocket, TR_Socket, TR_IF(TR_Class), TR_IF(TR_Socket));
  101 +
  102 +// vim: set ts=4 sw=4:
... ...
1   -/* trio.h. Generated from trio.h.in by configure. */
2   -/* trio.h.in. Generated from configure.ac by autoheader. */
3   -
4   -/* Define to 1 if you have the <dlfcn.h> header file. */
5   -#define HAVE_DLFCN_H 1
6   -
7   -/* Define to 1 if you have the <inttypes.h> header file. */
8   -#define HAVE_INTTYPES_H 1
9   -
10   -/* Define to 1 if you have the <memory.h> header file. */
11   -#define HAVE_MEMORY_H 1
12   -
13   -/* Define to 1 if you have the `memset' function. */
14   -/* #undef HAVE_MEMSET */
15   -
16   -/* Define to 1 if you have the <stdarg.h> header file. */
17   -#define HAVE_STDARG_H 1
18   -
19   -/* Define to 1 if stdbool.h conforms to C99. */
20   -/* #undef HAVE_STDBOOL_H */
21   -
22   -/* Define to 1 if you have the <stdint.h> header file. */
23   -#define HAVE_STDINT_H 1
24   -
25   -/* Define to 1 if you have the <stdio.h> header file. */
26   -#define HAVE_STDIO_H 1
27   -
28   -/* Define to 1 if you have the <stdlib.h> header file. */
29   -#define HAVE_STDLIB_H 1
30   -
31   -/* Define to 1 if you have the <strings.h> header file. */
32   -#define HAVE_STRINGS_H 1
33   -
34   -/* Define to 1 if you have the <string.h> header file. */
35   -#define HAVE_STRING_H 1
36   -
37   -/* Define to 1 if you have the <syslog.h> header file. */
38   -#define HAVE_SYSLOG_H 1
39   -
40   -/* Define to 1 if you have the <sys/stat.h> header file. */
41   -#define HAVE_SYS_STAT_H 1
42   -
43   -/* Define to 1 if you have the <sys/types.h> header file. */
44   -#define HAVE_SYS_TYPES_H 1
45   -
46   -/* Define to 1 if you have the <unistd.h> header file. */
47   -#define HAVE_UNISTD_H 1
48   -
49   -/* Define to 1 if the system has the type `_Bool'. */
50   -#define HAVE__BOOL 1
51   -
52   -/* Define to the sub-directory in which libtool stores uninstalled libraries.
53   - */
54   -#define LT_OBJDIR ".libs/"
55   -
56   -/* Name of package */
57   -#define PACKAGE "libtrio"
58   -
59   -/* Define to the address where bug reports for this package should be sent. */
60   -#define PACKAGE_BUGREPORT "Georg Hopp <georg@steffers.org>"
61   -
62   -/* Define to the full name of this package. */
63   -#define PACKAGE_NAME "libtrio"
64   -
65   -/* Define to the full name and version of this package. */
66   -#define PACKAGE_STRING "libtrio 0.0.0"
67   -
68   -/* Define to the one symbol short name of this package. */
69   -#define PACKAGE_TARNAME "libtrio"
70   -
71   -/* Define to the home page for this package. */
72   -#define PACKAGE_URL ""
73   -
74   -/* Define to the version of this package. */
75   -#define PACKAGE_VERSION "0.0.0"
76   -
77   -/* Define to 1 if you have the ANSI C header files. */
78   -#define STDC_HEADERS 1
79   -
80   -/* Version number of package */
81   -#define VERSION "0.0.0"
82   -
83   -/* Define to `__inline__' or `__inline' if that's what the C compiler
84   - calls it, or to nothing if 'inline' is not supported under any name. */
85   -#ifndef __cplusplus
86   -/* #undef inline */
87   -#endif
88   -
89   -/* Define to `int' if <sys/types.h> does not define. */
90   -/* #undef pid_t */
91   -
92   -/* Define to `unsigned int' if <sys/types.h> does not define. */
93   -/* #undef size_t */
Please register or login to post a comment