Commit 760537940532b738297eb46fd6dd55c8d688580f
1 parent
2b983646
create new more elaborated socket code. This is not 100% interface compatible.
Showing
20 changed files
with
859 additions
and
221 deletions
include/tr/interface/socket.h
0 → 100644
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: |
include/tr/remote_data.h
0 → 100644
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 |
src/i_socket.c
0 → 100644
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: |
src/remote_data.c
0 → 100644
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: |
src/socket_accept.c
0 → 100644
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: |
src/socket_init.c
0 → 100644
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: |
src/tcp_socket.c
0 → 100644
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: |
src/udp_socket.c
0 → 100644
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: |
trio.h
deleted
100644 → 0
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