From: teodor Date: Fri, 30 Nov 2007 18:07:44 +0000 (+0000) Subject: Use offsetof macro where possible to defined header size; X-Git-Url: http://www.sigaev.ru/git/gitweb.cgi?p=tedtools.git;a=commitdiff_plain;h=a2b2c2df517635ae5be20775d3c075a09b32b6fb Use offsetof macro where possible to defined header size; Use network byteorder for messages Use standart message type for tcp connection. --- diff --git a/connection.h b/connection.h index 6ccd725..572e357 100644 --- a/connection.h +++ b/connection.h @@ -6,13 +6,13 @@ * 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. + * 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. + * 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. + * 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 @@ -36,15 +36,15 @@ #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_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 @@ -56,46 +56,55 @@ #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 *buf; - char *ptr; + u_int32_t len; + char *ptr; + TCMsg *buf; /* send buf */ /* internal fields */ - int fd; - u_int32_t + int fd; + u_int32_t readyio:1, state:29; - struct sockaddr_in serv_addr; + struct sockaddr_in serv_addr; /* external link */ void* data; } TC_Connection; -#define TCCONNHDRSZ ( sizeof(TC_Connection) - sizeof(void*) ) +#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 ); -typedef struct { - u_int32_t len; - u_int32_t type; - char data[1]; -} TCMsg; - -#define TCMSGHDRSZ (2*sizeof(u_int32_t)) +/* udp */ -/* udp */ typedef struct { char *host; u_int32_t port; @@ -124,16 +133,16 @@ typedef struct { * * Udp client send: * Msg msg; - * msg.host = "127.0.0.1"; - * msg.port = 5432; + * msg.host = "127.0.0.1"; + * msg.port = 5432; * msg.sockfd =-1; * msg.msg = GOTFILLEDPMSG(); * if ( TC_sendMsg(&msg)!=CS_OK ) { - * //Very bad + * //Very bad * } * msg.msg = GOTFILLEDPMSG(); * if ( TC_sendMsg(&msg)!=CS_OK ) { - * //Very bad + * //Very bad * } * TC_closefd(&msg); */ @@ -143,10 +152,14 @@ 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; + u_int32_t len; + u_int32_t number; + TC_Connection **conn; } PoolConnection; void TC_addConnection(PoolConnection *pool, TC_Connection *c); diff --git a/regis.h b/regis.h index c28c619..bed78fd 100644 --- a/regis.h +++ b/regis.h @@ -31,6 +31,7 @@ #define __REGIS_H__ #include +#include "tools.h" typedef struct RegisNode { u_int32_t @@ -41,7 +42,7 @@ typedef struct RegisNode { unsigned char data[1]; } RegisNode; -#define RNHDRSZ (sizeof(u_int32_t)+sizeof(void*)) +#define RNHDRSZ offsetof(RegisNode, data) #define RSF_ONEOF 1 #define RSF_NONEOF 2 diff --git a/tcp.c b/tcp.c index 7183b42..112e98a 100644 --- a/tcp.c +++ b/tcp.c @@ -343,17 +343,22 @@ TC_Send( TC_Connection *cs ) { if ( cs->state == CS_ERROR ) return CS_ERROR; - if ( cs->state != CS_SEND ) { + if ( cs->state != CS_SEND || cs->ptr == NULL ) { cs->state = CS_SEND; - cs->ptr = cs->buf; + cs->ptr = (char*)cs->buf; + cs->len = cs->buf->len; + + /* convert fields to network byteorder */ + cs->buf->len = htonl(cs->buf->len); + cs->buf->type = htonl(cs->buf->type); } - if ( cs->ptr - cs->buf >= cs->len ) { + if ( cs->ptr - (char*)cs->buf >= cs->len ) { cs->state = CS_FINISHSEND; return CS_FINISHSEND; } - if ((sz=write(cs->fd, cs->ptr, cs->len - (cs->ptr - cs->buf)))==0 || + if ((sz=write(cs->fd, cs->ptr, cs->len - (cs->ptr - (char*)cs->buf)))==0 || (sz < 0 && (errno == EWOULDBLOCK || errno == EAGAIN))) { /* SunOS 4.1.x, are broken and select() says that @@ -375,8 +380,11 @@ TC_Send( TC_Connection *cs ) { cs->ptr += sz; - if ( cs->ptr - cs->buf >= cs->len ) { + if ( cs->ptr - (char*)cs->buf >= cs->len ) { cs->state = CS_FINISHSEND; + /* revert byteorder conversion */ + cs->buf->len = ntohl(cs->buf->len); + cs->buf->type = ntohl(cs->buf->type); return CS_FINISHSEND; } @@ -385,12 +393,13 @@ TC_Send( TC_Connection *cs ) { static void resizeCS( TC_Connection *cs, int sz ) { - int diff = cs->ptr - cs->buf; + int diff = cs->ptr - (char*)cs->buf; + if ( cs->len >= sz ) return; cs->len = sz; - cs->buf = (char*)trealloc( (void*)cs->buf, cs->len ); - cs->ptr = cs->buf + diff; + cs->buf = (TCMsg*)trealloc( (void*)cs->buf, cs->len ); + cs->ptr = ((char*)cs->buf) + diff; } u_int32_t @@ -400,17 +409,18 @@ TC_Read( TC_Connection *cs, size_t maxsize ) { if ( cs->state == CS_ERROR ) return CS_ERROR; - if (cs->state != CS_READ ) { + if (cs->state != CS_READ || cs->ptr == NULL ) { cs->state = CS_READ; - cs->ptr = cs->buf; + cs->ptr = (char*)cs->buf; + cs->len = 0; } - alreadyread = cs->ptr - cs->buf; - if ( alreadyread < sizeof(u_int32_t) ) { - toread = sizeof(u_int32_t) - alreadyread; - resizeCS(cs, sizeof(u_int32_t)); + alreadyread = cs->ptr - (char*)cs->buf; + if ( alreadyread < TCMSGHDRSZ ) { + toread = TCMSGHDRSZ - alreadyread; + resizeCS(cs, TCMSGHDRSZ); } else { - totalread = *(u_int32_t*)(cs->buf); + totalread = ntohl(cs->buf->len); if ( maxsize > 0 && totalread > maxsize ) { tlog(TL_ALARM,"TC_Read: message size (%d b) is greater than max allowed (%d b)", totalread, maxsize); @@ -435,7 +445,13 @@ TC_Read( TC_Connection *cs, size_t maxsize ) { return CS_ERROR; } - + if ( alreadyread < TCMSGHDRSZ && alreadyread + sz >= TCMSGHDRSZ ) { + /* + * we just read header - we can get totalread value. + */ + totalread = ntohl(cs->buf->len); + } + cs->ptr += sz; alreadyread += sz; if ( sz == 0 && alreadyread != totalread ) { @@ -443,7 +459,13 @@ TC_Read( TC_Connection *cs, size_t maxsize ) { cs->state = CS_ERROR; return CS_ERROR; } - cs->state = ( alreadyread == totalread ) ? CS_FINISHREAD : CS_READ; + + if ( alreadyread == totalread ) { + cs->buf->len = ntohl(cs->buf->len); + cs->buf->type = ntohl(cs->buf->type); + cs->state = CS_FINISHREAD; + } + return cs->state; } @@ -475,14 +497,14 @@ TC_Talk( TC_Connection *cs, size_t maxsize ) { return cs->state; cs->state = CS_SEND; - cs->ptr = cs->buf; + cs->ptr = NULL; while( cs->state != CS_FINISHSEND ) { while( !TC_ReadyIO( &cs, 1, 100) ); if ( TC_Send(cs) == CS_ERROR ) return CS_ERROR; } cs->state = CS_READ; - cs->ptr = cs->buf; + cs->ptr = NULL; while( cs->state != CS_FINISHREAD ) { while( !TC_ReadyIO( &cs, 1, 100) ); if ( TC_Read(cs, maxsize) == CS_ERROR ) return CS_ERROR; diff --git a/tmalloc.h b/tmalloc.h index a39a3ff..67069eb 100644 --- a/tmalloc.h +++ b/tmalloc.h @@ -55,7 +55,7 @@ typedef struct MemoryChunk { char data[1]; } MemoryChunk; -#define MEMCHNKHDRSZ ( sizeof(u_int32_t)*2 + sizeof(MemoryChunk*) ) +#define MEMCHNKHDRSZ offsetof(MemoryChunk, data) typedef struct MemoryContext { u_int32_t flags; diff --git a/udp.c b/udp.c index 6e127da..9c212af 100644 --- a/udp.c +++ b/udp.c @@ -110,6 +110,12 @@ TC_getMsg( int sockfd, Msg *msg ) { tlog(TL_ALARM, "Got message %d bytes (should be al least %d)", n, TCMSGHDRSZ ); return CS_AGAIN; } + + /* + * convert from network byteorder + */ + pmsg->len = ntohl(pmsg->len); + pmsg->type = ntohl(pmsg->type); if ( pmsg->len > MSGMAXSIZE ) { tlog(TL_ALARM, "Messages (%d bytes) is too big", pmsg->len); @@ -130,6 +136,8 @@ TC_getMsg( int sockfd, Msg *msg ) { /* send */ u_int32_t TC_sendMsg( Msg *msg ) { + int msglen; + if ( msg->msg == NULL || msg->msg->len <=0 ) return CS_OK; @@ -182,7 +190,14 @@ TC_sendMsg( Msg *msg ) { msg->host_addr.sin_port = htons(msg->port); } - if (sendto(msg->sockfd, (void*)msg->msg, msg->msg->len, 0, (struct sockaddr *) &(msg->host_addr), sizeof(msg->host_addr)) != msg->msg->len) { + /* + * convert to network byteorder + */ + msglen = msg->msg->len; + msg->msg->len = htonl(msg->msg->len); + msg->msg->type = htonl(msg->msg->type); + + if (sendto(msg->sockfd, (void*)msg->msg, msglen, 0, (struct sockaddr *) &(msg->host_addr), sizeof(msg->host_addr)) != msglen) { tlog(TL_CRIT,"Can't send message to %s:%d : %s", msg->host, msg->port, strerror(errno)); close(msg->sockfd); msg->sockfd=-1;