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,3 +39,4 @@ gmon.out
39 test-driver 39 test-driver
40 /assets/html/_documentation.html 40 /assets/html/_documentation.html
41 tags 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 * \file 2 * \file
3 * Abstraction layer above BSD sockets. Capsules and simplifies connect 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 * \author Georg Hopp 7 * \author Georg Hopp
7 * 8 *
@@ -25,24 +26,82 @@ @@ -25,24 +26,82 @@
25 #ifndef __TR_SOCKET_H__ 26 #ifndef __TR_SOCKET_H__
26 #define __TR_SOCKET_H__ 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 #include "trbase.h" 36 #include "trbase.h"
  37 +#include "tr/interface/socket.h"
31 #include "tr/logger.h" 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 #endif // __TR_SOCKET_H__ 106 #endif // __TR_SOCKET_H__
48 107
1 #ifndef __TR_IO_H__ 1 #ifndef __TR_IO_H__
2 #define __TR_IO_H__ 2 #define __TR_IO_H__
3 3
4 -#include "tr/logger.h"  
5 #include "tr/socket.h" 4 #include "tr/socket.h"
  5 +#include "tr/remote_data.h"
6 #include "tr/stream.h" 6 #include "tr/stream.h"
7 -#include "tr/interface/logger.h" 7 +#include "tr/interface/socket.h"
8 #include "tr/interface/reader.h" 8 #include "tr/interface/reader.h"
9 #include "tr/interface/writer.h" 9 #include "tr/interface/writer.h"
10 10
@@ -7,12 +7,18 @@ TRIO = stream.c \ @@ -7,12 +7,18 @@ TRIO = stream.c \
7 read.c \ 7 read.c \
8 write.c \ 8 write.c \
9 socket.c \ 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 i_reader.c \ 22 i_reader.c \
17 i_writer.c 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,40 +20,24 @@
20 * along with this program. If not, see <http://www.gnu.org/licenses/>. 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 #include <errno.h> // for errno 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 #include "tr/logger.h" 29 #include "tr/logger.h"
28 30
29 -  
30 void 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 // vim: set ts=4 sw=4: 43 // vim: set ts=4 sw=4:
@@ -23,7 +23,14 @@ @@ -23,7 +23,14 @@
23 #include <errno.h> 23 #include <errno.h>
24 #include <stdlib.h> 24 #include <stdlib.h>
25 #include <unistd.h> 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 #include "tr/socket.h" 34 #include "tr/socket.h"
28 #include "tr/logger.h" 35 #include "tr/logger.h"
29 #include "trbase.h" 36 #include "trbase.h"
@@ -32,30 +39,15 @@ static @@ -32,30 +39,15 @@ static
32 int 39 int
33 socketCtor(void * _this, va_list * params) 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 return 0; 52 return 0;
61 } 53 }
@@ -64,15 +56,33 @@ static @@ -64,15 +56,33 @@ static
64 void 56 void
65 socketDtor(void * _this) 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 if (STDERR_FILENO < this->handle) { 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 TR_INIT_IFACE(TR_Class, socketCtor, socketDtor, NULL); 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 // vim: set ts=4 sw=4: 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,16 +20,20 @@
20 * along with this program. If not, see <http://www.gnu.org/licenses/>. 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 #include "tr/socket.h" 28 #include "tr/socket.h"
27 #include "tr/logger.h" 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 // vim: set ts=4 sw=4: 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,7 +28,7 @@
28 #include "tr/logger.h" 28 #include "tr/logger.h"
29 29
30 void 30 void
31 -TR_socketNonblock(TR_Sock this) 31 +TR_socketNonblock(TR_Socket this)
32 { 32 {
33 int flags = fcntl(this->handle, F_GETFL, 0); 33 int flags = fcntl(this->handle, F_GETFL, 0);
34 fcntl(this->handle, F_SETFL, flags | O_NONBLOCK); 34 fcntl(this->handle, F_SETFL, flags | O_NONBLOCK);
@@ -20,16 +20,25 @@ @@ -20,16 +20,25 @@
20 * along with this program. If not, see <http://www.gnu.org/licenses/>. 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 #include "tr/socket.h" 28 #include "tr/socket.h"
27 #include "tr/logger.h" 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 // vim: set ts=4 sw=4: 44 // vim: set ts=4 sw=4:
@@ -22,32 +22,26 @@ @@ -22,32 +22,26 @@
22 22
23 #include <stdlib.h> // for atoi() and exit() 23 #include <stdlib.h> // for atoi() and exit()
24 #include <errno.h> // for errno 24 #include <errno.h> // for errno
  25 +#include <stdio.h>
  26 +#include <unistd.h>
25 27
26 #include "tr/socket.h" 28 #include "tr/socket.h"
27 #include "tr/logger.h" 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 // vim: set ts=4 sw=4: 47 // vim: set ts=4 sw=4:
@@ -20,38 +20,28 @@ @@ -20,38 +20,28 @@
20 * along with this program. If not, see <http://www.gnu.org/licenses/>. 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 <errno.h> // for errno 24 #include <errno.h> // for errno
  25 +#include <stdio.h>
24 #include <unistd.h> 26 #include <unistd.h>
25 -#include <fcntl.h>  
26 27
27 -#include "trbase.h"  
28 #include "tr/socket.h" 28 #include "tr/socket.h"
29 #include "tr/logger.h" 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 // vim: set ts=4 sw=4: 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