/* * Copyright (c) 2004 Teodor Sigaev * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __CONNECTION_H__ #define __CONNECTION_H__ #include #include #include #include #include #include "tools.h" #define CS_OK 0 #define CS_INPROCESS 1 #define CS_CONNECTED 2 #define CS_READ 3 #define CS_SEND 4 #define CS_WAIT 5 #define CS_ERROR 6 #define CS_FINISHSEND 7 #define CS_FINISHREAD 8 #define CS_TIMEOUT 9 #define CS_CLOSED 10 #define CS_NOTINITED 11 #define CS_AGAIN 12 #define CS_FINISH 13 #define READ_INCRIMENT_BUFSIZ 1024 /* * any message shoulbe compatible with TCMsg struct */ typedef struct { /* len and type should be transferred in network byte order */ u_int32_t len; u_int32_t type; char data[1]; } TCMsg; #define TCMSGHDRSZ offsetof(TCMsg, data) /* tcp */ typedef struct { /* I/O buffer */ u_int32_t len; char *ptr; TCMsg *buf; /* send buf */ /* internal fields */ int fd; u_int32_t readyio:1, state:29; struct sockaddr_in serv_addr; /* external link */ void* data; } TC_Connection; #define TCCONNHDRSZ offsetof(TC_Connection, data) TC_Connection *TC_fillConnection( TC_Connection *cs, char *name, u_int32_t port ); TC_Connection* TC_AcceptTcp(TC_Connection *cs); u_int32_t TC_ClientInitConnection(TC_Connection *cs, char *name, u_int32_t port); u_int32_t TC_ServerInitConnect( TC_Connection *cs ); u_int32_t TC_ServerConnect( TC_Connection *cs, int timeout ); /* * TC_Send doesn't promise to keep TC_Connection->buf unchanged */ u_int32_t TC_Send( TC_Connection *cs ); u_int32_t TC_Read( TC_Connection *cs, size_t maxsize ); u_int32_t TC_Talk( TC_Connection *cs, size_t maxsize ); void TC_FreeConnection( TC_Connection *cs ); int TC_ReadyIO( TC_Connection **cs, int number, int timeout ); /* udp */ typedef struct { char *host; u_int32_t port; TCMsg *msg; /* private members */ int sockfd; struct sockaddr_in host_addr; } Msg; /* * Udp server loop: * TC_Connection conn,*connptr; * conn.fd = TC_AcceptUdp("127.0.0.1", 5432); * conn.state = CS_READ; * connptr = &conn; * while(1) { * if ( TC_ReadyIO( &connptr, 1, 100 ) ) { * Msg m; * if ( TC_getMsg(conn.fd, &m) == CS_OK ) { * //do something * } * } * } * close(conn.fd); * * Udp client send: * Msg msg; * msg.host = "127.0.0.1"; * msg.port = 5432; * msg.sockfd =-1; * msg.msg = GOTFILLEDPMSG(); * if ( TC_sendMsg(&msg)!=CS_OK ) { * //Very bad * } * msg.msg = GOTFILLEDPMSG(); * if ( TC_sendMsg(&msg)!=CS_OK ) { * //Very bad * } * TC_closefd(&msg); */ int TC_AcceptUdp(char *host, int port); u_int32_t TC_getMsg( int sockfd, Msg *msg ); u_int32_t TC_sendMsg( Msg *msg ); void TC_closefd( Msg *msg ); /* * Connection pool */ typedef struct { u_int32_t len; u_int32_t number; TC_Connection **conn; } PoolConnection; void TC_addConnection(PoolConnection *pool, TC_Connection *c); void TC_deleteConnectionByN(PoolConnection *pool, int n); void TC_deleteConnectionByC(PoolConnection *pool, TC_Connection *c); #ifndef HAVE_HSTRERROR #define hstrerror strerror #define h_errno errno #endif #endif