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 | 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 | ... | ... |
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 | 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: | ... | ... |
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 | 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: | ... | ... |
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: | ... | ... |
| ... | ... | @@ -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: | ... | ... |
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