/** * \file * Abstraction layer above BSD sockets. Capsules and simplifies connect * accept and listen for TCP and UDP sockets. * It also provides a mostly unified interface to both types of sockets. * * \author Georg Hopp * * \copyright * Copyright © 2014 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 . */ #ifndef __TR_SOCKET_H__ #define __TR_SOCKET_H__ #include #include #include #include //#include // for in_port_t #include "trbase.h" //#include "tr/interface/socket.h" #include "tr/logger.h" #define TR_UDP_MAX_READ_BLOCK 8 * 1024 #define TR_TCP_MAX_READ_BLOCK 256 * 1024 typedef enum TR_e_socket_fin { TR_FIN_NO = 0, TR_FIN_RD = 1, TR_FIN_WR = 2, TR_FIN_RDWR = 3 } TR_SocketFin; #define TR_MAX_HOST 256 #define TR_MAX_CNAME 512 TR_CLASS(TR_Socket) { TR_Logger log; int flags; int type; char host[TR_MAX_HOST]; char cname[TR_MAX_CNAME]; int port; time_t ttl; union { struct sockaddr info; struct sockaddr_in in; struct sockaddr_in6 in6; } addr; socklen_t addrlen; int handle; TR_SocketFin fin_state; int fd_getter; }; TR_INSTANCE_INIT(TR_Socket); TR_CLASSVARS_DECL(TR_Socket) {}; #define TR_socketLog(socket) ((socket)->log) #define TR_socketFlags(socket) ((socket)->flags) #define TR_socketType(socket) ((socket)->type) #define TR_socketHost(socket) ((socket)->host) #define TR_socketPort(socket) ((socket)->port) #define TR_socketCname(socket) ((socket)->cname) #define TR_socketTtl(socket) ((socket)->ttl) #define TR_socketAddr(socket) ((void *)&(socket)->addr) #define TR_socketAddrlen(socket) ((socket)->addrlen) #define TR_socketHandle(socket) ((socket)->handle) #define TR_socketFinState(socket) ((socket)->fin_state) #define TR_socketFdGetter(socket) ((socket)->fd_getter) #define TR_socketFinRd(socket) \ ((TR_socketFinState(socket) & TR_FIN_RD) == TR_FIN_RD) #define TR_socketFinWr(socket) \ ((TR_socketFinState(socket) & TR_FIN_WR) == TR_FIN_WR) #define TR_socketFinRdWr(socket) \ ((TR_socketFinState(socket) & TR_FIN_RDWR) == TR_FIN_RDWR) #define TR_socketAddrPort(socket) \ ((socket)->addr.info.sa_family == AF_INET \ ? ntohs((socket)->addr.in.sin_port) \ : (socket)->addr.info.sa_family == AF_INET6 \ ? ntohs((socket)->addr.in6.sin6_port) \ : 0) #define TR_socketAddrIp(socket) \ ((socket)->addr.info.sa_family == AF_INET \ ? (void *)&(socket)->addr.in.sin_addr.s_addr \ : (socket)->addr.info.sa_family == AF_INET6 \ ? (void *)&(socket)->addr.in6.sin6_addr.s6_addr \ : NULL) #define TR_socketAddrIplen(socket) \ ((socket)->addr.info.sa_family == AF_INET \ ? sizeof((socket)->addr.in.sin_addr) \ : (socket)->addr.info.sa_family == AF_INET6 \ ? sizeof((socket)->addr.in6.sin6_addr) \ : 0) #define TR_socketAddrIpStr(socket, buffer, nbuffer) \ if (TR_socketAddrIp((socket))) \ inet_ntop( \ (socket)->addr.info.sa_family, \ TR_socketAddrIp((socket)), \ buffer, nbuffer) TR_CLASS(TR_TcpSocket) { TR_EXTENDS(TR_Socket); int connected; }; TR_INSTANCE_INIT(TR_TcpSocket); TR_CLASSVARS_DECL(TR_TcpSocket) {}; TR_CLASS(TR_UdpSocket) { TR_EXTENDS(TR_Socket); }; TR_INSTANCE_INIT(TR_UdpSocket); TR_CLASSVARS_DECL(TR_UdpSocket) {}; 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)) #define TR_socketOpen(socket) \ (TR_socketInit((socket), NULL)) void TR_socketPair(TR_Socket[2], int); void TR_socketSendFd(TR_Socket, int); int TR_socketGetFd(TR_Socket); #endif // __TR_SOCKET_H__ // vim: set ts=4 sw=4: