Browse Source

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

1.0.0
Georg Hopp 12 years ago
parent
commit
7605379405
  1. 1
      .gitignore
  2. 52
      include/tr/interface/socket.h
  3. 48
      include/tr/remote_data.h
  4. 85
      include/tr/socket.h
  5. 4
      include/trio.h
  6. 18
      src/Makefile.am
  7. 115
      src/i_socket.c
  8. 59
      src/listen.c
  9. 66
      src/remote_data.c
  10. 43
      src/remote_data_set_data.c
  11. 64
      src/socket.c
  12. 48
      src/socket_accept.c
  13. 14
      src/socket_close.c
  14. 103
      src/socket_init.c
  15. 2
      src/socket_nonblock.c
  16. 19
      src/socket_shutdown.c
  17. 32
      src/socket_shutdown_read.c
  18. 47
      src/socket_shutdown_write.c
  19. 121
      src/tcp_socket.c
  20. 102
      src/udp_socket.c
  21. 93
      trio.h

1
.gitignore

@ -39,3 +39,4 @@ gmon.out
test-driver
/assets/html/_documentation.html
tags
trio.h

52
include/tr/interface/socket.h

@ -0,0 +1,52 @@
/**
* \file
* Inteface for common socket operations. (bind, send, recv)
*
* \author Georg Hopp
*
* \copyright
* Copyright © 2012 Georg Hopp
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __TR_INTERFACE_SOCKET_H__
#define __TR_INTERFACE_SOCKET_H__
#include <sys/types.h>
#include "trbase.h"
#include "tr/remote_data.h"
typedef int (* fptr_TR_socketBind)(void *);
typedef int (* fptr_TR_socketConnect)(void *);
typedef TR_RemoteData (* fptr_TR_socketRecv)(void *, size_t);
typedef ssize_t (* fptr_TR_socketSend)(void *, TR_RemoteData);
TR_INTERFACE(TR_Socket) {
TR_IFID;
fptr_TR_socketBind bind;
fptr_TR_socketConnect connect;
fptr_TR_socketRecv recv;
fptr_TR_socketSend send;
};
extern int TR_socketBindAction(void *);
extern int TR_socketConnectAction(void *);
extern TR_RemoteData TR_socketRecv(void *, size_t);
extern ssize_t TR_socketSend(void *, TR_RemoteData);
#endif // __TR_INTERFACE_SOCKET_H__
// vim: set ts=4 sw=4:

48
include/tr/remote_data.h

@ -0,0 +1,48 @@
/**
* \file
* Abstraction layer above BSD sockets. Capsules and simplifies connect
* accept and listen.
*
* \author Georg Hopp
*
* \copyright
* Copyright © 2012 Georg Hopp
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __TR_REMOTE_DATA_H__
#define __TR_REMOTE_DATA_H__
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include "trbase.h"
TR_CLASS(TR_RemoteData) {
unsigned char * data;
size_t ndata;
struct sockaddr_in addr; // for now... should be more generic
socklen_t addrlen;
};
extern TR_RemoteData TR_emptyRemoteData;
void TR_remoteDataSetData(TR_RemoteData, unsigned char *, size_t);
#endif // __TR_REMOTE_DATA_H__
// vim: set ts=4 sw=4:

85
include/tr/socket.h

@ -1,7 +1,8 @@
/**
* \file
* Abstraction layer above BSD sockets. Capsules and simplifies connect
* accept and listen.
* accept and listen for TCP and UDP sockets.
* It also provides a mostly unified interface to both types of sockets.
*
* \author Georg Hopp
*
@ -25,24 +26,82 @@
#ifndef __TR_SOCKET_H__
#define __TR_SOCKET_H__
#include <arpa/inet.h> // for in_port_t
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
//#include <arpa/inet.h> // for in_port_t
#include "trbase.h"
#include "tr/interface/socket.h"
#include "tr/logger.h"
TR_CLASS(TR_Sock) {
TR_Logger log;
in_port_t port;
struct sockaddr_in addr;
int handle;
typedef enum TR_e_socket_fin {
TR_FIN_NO = 0,
TR_FIN_RD = 1,
TR_FIN_WR = 2,
TR_FIN_RDWR = 3
} TR_SocketFin;
TR_CLASS(TR_Socket) {
TR_Logger log;
int flags;
int type;
char * host;
char * cname;
int port;
time_t ttl;
struct sockaddr_in addr; // for now... should be more generic.
socklen_t addrlen;
int handle;
TR_SocketFin fin_state;
};
#define TR_socketLog(socket) (((TR_Socket)(socket))->log)
#define TR_socketFlags(socket) (((TR_Socket)(socket))->flags)
#define TR_socketType(socket) (((TR_Socket)(socket))->type)
#define TR_socketHost(socket) (((TR_Socket)(socket))->host)
#define TR_socketPort(socket) (((TR_Socket)(socket))->port)
#define TR_socketCname(socket) (((TR_Socket)(socket))->cname)
#define TR_socketTtl(socket) (((TR_Socket)(socket))->ttl)
#define TR_socketAddr(socket) (((TR_Socket)(socket))->addr)
#define TR_socketAddrlen(socket) (((TR_Socket)(socket))->addrlen)
#define TR_socketHandle(socket) (((TR_Socket)(socket))->handle)
#define TR_socketFinState(socket) (((TR_Socket)(socket))->fin_state)
#define TR_socketFinRd(socket) ((TR_socketFinState((socket)) & 1) == 1)
#define TR_socketFinWr(socket) ((TR_socketFinState((socket)) & 2) == 2)
#define TR_socketFinRdWr(socket) ((TR_socketFinState((socket)) & 3) == 3)
#define TR_socketGetIp(socket) (TR_socketAddr(socket).sin_addr.s_addr)
#define TR_socketGetIpStr(socket) (inet_ntoa(TR_socketGetIp(socket)))
TR_CLASS(TR_TcpSocket) {
TR_EXTENDS(TR_Socket);
int listen;
int connected;
};
void TR_socketConnect(TR_Sock this, const char * addr, char (*)[16]);
void TR_socketListen(TR_Sock this, int backlog);
TR_Sock TR_socketAccept(TR_Sock this, char (*remoteAddr)[16]);
void TR_socketNonblock(TR_Sock this);
in_addr_t TR_socketGetIp(TR_Sock this);
const char * const TR_socketGetIpStr(TR_Sock this);
TR_CLASS(TR_UdpSocket) {
TR_EXTENDS(TR_Socket);
};
typedef int (* TR_socketAction_fptr)(void *);
int TR_socketInit(TR_Socket, TR_socketAction_fptr);
TR_SocketFin TR_socketShutdownRead(TR_Socket);
TR_SocketFin TR_socketShutdownWrite(TR_Socket);
TR_SocketFin TR_socketShutdown(TR_Socket);
void TR_socketClose(TR_Socket);
void TR_socketNonblock(TR_Socket);
#define TR_socketBind(socket) \
(TR_socketInit((socket), TR_socketBindAction))
TR_TcpSocket TR_socketAccept(TR_TcpSocket);
#define TR_socketConnect(socket) \
(TR_socketInit((socket), TR_socketConnectAction))
#endif // __TR_SOCKET_H__

4
include/trio.h

@ -1,10 +1,10 @@
#ifndef __TR_IO_H__
#define __TR_IO_H__
#include "tr/logger.h"
#include "tr/socket.h"
#include "tr/remote_data.h"
#include "tr/stream.h"
#include "tr/interface/logger.h"
#include "tr/interface/socket.h"
#include "tr/interface/reader.h"
#include "tr/interface/writer.h"

18
src/Makefile.am

@ -7,12 +7,18 @@ TRIO = stream.c \
read.c \
write.c \
socket.c \
accept.c \
connect.c \
listen.c \
get_ip.c \
get_ip_str.c \
nonblock.c \
socket_init.c \
socket_accept.c \
socket_nonblock.c \
socket_close.c \
socket_shutdown.c \
socket_shutdown_read.c \
socket_shutdown_write.c \
tcp_socket.c \
udp_socket.c \
remote_data.c \
remote_data_set_data.c \
i_socket.c \
i_reader.c \
i_writer.c

115
src/i_socket.c

@ -0,0 +1,115 @@
/**
* \file
*
* \author Georg Hopp
*
* \copyright
* Copyright © 2012 Georg Hopp
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <errno.h>
#include "tr/interface/socket.h"
#include "tr/remote_data.h"
#include "trbase.h"
TR_CREATE_INTERFACE(TR_Socket, 4);
int
TR_socketBindAction(void * _this)
{
int callret;
TR_RETCALL(_this, TR_Socket, bind, callret);
return callret;
}
int
TR_socketConnectAction(void * _this)
{
int callret;
TR_RETCALL(_this, TR_Socket, connect, callret);
return callret;
}
TR_RemoteData
TR_socketRecv(void * _this, size_t size)
{
TR_RemoteData remote_data;
TR_RETCALL(_this, TR_Socket, recv, remote_data, size);
if (remote_data->ndata < 0) {
switch (errno) {
case (EAGAIN|EWOULDBLOCK):
TR_delete(remote_data);
return TR_emptyRemoteData;
case EINTR:
case ENOMEM:
// these are fatal and should lead to a shutown
// of the whole application...
TR_delete(remote_data);
return NULL;
default:
TR_delete(remote_data);
return NULL;
}
} else if (remote_data->ndata == 0) {
// this is a remote close...
TR_delete(remote_data);
return NULL;
}
return remote_data;
}
ssize_t
TR_socketSend(void * _this, TR_RemoteData data)
{
ssize_t size;
TR_RETCALL(_this, TR_Socket, send, size, data);
TR_delete(data);
if (size < 0) {
switch (errno) {
case EINTR:
case ENOMEM:
// these are fatal and should lead to a shutown
// of the whole application...
return 0;
case (EAGAIN|EWOULDBLOCK):
return -1;
case ECONNRESET:
// this is a remote close...
return -2;
default:
return -2;
}
}
return size;
}
// vim: set ts=4 sw=4:

59
src/listen.c

@ -1,59 +0,0 @@
/**
* \file
*
* \author Georg Hopp
*
* \copyright
* Copyright © 2012 Georg Hopp
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h> // for atoi() and exit()
#include <errno.h> // for errno
#include "tr/socket.h"
#include "tr/logger.h"
void
TR_socketListen(TR_Sock this, int backlog)
{
(this->addr).sin_family = AF_INET; // Internet address family
(this->addr).sin_addr.s_addr = htonl(INADDR_ANY); // Any incoming interface
//(this->addr).sin_addr.s_addr = inet_addr("127.0.0.1"); // Any incoming interface
(this->addr).sin_port = htons(this->port); // Local port
/**
* Bind to the local address
*/
if (-1 == bind(this->handle, (struct sockaddr *) &(this->addr), sizeof(this->addr))) {
TR_loggerLog(this->log, TR_LOGGER_CRIT,
"error binding socket: %s - service terminated",
strerror(errno));
exit(EXIT_FAILURE);
}
/**
* Mark the socket so it will listen for incoming connections
*/
if (-1 == listen(this->handle, backlog)) {
TR_loggerLog(this->log, TR_LOGGER_CRIT,
"error binding socket: %s - service terminated",
strerror(errno));
exit(EXIT_FAILURE);
}
}
// vim: set ts=4 sw=4:

66
src/remote_data.c

@ -0,0 +1,66 @@
/**
* \file
*
* \author Georg Hopp
*
* \copyright
* Copyright © 2012 Georg Hopp
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include "tr/remote_data.h"
#include "trbase.h"
static
int
remoteDataCtor(void * _this, va_list * params)
{
TR_RemoteData this = _this;
struct sockaddr * addr_ptr = va_arg(*params, struct sockaddr *);
this->addrlen = va_arg(*params, socklen_t);
memcpy(&(this->addr), addr_ptr, this->addrlen);
this->data = NULL;
this->ndata = 0;
return 0;
}
static
void
remoteDataDtor(void * _this)
{
TR_RemoteData this = _this;
TR_MEM_FREE(this->data);
}
TR_INIT_IFACE(TR_Class, remoteDataCtor, remoteDataDtor, NULL);
TR_CREATE_CLASS(TR_RemoteData, NULL, TR_IF(TR_Class));
TR_INSTANCE(TR_RemoteData, TR_emptyRemoteData, NULL, 0, NULL, NULL);
// vim: set ts=4 sw=4:

43
src/remote_data_set_data.c

@ -0,0 +1,43 @@
/**
* \file
*
* \author Georg Hopp
*
* \copyright
* Copyright © 2012 Georg Hopp
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h> // for atoi() and exit()
#include <errno.h> // for errno
#include <stdio.h>
#include <unistd.h>
#include "tr/remote_data.h"
#include "tr/logger.h"
void
TR_remoteDataSetData(TR_RemoteData this, unsigned char * data, size_t size)
{
if (this->data && TR_getSize(this->data) < size) {
TR_MEM_FREE(this->data);
}
this->data = TR_malloc(size);
this->ndata = size;
memcpy(this->data, data, size);
}
// vim: set ts=4 sw=4:

64
src/socket.c

@ -23,7 +23,14 @@
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include "tr/remote_data.h"
#include "tr/socket.h"
#include "tr/logger.h"
#include "trbase.h"
@ -32,30 +39,15 @@ static
int
socketCtor(void * _this, va_list * params)
{
TR_Sock this = _this;
int reUse = 1; //! \todo make this configurable
int port;
this->log = va_arg(* params, TR_Logger);
port = va_arg(* params, int);
//! if port is -1 do not initialize the socket. (Used with accept)
if (-1 == port) {
return 0;
} else {
this->port = port;
}
TR_Socket this = _this;
//! Create socket for incoming connections
if (-1 == (this->handle = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))) {
TR_loggerLog(this->log, TR_LOGGER_CRIT,
"error opening socket: %s - service terminated",
strerror(errno));
return -1;
}
//! Make the socket REUSE a TIME_WAIT socket
setsockopt(this->handle, SOL_SOCKET, SO_REUSEADDR, &reUse, sizeof(reUse));
this->type = 0;
this->handle = -1;
this->log = va_arg(*params, TR_Logger);
this->host = va_arg(*params, char*);
this->port = va_arg(*params, int);
this->flags = va_arg(*params, int);
this->fin_state = TR_FIN_RDWR;
return 0;
}
@ -64,15 +56,33 @@ static
void
socketDtor(void * _this)
{
TR_Sock this = _this;
TR_Socket this = _this;
TR_MEM_FREE(this->cname);
if (STDERR_FILENO < this->handle) {
shutdown(this->handle, SHUT_RDWR);
close(this->handle);
TR_socketClose(this);
}
}
static
int
socketBind(void * _this)
{
TR_Socket this = _this;
int state;
state = bind(this->handle, (struct sockaddr *)&(this->addr), this->addrlen);
if (-1 == state) {
perror("bind");
}
return state;
}
TR_INIT_IFACE(TR_Class, socketCtor, socketDtor, NULL);
TR_CREATE_CLASS(TR_Sock, NULL, TR_IF(TR_Class));
TR_INIT_IFACE(TR_Socket, socketBind, NULL, NULL);
TR_CREATE_CLASS(TR_Socket, NULL, TR_IF(TR_Class), TR_IF(TR_Socket));
// vim: set ts=4 sw=4:

48
src/accept.c → src/socket_accept.c

@ -20,38 +20,48 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define _POSIX_SOURCE 1
#include <stdio.h> // for atoi() and exit()
#include <errno.h> // for errno
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include "trbase.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "tr/socket.h"
#include "tr/logger.h"
TR_Sock
TR_socketAccept(TR_Sock this, char (*remoteAddr)[16])
TR_TcpSocket
TR_socketAccept(TR_TcpSocket this)
{
TR_Sock sock; // Socket for client
unsigned int len; // Length of client address data structure
TR_Socket remote = TR_new(TR_TcpSocket, TR_socketLog(this), NULL, 0, 0);
//int flags;
// Set the size of the in-out parameter
len = sizeof(this->addr);
remote->handle = accept(
TR_socketHandle(this),
(struct sockaddr *)&(remote->addr),
&(remote->addrlen));
sock = TR_new(TR_Sock, this->log, -1);
//flags = fcntl(remote->handle, F_GETFL, 0);
//fcntl(remote->handle, F_SETFL, flags | O_NONBLOCK);
// Wait for a client to connect
sock->handle = accept(this->handle, (struct sockaddr *) &(sock->addr), &len);
if (-1 == sock->handle) {
TR_loggerLog(this->log, TR_LOGGER_WARNING,
"error accepting connection: %s", strerror(errno));
} else {
strcpy(*remoteAddr, inet_ntoa((sock->addr).sin_addr));
remote->host = TR_strdup(inet_ntoa(remote->addr.sin_addr));
remote->port = ntohs(remote->addr.sin_port);
remote->type = TR_socketType(this);
remote->flags = TR_socketFlags(this);
//loggerLog(this->log, LOGGER_INFO,
// "handling client %s\n", inet_ntoa((sock->addr).sin_addr));
}
if (-1 == remote->handle) {
perror("accept");
TR_delete(remote);
}
return sock;
return (TR_TcpSocket)remote;
}
// vim: set ts=4 sw=4:

14
src/get_ip.c → src/socket_close.c

@ -20,16 +20,20 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <arpa/inet.h>
#include <stdlib.h> // for atoi() and exit()
#include <errno.h> // for errno
#include <stdio.h>
#include <unistd.h>
#include "trbase.h"
#include "tr/socket.h"
#include "tr/logger.h"
in_addr_t
TR_socketGetIp(TR_Sock this)
void
TR_socketClose(TR_Socket this)
{
return this->addr.sin_addr.s_addr;
TR_socketShutdown(this);
close(this->handle);
this->handle = -1;
}
// vim: set ts=4 sw=4:

103
src/socket_init.c

@ -0,0 +1,103 @@
/**
* \file
*
* \author Georg Hopp
*
* \copyright
* Copyright © 2012 Georg Hopp
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define _POSIX_SOURCE 1
#include <stdlib.h> // for atoi() and exit()
#include <errno.h> // for errno
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include "tr/socket.h"
#include "tr/logger.h"
int
TR_socketInit(TR_Socket this, TR_socketAction_fptr action)
{
struct addrinfo hint;
struct addrinfo * info, * current_info;
char port_str[6];
hint.ai_socktype = this->type;
hint.ai_flags = this->flags;
hint.ai_family = AF_UNSPEC;
hint.ai_protocol = 0;
hint.ai_addrlen = 0;
hint.ai_canonname = NULL;
hint.ai_addr = NULL;
hint.ai_next = NULL;
sprintf(port_str, "%u", this->port);
if (0 != getaddrinfo(this->host, port_str, &hint, &info)) {
// TODO error handling...
return FALSE;
}
current_info = info;
for (
current_info = info;
current_info;
current_info = current_info->ai_next)
{
this->handle = socket(
current_info->ai_family,
current_info->ai_socktype,
current_info->ai_protocol);
if (-1 == this->handle) {
continue;
}
this->addrlen = current_info->ai_addrlen;
memcpy(&(this->addr), current_info->ai_addr, this->addrlen);
if (0 == action(this)) {
break; // success / open and bind or open and connect...
}
close(this->handle);
this->handle = -1;
}
if (NULL != current_info) {
int reUse = 1; //! \todo make this configurable
//int flags = fcntl(this->handle, F_GETFL, 0);
//fcntl(this->handle, F_SETFL, flags | O_NONBLOCK);
this->cname = TR_strdup(current_info->ai_canonname);
this->fin_state = TR_FIN_NO;
//! Make the socket REUSE a TIME_WAIT socket
setsockopt(this->handle, SOL_SOCKET, SO_REUSEADDR, &reUse, sizeof(reUse));
}
freeaddrinfo(info);
return TRUE;
}
// vim: set ts=4 sw=4:

2
src/nonblock.c → src/socket_nonblock.c

@ -28,7 +28,7 @@
#include "tr/logger.h"
void
TR_socketNonblock(TR_Sock this)
TR_socketNonblock(TR_Socket this)
{
int flags = fcntl(this->handle, F_GETFL, 0);
fcntl(this->handle, F_SETFL, flags | O_NONBLOCK);

19
src/get_ip_str.c → src/socket_shutdown.c

@ -20,16 +20,25 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <arpa/inet.h>
#include <stdlib.h> // for atoi() and exit()
#include <errno.h> // for errno
#include <stdio.h>
#include <unistd.h>
#include "trbase.h"
#include "tr/socket.h"
#include "tr/logger.h"
const char * const
TR_socketGetIpStr(TR_Sock this)
TR_SocketFin
TR_socketShutdown(TR_Socket this)
{
return inet_ntoa(this->addr.sin_addr);
if (TR_socketFinRdWr(this)) {
return this->fin_state;
}
shutdown(this->handle, SHUT_RDWR);
this->fin_state |= TR_FIN_RDWR;
return this->fin_state;
}
// vim: set ts=4 sw=4:

32
src/connect.c → src/socket_shutdown_read.c

@ -22,32 +22,26 @@
#include <stdlib.h> // for atoi() and exit()
#include <errno.h> // for errno
#include <stdio.h>
#include <unistd.h>
#include "tr/socket.h"
#include "tr/logger.h"
void
TR_socketConnect(TR_Sock this, const char * addr, char (*remoteAddr)[16])
TR_SocketFin
TR_socketShutdownRead(TR_Socket this)
{
inet_pton(AF_INET, addr, &((this->addr).sin_addr));
(this->addr).sin_family = AF_INET; // Internet address family
(this->addr).sin_port = htons(this->port); // Local port
if (TR_socketFinRd(this)) {
return this->fin_state;
}
if (-1 == connect(
this->handle,
(struct sockaddr*) &(this->addr),
sizeof(this->addr)))
{
TR_loggerLog(this->log, TR_LOGGER_CRIT,
"error connection socket: %s - service terminated",
strerror(errno));
exit(EXIT_FAILURE);
} else {
strcpy(*remoteAddr, inet_ntoa((this->addr).sin_addr));
if (0 == shutdown(this->handle, SHUT_RD)) {
this->fin_state |= TR_FIN_RD;
} else {
this->fin_state |= TR_FIN_RDWR;
}
TR_loggerLog(this->log, TR_LOGGER_INFO,
"handling connection %s\n", inet_ntoa((this->addr).sin_addr));
}
return this->fin_state;
}
// vim: set ts=4 sw=4:

47
src/socket_shutdown_write.c

@ -0,0 +1,47 @@
/**
* \file
*
* \author Georg Hopp
*
* \copyright
* Copyright © 2012 Georg Hopp
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h> // for atoi() and exit()
#include <errno.h> // for errno
#include <stdio.h>
#include <unistd.h>
#include "tr/socket.h"
#include "tr/logger.h"
TR_SocketFin
TR_socketShutdownWrite(TR_Socket this)
{
if (TR_socketFinWr(this)) {
return this->fin_state;
}
if (0 == shutdown(this->handle, SHUT_WR)) {
this->fin_state |= TR_FIN_WR;
} else {
this->fin_state |= TR_FIN_RDWR;
}
return this->fin_state;
}
// vim: set ts=4 sw=4:

121
src/tcp_socket.c

@ -0,0 +1,121 @@
/**
* \file
*
* \author Georg Hopp
*
* \copyright
* Copyright © 2012 Georg Hopp
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include "tr/socket.h"
#include "tr/logger.h"
#include "trbase.h"
static
int
tcpSocketCtor(void * _this, va_list * params)
{
TR_TcpSocket this = _this;
TR_PARENTCALL(_this, TR_Class, ctor, params);
TR_socketType(this) = SOCK_STREAM;
this->listen = FALSE;
this->connected = FALSE;
return 0;
}
static
int
tcpSocketBind(void * _this)
{
TR_TcpSocket this = _this;
int bind_ret;
TR_PARENTRETCALL(_this, TR_Socket, bind, bind_ret);
if (bind_ret != 0) {
return -1;
}
if (listen(TR_socketHandle(this), 128) != 0) {
// error
return -1;
}
this->listen = TRUE;
return 0;
}
static
int
tcpSocketConnect(void * _this)
{
TR_Socket this = _this;
return connect(
this->handle,
(struct sockaddr *)&(this->addr),
this->addrlen);
}
static
TR_RemoteData
tcpSocketRecv(TR_Socket this, size_t size)
{
TR_RemoteData rdata = TR_new(TR_RemoteData, &(this->addr), this->addrlen);
unsigned char buffer[size];
ssize_t received;
received = recv(this->handle, buffer, size, this->flags);
if (-1 == received) {
perror("recv");
TR_delete(rdata);
} else {
TR_remoteDataSetData(rdata, buffer, received);
}
return rdata;
}
static
ssize_t
tcpSocketSend(TR_Socket this, TR_RemoteData data)
{
return send(this->handle, data->data, data->ndata, this->flags);
}
TR_INIT_IFACE(TR_Class, tcpSocketCtor, NULL, NULL);
TR_INIT_IFACE(
TR_Socket,
tcpSocketBind,
tcpSocketConnect,
tcpSocketRecv,
tcpSocketSend);
TR_CREATE_CLASS(TR_TcpSocket, TR_Socket, TR_IF(TR_Class), TR_IF(TR_Socket));
// vim: set ts=4 sw=4:

102
src/udp_socket.c

@ -0,0 +1,102 @@
/**
* \file
*
* \author Georg Hopp
*
* \copyright
* Copyright © 2012 Georg Hopp
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include "tr/socket.h"
#include "tr/logger.h"
#include "trbase.h"
static
int
udpSocketCtor(void * _this, va_list * params)
{
TR_Socket this = _this;
TR_PARENTCALL(_this, TR_Class, ctor, params);
this->type = SOCK_DGRAM;
return 0;
}
static
TR_RemoteData
udpSocketRecv(TR_Socket this, size_t size)
{
TR_RemoteData rdata;
struct sockaddr_in addr;
socklen_t addrlen = this->addrlen;
unsigned char buffer[size];
ssize_t received;
received = recvfrom(
this->handle,
buffer,
size,
this->flags,
(struct sockaddr *)&addr,
&addrlen);
if (-1 == received) {
perror("recvfrom");
} else {
rdata = TR_new(TR_RemoteData, &addr, addrlen);
TR_remoteDataSetData(rdata, buffer, received);
}
return rdata;
}
static
ssize_t
udpSocketSend(TR_Socket this, TR_RemoteData data)
{
ssize_t send;
send = sendto(
this->handle,
data->data,
data->ndata,
this->flags,
(struct sockaddr *)&(data->addr),
data->addrlen);
if (-1 == send) {
perror("sendto");
}
return send;
}
TR_INIT_IFACE(TR_Class, udpSocketCtor, NULL, NULL);
TR_INIT_IFACE(TR_Socket, NULL, NULL, udpSocketRecv, udpSocketSend);
TR_CREATE_CLASS(TR_UdpSocket, TR_Socket, TR_IF(TR_Class), TR_IF(TR_Socket));
// vim: set ts=4 sw=4:

93
trio.h

@ -1,93 +0,0 @@
/* trio.h. Generated from trio.h.in by configure. */
/* trio.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `memset' function. */
/* #undef HAVE_MEMSET */
/* Define to 1 if you have the <stdarg.h> header file. */
#define HAVE_STDARG_H 1
/* Define to 1 if stdbool.h conforms to C99. */
/* #undef HAVE_STDBOOL_H */
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <syslog.h> header file. */
#define HAVE_SYSLOG_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if the system has the type `_Bool'. */
#define HAVE__BOOL 1
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
/* Name of package */
#define PACKAGE "libtrio"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "Georg Hopp <georg@steffers.org>"
/* Define to the full name of this package. */
#define PACKAGE_NAME "libtrio"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "libtrio 0.0.0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libtrio"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "0.0.0"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Version number of package */
#define VERSION "0.0.0"
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
/* #undef inline */
#endif
/* Define to `int' if <sys/types.h> does not define. */
/* #undef pid_t */
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
Loading…
Cancel
Save